Class 12 - More motion tracking applications
|
Motion tracking examples
|
|
For some applications, it may be difficult or not necessary to identify the shape of an object. All we need is to find out the changes in motion within the camera frame. In this section, we try to use a simplified version to identify the optical flow.
In this simple version, we divide the screen into grids. We use two constant variables
And we have 2 PImage variables
We use img1 to store the current image from the camera (JMyron) and img2 the previous image. In each frame, we copy the image from img1 to img2 first and then refresh img1 with the latest camera image. We use a temporary data structure Point class to hold the information for each point.
All the data elements for the program are:
The setup() function is pretty straight forward.
We delay the complexity of the draw() function by just putting a findFlow() function there.
The findFlow() function is a double for loop to scan through the pixels in img2 first. Note that xOff and yOff are half the size of w and h for the definition of the neighborhood size. We also start the loop at index 1, rather than 0, in order to skip those points on the edges.
There are 2 remaining functions, findPoint() and drawLine(). The simple one is drawLine(). It draws a straight line connecting the 2 points, from p2 to p1. In order to show the flow direction, we draw 2 more tiny lines to form an arrow. The two tiny lines are drawn at 30 degree (PI/6) connecting to the end point, _p.
The complicated one is the findPoint() function, which needs to search through the neighborhood in img2 of a given point in img1.
The matchCol() function is the same one we have been using in previous class.
Now combine everything to create the first program visualizing the flow.
|
|
The next step is not to use the whole screen as the control area. We define a smaller region with a class Region and calculate the flow within that region to determine the actions.
Given all those arrows inside the region, all we need to do is to find out the overall (average) movement and store it in 2 variables,
such that the region can move according to these values. You can play around with the source and modify for your own creative needs Region class
Point class
Main program
Another variation: change the flow information into force to control the acceleration, rather than velocity of the Region.
|
|
The overall motion information from the arrows can give you another piece of hint. Try to imagine that the arrows can also show the direction of rotation of the object (region) on the screen. That is, the object can rotate around its centre of gravity. The arrows are thus indicators of how it rotates.
cx, cy is the centre of the region. When a pixel moves from p2 to p1, we try to approximate the angular movement it induces. We are going to use the sum: d2*d1*sin(a2-a1) for the purpose.
|
|
Region with translation and rotation The following combines the linear and angular movements to form an intuitive interface. It may need some time to adapt to the motion.
Sources for discussion:
|
|
Besides using flow as an interaction device, you can consider creative application by making use of the flow information. Here is a simple example. Given the flow information for each point in the grid, if we take the length of each arrow and use it as the z shift of an vertex at that point. See what happens.
Going back to the code, the length of each arrow is:
The length of each arrow is the distance between p1 and p2, i.e., dist(p1.x,p1.y,p2.x,p2.y) Rather than displaying the webcam video with an image() command, we can use texture map to skin the image onto a grid. First of all, we modify the Point class to include z dimension.
A 2D array grid is defined to maintain the vertex information.
To initialize the grid information,
To map the image texture onto the grid,
We can then modify the findFlow() function to change the z value for the points in the grid.
You can also use the flow information to change the x and y values of the points in the grid.
|
|
A day at the gallery, Romy Achituv
4th Dimension, Zbig Rybczynski
Khronos Projector Demo video (wmv)
The Last Clock Demo video (mov)
TX transform
|
|
Face detection Download and unpack the file pFaceDetect.zip into your Processing libraries folder. Add the following file into the data folder of your sketch. If you do not have OpenCV installed, copy the following files in the Processing root folder. Here is a simple demonstration program.
|