So, with the lag in Kinect imaging finally sorted out, and with a program (thanks to
Making Things See by Greg Boorenstein) that successfully tracks the point closest to the Kinect I decided it was time to create a program capable of tracking the velocity of that closest point. The first step in doing so was to compensate for the fact that the closest-point program I'm using tracks x and y-values based upon pixels. Obviously, a movement of 5 pixels three feet from the Kinect is smaller than a movement of 5 pixels twenty feet from the Kinect, so some sort of calibration was necessary to attain consistent velocity values. To accomplish this calibration, I first determined the field of view of the Kinect by taking specs. I found online and expanding upon them with some trig. functions, as shown below:
Field of View Calculations
Next, I needed to write an algorithm that would take those field of vision calculations, as well as the Kinect's generated depth values (ranging from 0 to 2048), and determine the ball's velocity based upon them. Below is a picture of the calculations I used, as well as an explanation of variable and my procedure.
Velocity Algorithm Calculations
- First, delta x and delta y (the difference between the Kinect's horizontal and vertical fields of view at 6m and at .7m) were computed.
- Delta x and y were then divided by 2048 (the maximum depth value the Kinect returns) to determine the x-constant (Xc) and y-constant (Yc)--the amount in meters that the horizontal and vertical fields of vision of the Kinect grow by for each unit of depth.
- Xc was then multiplied by D (the depth value of the closest point as returned by the Kinect). The resulting product was then added to the minimum horizontal field of view (.7601m) to determine the size of the horizontal field of view at depth D. The resulting sum was then divided by 640 (the number of pixels making up the horizontal field of view) to yield the value Ux (the distance in meters between each pixel at a given depth D in the x-dimension).
- The same process was undertaken to determine Uy, though a different value (.5515m) was used for the minimum field of view and a different number of pixels (480) was used as a divisor, in accordance with the y-field's smaller size.
- Next, the velocity in the x direction (Vx), was determined by multiplying Ux by delta pixelsx (the change in x value (in pixels) from one Kinect measurement to the next) and by 24 (the number of Kinect measurements (as determined by Kinect frame rate) per second). By multiplying by 24 in this manner, the Vx value returned is in m/s, rather than in m/((1/24)s), which would be a really irritating unit to have to deal with.
- The velocity in the y direction (Vy) was determined in the same manner.
At
this point, I realized that I'd forgotten I needed the ball's velocity
in the z-direction as well, so I began another set of similar
calculations:
- First, delta z was determined by subtracting the minimum functioning Kinect distance from the maximum (6m-.7m).
- This value was then divided by 2048 (the max depth value returned by the Kinect) to determine a z-constant (Zc)
- Zc was then multiplied by D (the depth value).
The resulting product was then added to the minimum depth (.7m) to determine the true depth at returned
depth D. The resulting sum was then divided by 2048 (the max depth value) to yield the value Uz.
- Uz was then multiplied by delta D (the change in depth from one Kinect measurement to the next) and multiplied by 24 to yield Vz in m/s.
FINAL VELOCITY CALCULATION:
With these myriad values determined, I then needed to calculate the overall velocity:
- The magnitude of the overall velocity (Mv) was calculated by taking the square root of (Vz)^2 + (Vx)^2 + (Vy)^2.
- The angle of the overall velocity (with respect to the z-axis) was then determined by taking arcsin(Vx/Mv)
This algorithm has been used to produce a functional Processing program in conjunction with the Kinect. A video of this program in action will be uploaded in the near future (ie. as soon as I find a program that allows me to take video of what's happening on my computer screen)