Permalink
Browse files

Initial import

  • Loading branch information...
hcarvalhoalves committed Feb 22, 2010
0 parents commit b90c545c603b943bd30077cdb5821e4f3e714586
Showing with 142 additions and 0 deletions.
  1. +74 −0 CamMesh.pde
  2. +68 −0 Functions.pde
  3. BIN data/Menlo-Bold-12.vlw
@@ -0,0 +1,74 @@
+import processing.video.*;
+import megamu.mesh.*;
+
+Capture video;
+PImage buffer;
+int[] lastFrame;
+
+Delaunay mesh;
+float[][] points;
+
+boolean renderMesh = false;
+float threshold = 0.25;
+float maxDistance;
+
+void setup() {
+ size(512, 400);
+
+ background(0, 0, 0);
+ fill(255, 255, 255);
+ stroke(255, 255, 255);
+
+ hint(ENABLE_NATIVE_FONTS);
+ textFont(loadFont("Menlo-Bold-12.vlw"));
+
+ video = new Capture(this, 512, 400);
+ buffer = new PImage(video.width, video.height);
+ lastFrame = new int[video.width * video.height];
+ maxDistance = dist(0, 0, video.width, video.height);
+}
+
+void draw() {
+ if (video.available()) {
+ video.read();
+ video.filter(GRAY);
+ set(0, 0, video);
+
+ buffer.pixels = video.pixels;
+ buffer.pixels = getPixelEdges(getDifference(buffer.pixels, lastFrame));
+ buffer.filter(THRESHOLD, threshold);
+ if (!renderMesh) {
+ blend(buffer, 0, 0, video.width, video.height, 0, 0, video.width, video.height, ADD);
+ }
+
+ if (renderMesh) {
+ points = getPoints(buffer.pixels);
+ mesh = new Delaunay(points);
+ float[][] edges = mesh.getEdges();
+ for(int i=0; i<edges.length; i++) {
+ float sx = edges[i][0];
+ float sy = edges[i][1];
+ float ex = edges[i][2];
+ float ey = edges[i][3];
+ float distance = dist(sx, sy, ex, ey);
+ if (distance < maxDistance/4) {
+ float strokeAlpha = norm(distance, 0, maxDistance/8);
+ stroke(255, 255, 255, 255 - (255*strokeAlpha));
+ line(sx, sy, ex, ey);
+ }
+ }
+ }
+
+ text("FPS: " + frameRate, 5, 15);
+ text("Threshold (+/-): " + threshold, 5, 35);
+ text("Render Mesh (M): " + renderMesh, 5, 55);
+ }
+}
+
+void keyPressed() {
+ if (key == 'm') renderMesh = !renderMesh;
+ if (key == 's') save("screenshot-" + millis() + ".png");
+ if (key == '=') threshold += 0.05;
+ if (key == '-') threshold -= 0.05;
+ threshold = constrain(threshold, 0.1, 0.9);
+}
@@ -0,0 +1,68 @@
+float[][] kernel = {
+ { -1, -1, -1},
+ { -1, 5, -1},
+ { -1, -1, -1},
+};
+
+int[] getPixelEdges(int[] img) {
+ for (int y = 1; y < video.height-1; y++) {
+ for (int x = 1; x < video.width-1; x++) {
+ float sum = 0;
+ for (int ky = -1; ky <= 1; ky++) {
+ for (int kx = -1; kx <= 1; kx++) {
+ // Calculate the adjacent pixel for this kernel point
+ int pos = (y + ky)*video.width + (x + kx);
+ // Multiply adjacent pixels based on the kernel values
+ // Use Red channel, normally it's the best channel for webcams
+ sum += kernel[ky+1][kx+1] * ((img[pos] >> 16) & 0xFF);
+ }
+ }
+ // For this pixel in the new image, set the gray value
+ // based on the sum from the kernel
+ img[y*video.width + x] = color(sum);
+ }
+ }
+ return img;
+}
+
+int[] getDifference(int[] frame, int[] lastFrame) {
+ int[] diff = new int[frame.length];
+ for (int i = 0; i < frame.length; i++) {
+ color currColor = frame[i];
+ color prevColor = lastFrame[i];
+ int currR = (currColor >> 16) & 0xFF;
+ int currG = (currColor >> 8) & 0xFF;
+ int currB = currColor & 0xFF;
+ int prevR = (prevColor >> 16) & 0xFF;
+ int prevG = (prevColor >> 8) & 0xFF;
+ int prevB = prevColor & 0xFF;
+ int diffR = abs(currR - prevR);
+ int diffG = abs(currG - prevG);
+ int diffB = abs(currB - prevB);
+ diff[i] = 0xff000000 | (diffR << 16) | (diffG << 8) | diffB;
+ lastFrame[i] = currColor;
+ }
+ return diff;
+}
+
+float[][] getPoints(int[] img) {
+ int numPoints = 0;
+ for (int y = 1; y < video.height-1; y++) {
+ for (int x = 1; x < video.width-1; x++) {
+ if (((img[y*video.width + x] >> 16) & 0xFF) > 0) numPoints++;
+ }
+ }
+
+ float[][] points = new float[numPoints][2];
+ int i = 0;
+ for (int y = 1; y < video.height-1; y++) {
+ for (int x = 1; x < video.width-1; x++) {
+ if (((img[y*video.width + x] >> 16) & 0xFF) > 0) {
+ float[] p = {x, y};
+ points[i] = p;
+ i++;
+ }
+ }
+ }
+ return points;
+}
Binary file not shown.

0 comments on commit b90c545

Please sign in to comment.