CV: Blob tracking

We’ll start by importing the video library and declaring some variables. We need a Capture object to access the webcam and an integer variable to use as a threshold value. The other integer variables are used to track the boundaries around the white pixels in the image. import processing.video.*; Capture webcam; int threshold; int topLeftX; int topLeftY; int bottomRightX; int bottomRightY; void setup() { size( 640, 480 ); webcam = new Capture( this, width, height, 30); webcam.start(); threshold = 127; topLeftX = width; topLeftY = height; bottomRightX = 0; bottomRightY = 0; } Inside the draw() function, we’ll apply the threshold algorithm, just like we did in the Thresholding video recipe. We’ll loop through the pixel array with a nested for loop, because¬†we need to know the exact location of the white pixels, so that we can update the boundary¬†variables. The rest of the code is the same as the threshold video sketch. void draw() { if ( webcam.available() ) { webcam.read(); image( webcam, 0, 0 ); loadPixels(); int counter = 0; for ( int j = 0; j < webcam.height; j++ ) { for ( int i = 0; i < webcam.width; i++ ) { color c = webcam.pixels[counter]; float b = brightness( c ); if ( b > threshold ) { pixels[counter] = color( 255 ); if ( i < topLeftX ) { topLeftX = i; } if ( j < topLeftY ) { topLeftY = j; } if ( i > bottomRightX ) { bottomRightX = i; } if ( j > bottomRightY ) { bottomRightY = j; } } else { pixels[counter] = color( 0 ); } counter++; } } updatePixels(); noFill(); stroke( 255, 0, 0 ); strokeWeight( 2 ); rect( topLeftX, topLeftY, bottomRightX – topLeftX, bottomRightY – topLeftY ); // reset tracking points topLeftX = width; topLeftY = height; bottomRightX = 0; bottomRightY = 0; fill( 255, 0, 0 ); noStroke(); rect( 10, 10, 110, 20 ); fill( 255 ); text( “Threshold: ” + threshold, 14, 24 ); } } void keyPressed() { if ( key == CODED ) { if ( keyCode == UP ) { threshold++; } if ( keyCode == DOWN ) { threshold–; } } } If you run the sketch, you’ll see a red rectangle around the white pixels. This algorithm works best in a dark room where you put light on your subject. The tracking algorithm is quite easy. If the brightness of a pixel is greater than the threshold value, we set the pixel to white. In each frame, the values for the top, left-hand side and bottom, right-hand side corner of the boundary box are calculated. Let’s take a look at how this works for the top, left-hand side corner. At the beginning of each frame, the value of the topLeftX variable is equal to the width of the sketch window. The topLeftY variable is equal to the height of the window. These two variables point to the bottom, right-hand side corner of the sketch window. topLeftX = width; topLeftY = height; The for loop with the i counter is used to loop through the horizontal lines of pixels. If the pixel is white, we compare the position to the topLeftX value. If it is smaller, we change the value of the topLeftX variable. This way, we’ll always end up with the x coordinate of the white pixel closest to the left-hand side of the window. The for loop with the j counter is used to loop through the vertical lines of pixels. We use the same idea to get the y coordinate of the white pixel that is closest to the top of the window. I’ve used the min() function to do this. The following function returns the smallest value for the two variables passed: topLeftX = min( i, topLeftX ); topLeftY = min( j, topLeftY ); The i and j counter variables are also compared to the bottomRightX and bottomRightY values, to calculate the top, left-hand side corner of the sketch window. But this time, they have to be bigger. I’ve used the max() function to do this. This function does the opposite of the min() function and returns the largest number of the two variables you’ve passed. Once we have found the coordinates we need, we can draw a rectangle around the white pixels with this line: rect( topLeftX, topLeftY, bottomRightX – topLeftX, bottomRightY -topLeftY ); After drawing the rectangle, it’s important to set the coordinates of the rectangle to their initial values, so that we can calculate them again for the next video frame.

The best way to predict the future is to invent it (Alan Kay)