3
votes

I'm working on a Kinect camera to get the depth data. So far my app works, i got out the 13 bits of depth info, excluded player data. Placed it on a 24bits RGB bitmap (i didnt like rgb656), well the mdf app looks great works fine, no problems in that area, no bit shift errors etc. (and no need for WPF to display it)

However.. I went on and wanted to verify it to real world measurements. I am using the orginal Microsoft SDK (i think thats 1.7 for windows 7).

And then i noticed that despite i do get the correct bits, the error rate is still to high for me to work with. See the table below where i put in Kinect and (real) world millimeter measurements using a (much cheaper) tape-measure tool to verify it

(Measurement is from frontal midpixel, its not under angle to an object)

kinect  world    err
 800    800      0
 894    900      6
 987    1000    13
1082    1100    18
1179    1200    21
1271    1300    29
1366    1400    34
1459    1500    41
1550    1600    50
1647    1700    53
1730    1800    70
1831    1900    69
1924    2000    76
2014    2100    86
2112    2200    88
2207    2300    93

By some trial and error, i found that kinect depth data multiplied by 1,0063 does give a bit better results. Now although that it improves it a bit. I do wonder if there is some formula that would work better, because multiplying by 1,0063 is well ..pretty linear math, and perhaps this should be exponential, logarithmic, or ???. I just think the error rate isnt really linear.

Above data, i took manually (so likely it contains some small humman measurement errors because of that too) I'm looking for some math that could also provide the possible deviation plusminus. like the distance is 730mm and possibly 12mm above or below that.

I code in C#, i'm a starter and new here. And maybe this is not a straight question about C#, but its a bit a of coding dilemma, and i've seen other subjects here were people ask for the right formula's (wel coding is a lot of that). And there is a pretty strong kinect community here. Most likely one you here knows a better answer then my 1,0063

I can read about 12 coding languages, so if you know an answer in a different language its fine too. Things that dont help me, is use Aforge/OpenCV/xyz/Mathlab/etc Sure they are great but if i need only 1 function, then i prefer not to use them, as all other graphic stuff for this project i do in my own libraries. (because i find it cool to learn about these things)

---Update Not yet nailed it, but besides depth 1,0063 It seams that :

depth = kinectdept * ( kinectdepth - 800 ) * 0,069

comes pretty close too. Strangely the error rate as in above table quite closely seams

(realDepth-800)/16 

But i need more samples to verify it as the human err is to large here.

1
That sound you just heard was my head exploding. - durbnpoisn
:) did i do to much typing ? - Peter
No, it's just that this is the first time I've seen someone asking something quite that advanced. - durbnpoisn
I've no clue whatsoever to expect for accuracy of depth readings from Kinect (do you have documentation?). Trying graphing your error measurements, they almost look linear. Also try other lighting scenarios, other targets. You might to also trying looking at http://electronics.stackexchange.com/. - Chris O
Also see msdn kinect forum post which also references this fascinating ROS post, which mentions something about the importance of calibration. - Chris O

1 Answers

2
votes

Alarm bells went off here when I read how serious this error is. Personally I am kind of amazed this didn't trigger more attention here. I started testing and found a slightly different result. I assume you made a small error in the formula you wrote down. I get best results with :

//Below  1300mm
kinectDepth = kinectDepth + (kinectDepth -800) * 0,05
// range 1350mm 2050mm
kinectDepth = kinectDepth + (kinectDepth -800) * 0,064
// range 2050mm 2850mm
kinectDepth = kinectDepth + (kinectDepth -800) * 0,069
// beyond 2900mm 
kinectDepth = kinectDepth + (kinectDepth -800) * 0,08
// beyond 3500mm
kinectDepth = kinectDepth + (kinectDepth -800) * 0,085

Notice that we didn't get exact mm often, we saw numbers jumping in cm when more far ahead, at close range it jumps 2mm ~ 4mm.

I didn't have a chance to test it with other Kinects, but in case others like to share their testing too, we simply took Excel, put in your math and kept a $B$1 to point to a single value (ea 0,05).

We took our test results from column A, and made 2 correction columns by your maths to compare the results. For the ranges we used, we made per range a small line graph, and visually tested best fit. We also took some trend lines but that was less handy for this. Since there is at some distance more inaccuracy variation at some specific intervals like a shape that's a wave that grows over time (not a straight line).

Also because we have an upscaling correction this likely is non-linear. But I couldn't figure it out so i corrected a function based upon above

I hope some more people could test this so we could find a real solution for it. My answer isn't the solution I think, but I hope someone could improve and post a better solution based upon my and your results. So I post this as "a test" result solution not as a "a final" solution.