Created
October 5, 2012 22:41
-
-
Save atduskgreg/3842886 to your computer and use it in GitHub Desktop.
hand gesture recognizer example using Processing wrapper of libsvm and a Histogram of Oriented Gradients library
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import hog.*; | |
import psvm.*; | |
PixelGradientVector[][] pixelGradients; | |
PImage img; | |
SVM model; | |
int[] labels; // 1 = A, 2 = B | |
String[] trainingFilenames, testFilenames; | |
float[][] trainingFeatures, testFeatures; | |
int[] testLabels; | |
PImage testImage; | |
double testResult = 0.0; | |
void setup() { | |
size(500, 500); | |
// get the names of all of the training image files | |
java.io.File folder = new java.io.File(dataPath("train")); | |
trainingFilenames = folder.list(); | |
labels = new int[trainingFilenames.length]; | |
trainingFeatures = new float[trainingFilenames.length][324]; | |
// load in the labels based on the first letter of | |
// the training images' filenames | |
for (int i = 0; i < trainingFilenames.length; i++) { | |
println(trainingFilenames[i]); | |
String gestureLabel = split(trainingFilenames[i], '-')[0]; | |
if (gestureLabel.equals("A")) { | |
labels[i] = 1; | |
} | |
if (gestureLabel.equals("B")) { | |
labels[i] = 2; | |
} | |
// calcualte the Histogram of Oriented Gradients for this image | |
// use its results as a training vector in our SVM | |
trainingFeatures[i] = gradientsForImage(loadImage("train/" + trainingFilenames[i])); | |
} | |
model = new SVM(this); | |
SVMProblem problem = new SVMProblem(); | |
problem.setNumFeatures(324); | |
// load the problem with the labels and training data | |
problem.setSampleData(labels, trainingFeatures); | |
// train the model | |
model.train(problem); | |
testResult = testNewImage(); | |
} | |
double testNewImage() { | |
int imgNum = (int)random(0, testFilenames.length-1); | |
testImage = loadImage("test/" + testFilenames[imgNum]); | |
testImage.resize(50, 50); | |
return model.test(gradientsForImage(testImage)); | |
} | |
void draw() { | |
background(0); | |
image(testImage, 0, 0); | |
String result = "Gesture is: "; | |
if ((int)testResult == 1) { | |
fill(255, 0, 0); | |
result = result + "A"; | |
} | |
else if ((int)testResult == 2) { | |
fill(0, 255, 0); | |
result = result + "B"; | |
} | |
text(result, 100, 20); | |
} | |
void keyPressed() { | |
testResult = testNewImage(); | |
} | |
float[] gradientsForImage(PImage img) { | |
// resize the images to a consistent size: | |
img.resize(50, 50); | |
// settings for Histogram of Oriented Gradients | |
// (probably don't change these) | |
int window_width=64; | |
int window_height=128; | |
int bins = 9; | |
int cell_size = 8; | |
int block_size = 2; | |
boolean signed = false; | |
int overlap = 0; | |
int stride=16; | |
int number_of_resizes=5; | |
// a bunch of unecessarily verbose HOG code | |
HOG_Factory hog = HOG.createInstance(); | |
GradientsComputation gc=hog.createGradientsComputation(); | |
Voter voter=MagnitudeItselfVoter.createMagnitudeItselfVoter(); | |
HistogramsComputation hc=hog.createHistogramsComputation( bins, cell_size, cell_size, signed, voter); | |
Norm norm=L2_Norm.createL2_Norm(0.1); | |
BlocksComputation bc=hog.createBlocksComputation(block_size, block_size, overlap, norm); | |
pixelGradients = gc.computeGradients(img, this); | |
Histogram[][] histograms = hc.computeHistograms(pixelGradients); | |
Block[][] blocks = bc.computeBlocks(histograms); | |
Block[][] normalizedBlocks = bc.normalizeBlocks(blocks); | |
DescriptorComputation dc=hog.createDescriptorComputation(); | |
return dc.computeDescriptor(normalizedBlocks); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment