Skip navigation

Smile Classification

I altered Carols and Barkin’s code for detecting hand written digits and used it to detect whether a face is smiling or not. It was 80% accurate testing 20 pics and using 80 as test data.

import wekaizing.*;
import java.io.File;
import java.lang.Integer;

// The class we use to store our digits from files
// Contains the number digit stands for, the image of the digit
// And the resized pixel data of the digit
class faceImage {
int number;
PImage digit;
int[] pixeldata;

//The pixel data is kept 101 long for 10×10 pixels and 1 number
public faceImage() {
pixeldata = new int[101];}
}

WekaData facesTrain;
WekaData facesTest;
WekaClassifier classifier;
faceImage[] faces;

int[] results;
PFont courier_font;

void setup() {

background(0);
size(560,120);
courier_font = loadFont(“CourierNew-12.vlw”);
textFont(courier_font, 15);

facesTrain = new WekaData();
facesTest = new WekaData();

// create an attribute for each pixel
for (int i = 0; i < 100; i++) {
facesTrain.AddAttribute(Integer.toString(i));
facesTest.AddAttribute(Integer.toString(i));
}

// create an attribute for the class (face)
Object[] facearray = new Object[] {0,1};
facesTrain.AddAttribute(“face”,facearray);
facesTest.AddAttribute(“face”,facearray);

// load data from disk into data structure
loadFaces(“faces”);

// set the class variable to be the last attribute
facesTrain.setClassIndex(100);
facesTest.setClassIndex(100);

//Train the classifier
classifier = new WekaClassifier(WekaClassifier.LOGISTIC);
classifier.Build(facesTrain);
print(“Training done”);

//Test the 100 digits
results = classifier.Classify(facesTest);
print(“Classification done”);

drawResults();
}

// load digits from disk
void loadFaces(String facesfolder) {

// open file for face images
File facefiles = new File(sketchPath, “data/” + facesfolder);
String[] files = facefiles.list(filter);
faces = new faceImage[files.length];

// digits.txt contains the actual true class labels for the digit images
String numbers[] = loadStrings(facesfolder + “/faces.txt”);

// for each image file
for (int i = 0; i < files.length; i++) {
println(“Loading image ” + files[i]);

// load digit image (used for displaying)
faces[i] = new faceImage();
faces[i].digit = loadImage(“data/” + facesfolder + “/” + files[i]);

// load true class for digit
faces[i].number = Integer.valueOf(numbers[i]);

// get a 10×10 version of the image, will be used as feature for classifier
// lower resolution means we can learn from less data (though we could be more
// accurate with higher resolution if we had more data)
PImage resizedImg = loadImage(“data/” + facesfolder + “/” + files[i]);
resizedImg.resize(10,10);

// copy the pixels of lower resolution data into data structure that will be
// used by Weka
resizedImg.loadPixels();
for (int j = 0; j < 100; j++) {
faces[i].pixeldata[j] = resizedImg.pixels[j];
}
// the last entry is the true label
faces[i].pixeldata[100] = faces[i].number;

// the first 100 digits will be used for testing, the rest as training data.
if (i < 20) {
facesTest.InsertData(faces[i].pixeldata);
} else { //Otherwise training
facesTrain.InsertData(faces[i].pixeldata);
}
}
}

// Draws the digits in a grid
void drawResults() {
// count the number of digits we got correct
float num_correct = 0.0, total = 0.0;

// display each image, 10 per row
int imgx, imgy;
for (int i = 0; i < 20; i++) {
//Center every digit on its 56×56 grid
imgx = (i % 10) * 56 + 14;
imgy = (i / 10) * 56 + 24;
image(faces[i].digit,imgx,imgy);
}

//Display the predicted and actual digits above the drawings
for (int i = 0; i < 20; i++) {
imgx = (i % 10) * 56 + 14;
imgy = (i / 10) * 56 + 14;

//actual value
//fill(255, 255, 255);
//if (faces[i].number == 1) { text(faces[i].number, imgx, imgy);}
//text(faces[i].number, imgx, imgy);

// predicted value
if (results[i] == 1) {
fill(0, 255, 0);
text(“:)”, imgx+5, imgy);
}
if (results[i] == 0) {
fill(255, 0, 0);
text(“:(“, imgx+5, imgy);
}
//text(results[i], imgx + 28, imgy);

// if actual value and predicted value are the same, then we got this digit correct
total += 1.0;
if(faces[i].number == results[i])
num_correct += 1.0;

}

// print accuracy
println(“\n” + “Accuracy = ” + num_correct/total*100 + “%”);
}

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

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: