Skip navigation

Category Archives: Exercise 3

logos

Above is an image of my Exercise 3.

==============================================================

Description:

This Processing applet was made to explore how machine learning can be used to sort logos by similarity. The applet looks at a collection of logos and sorts them based on how similar they are to a user-chosen logo from the collection. The logos all begin at full brightness, and when a logo is chosen, the other logos fade to black until they are sorted with the most similar logo as the brightest and the least similar logo as the darkest.

==============================================================

Code:

import java.io.File;
import java.io.FilenameFilter;
import imagelib.*;
import similarity.*;
ArrayList histograms;
PImage[] images;
int picIndex;
float px = 0;
float py = 0;
float pz = 0;
float mx = 0;
float my = 0;
float circleX = 0;
float circleY = 0;
float circleDiameter = 0;
float colorVariable = 0;
float opacity;
float vOpacity;
float vBoxOpacity;
int colorStart;
int frame;
color c;
float boxOpacity = 17;
//float idealBoxOpacity;
void setup() {
picIndex=-1;
size(1280,720);
File datafolder = new File(sketchPath, “data”);
String[] files = datafolder.list(filter);
if (files==null|files.length<1){
println(“You must add images in jpg format to the data subdirectory of your sketch.”);
exit();
}
images = new PImage[files.length];
int num_bins = 6;
histograms = new ArrayList(files.length);
double[] histogram;
for (int i = 0; i < files.length; i++) {
println(files[i]);
images[i] = loadImage(files[i]);
histogram = ImageParsing.histHue(this, images[i],num_bins);
histograms.add(i, histogram);
}
resetImages();
fill(0,220);
rect(0,0, 1280,720);
noFill();
}
void resetImages() {
int picy = 0;
int picx = 0;
background(255);
for (int i = 0; i < images.length ;i++) {
if (picx >= width) {
picx = 0;
picy += 240;
}
image(images[i],picx,picy,320,240);
picx += 320;
}
}
void draw() {
smooth();
noStroke();
float A = 0.90;
float B = 1.0-A;
mx = A*mx + B*mouseX;
my = A*my + B*mouseY;
circleDiameter = 40;
vOpacity = -10;
opacity = vOpacity+opacity;
if(opacity<25){
opacity=25;
}
if(picIndex>-1){
markSimilars(picIndex);
}
}
void mousePressed() {
boxOpacity = 0;
opacity = 255;
c = color(random(0,255),random(150,255),random(0,255));
if (mouseButton == LEFT) {
picIndex = (mouseY / 240) * 4 + mouseX / 320;
if (picIndex < images.length) {
markSimilars(picIndex);
}
}
}
void markSimilars(int index) {
int rectx, recty;
resetImages();
int[] similars = Similarity.similarVectors(histograms, index);
PFont Serif_48;
Serif_48 = loadFont(“Serif-48.vlw”);
textFont(Serif_48, 48);
for (int i = 0; i < similars.length; i++) {
println(i);
rectx = (similars[i] % 4) * 320;
recty = (similars[i] / 4) * 240;
/*fill(255,255,0);
text(i,rectx+30,recty+90);*/
float idealBoxOpacity = (i+1)*20;
println(idealBoxOpacity);
if(boxOpacity>idealBoxOpacity){
vBoxOpacity = -2;
boxOpacity = vBoxOpacity+boxOpacity;
}
else if(boxOpacity<idealBoxOpacity){
vBoxOpacity = 2;
boxOpacity = vBoxOpacity+boxOpacity;
}
else{
boxOpacity=idealBoxOpacity;
}
fill(0,boxOpacity);
noStroke();
rect(rectx,recty,320,240);
}
}
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
if (name.toLowerCase().endsWith(“.jpg”)) return true;
return false;
}
};

import java.io.File;

import java.io.FilenameFilter;

import imagelib.*;

import similarity.*;

ArrayList histograms;

PImage[] images;

int picIndex;

float px = 0;

float py = 0;

float pz = 0;

float mx = 0;

float my = 0;

float circleX = 0;

float circleY = 0;

float circleDiameter = 0;

float colorVariable = 0;

float opacity;

float vOpacity;

float vBoxOpacity;

int colorStart;

int frame;

color c;

float boxOpacity = 17;

//float idealBoxOpacity;

void setup() {

picIndex=-1;

size(1280,720);

File datafolder = new File(sketchPath, “data”);

String[] files = datafolder.list(filter);

if (files==null|files.length<1){

println(“You must add images in jpg format to the data subdirectory of your sketch.”);

exit();

}

images = new PImage[files.length];

int num_bins = 6;

histograms = new ArrayList(files.length);

double[] histogram;

for (int i = 0; i < files.length; i++) {

println(files[i]);

images[i] = loadImage(files[i]);

histogram = ImageParsing.histHue(this, images[i],num_bins);

histograms.add(i, histogram);

}

resetImages();

fill(0,220);

rect(0,0, 1280,720);

noFill();

}

void resetImages() {

int picy = 0;

int picx = 0;

background(255);

for (int i = 0; i < images.length ;i++) {

if (picx >= width) {

picx = 0;

picy += 240;

}

image(images[i],picx,picy,320,240);

picx += 320;

}

}

void draw() {

smooth();

noStroke();

float A = 0.90;

float B = 1.0-A;

mx = A*mx + B*mouseX;

my = A*my + B*mouseY;

circleDiameter = 40;

vOpacity = -10;

opacity = vOpacity+opacity;

if(opacity<25){

opacity=25;

}

if(picIndex>-1){

markSimilars(picIndex);

}

}

void mousePressed() {

boxOpacity = 0;

opacity = 255;

c = color(random(0,255),random(150,255),random(0,255));

if (mouseButton == LEFT) {

picIndex = (mouseY / 240) * 4 + mouseX / 320;

if (picIndex < images.length) {

markSimilars(picIndex);

}

}

}

void markSimilars(int index) {

int rectx, recty;

resetImages();

int[] similars = Similarity.similarVectors(histograms, index);

PFont Serif_48;

Serif_48 = loadFont(“Serif-48.vlw”);

textFont(Serif_48, 48);

for (int i = 0; i < similars.length; i++) {

println(i);

rectx = (similars[i] % 4) * 320;

recty = (similars[i] / 4) * 240;

/*fill(255,255,0);

text(i,rectx+30,recty+90);*/

float idealBoxOpacity = (i+1)*20;

println(idealBoxOpacity);

if(boxOpacity>idealBoxOpacity){

vBoxOpacity = -2;

boxOpacity = vBoxOpacity+boxOpacity;

}

else if(boxOpacity<idealBoxOpacity){

vBoxOpacity = 2;

boxOpacity = vBoxOpacity+boxOpacity;

}

else{

boxOpacity=idealBoxOpacity;

}

fill(0,boxOpacity);

noStroke();

rect(rectx,recty,320,240);

}

}

FilenameFilter filter = new FilenameFilter() {

public boolean accept(File dir, String name) {

if (name.toLowerCase().endsWith(“.jpg”)) return true;

return false;

}

};

Advertisements

In this exercise, we’re trying to study how we can use similarity to display interesting information.

I took 17 ebooks from the Internet (from the open-source project: http://www.gutenberg.org), by using the download popularity at that time (and filtering to get at least somewhat popular books, in english, and of usable size).

Then I run the TF-IDFs algorithm on that corpus, kept the best 50 words per document, and rendered each book as a chromosome, while each word is a gene. For each word, the mapping is the following :

– the IDF factor, since it is the same across the entire corpus, is considered as the size (height) of the gene: if the word is important, then its presence has an high impact on the overall property of the book.

– the TF is used to display the intensity of the gene: if the word/gene is more present in this book, then it means that it expresses itself more that others genes/words, and appears more white.

– the size of a book depends on the the number of words.

In addition, we can cycle through the book y using the W and X key: the current book is then selected in green, and all the best words of this book that appear at least once in others are displayed in green to across all the corpus, with the count per book. Then it is easy to see what are the similar book, and how they are similar.

François

Code

bookadn

http://paulshen.name/sketches/6

Paul Shen

Data: images of ex-president George W. Bush and monkeys

Data cleaning: crop out individual 50 by 50 image of each face, and then turn them into grayscale.

Usage: user select one of the faces, and it will be turned into a collage of all input faces.

Algorithm:

  1. compute the average brightness of each input face
  2. replace each pixel of the selected face by one of the input faces that has the most similar brightness

Source code: download
Sample:

Fragments with similar borders (but from different images) are put next to each other to create a “composite picture”. For similarity, I am using (negative of) the L1 distance between the pixels of two images in a small strip around the borders.

We start with a whole picture, and insert fragments clockwise.

screenshot02

and keep going

screenshot11

and going until a steady state has been reached

screenshot21

Just for kicks, a downtown Pittsburgh picture:

screenshot31

The code can be found here.

I started looking at similarities from a security camera, but I couldn’t get the sample code to reverse sort (most different to least different)  in a useful way. I’m not sure if it was a bug in my code,  if I wasn’t using enough bins, or if my images weren’t well suited.   So I switched to the OpenCV module for Processing which provides some of the basic absdiff and threshold modules needed for simple motion detection.

// -*-Java-*-
import java.io.File;
import java.io.FilenameFilter;

import hypermedia.video.*;

OpenCV opencv;
PImage[] images;
int[] moved = new int[65536];
int movedCount = 0;
File datafolder;
String[] files;

int ci = 0;
int imageW = 320;
int imageH = 240;

void setup() {

    size(700,600);

    // open video stream
    opencv = new OpenCV( this );
    opencv.allocate(imageW, imageH);

    // read list of images from directory   
    datafolder = new File(sketchPath, “data”);
    files = datafolder.list(filter);
    images = new PImage[files.length];

    for (int i = 0; i < files.length; i++) {     println(files[i]);     images[i] = loadImage(files[i]);     } } // turn draw into a method that generates a list of interesting images // based on threshold values. void draw() {     int t;     // only do the search once     if (movedCount == 0) {     FindUnusual();     background(0);     }     if (ci > movedCount) {
    ci = 0;
    background(0);
    delay(1000);
    }

    t = moved[ci];
    image(images[t], 0, 0);
    print(ci); print(“: “);
    println(files[t]);
}

int CountWhite(PImage im)
{
    int thresh = 250;
    int white = 0;
    int p;

    // if r, g, and b are all greater than thresh, then we’re
    // calling this “white”

    int l = im.width * im.height;
    for (int i = 0; i < l; i++) {     //    println (hex(im.pixels[i]));     p = im.pixels[i];     if ( (((p >> 24) & 0xFF) > thresh)
         && ((( p >> 16) & 0xFF) > thresh)
         && ((( p >> 8)  & 0xFF) > thresh) ) {
        white++;
    }
    }
    //    if (white > 0) {
    //    println(white);
    //    }
    return white;
}

void FindUnusual()
{
    int mi = images.length -1;
    for (int i = 0; i < mi; i++) {     println(i);     opencv.copy(images[i]);     opencv.remember(OpenCV.BUFFER);     opencv.copy(images[i+1]);     //    image(opencv.image(), images[i].width, 0);     opencv.absDiff();     opencv.threshold(70);     //    image(images[i], 0, 0);     //    image( opencv.image(), 0, images[i].height );               PImage ti = opencv.image();     if (CountWhite(ti) > 100) {
        moved[movedCount++] = (i+1);
        //        moved[movedCount++] = i+1;
    }
    }
}

FilenameFilter filter = new FilenameFilter() {
    public boolean accept(File dir, String name) {
        if (name.toLowerCase().endsWith(“.jpg”)) return true;
        return false;
    }
    };

void keyPressed()
{
    if (key == ‘n’) {
    ci++;
    }
    else if (key == ‘p’) {
    ci–;
    }

    if (ci < 0) {     ci = movedCount;     }     else if (ci == movedCount )  {     ci = 0;     }     println(ci); } [/sourcecode]

flow-mangled video

flow-mangled video

I wanted to work with motion similarity; I dabbled with a hybrid grid/particle fluid simulator, and got, well, this. It is it a sheet of fluid-like stuff that responds to video; while it’s doing that, patches of pre-specified motion (a swirl, a linear motion, an expansion) are correlated with the existing motion and, on occasion, added to it. This is pretty subtle, but it keeps things from getting boring.

Source code (C++, OpenCV, SDL, OpenGL) here.