compute distance from depth images (libfreenect)

3,780 views
Skip to first unread message

Kang

unread,
Feb 10, 2012, 2:44:15 PM2/10/12
to OpenKinect
Hi,

I record depth images from kinect using libfreenect.
I have problem in computing the right distance from depth images.
What I did is convert the values in the depth images to binary and get
the last 11 bit as described int the web. Then followed the formula
there:

distance = 0.1236 * tan(rawDisparity / 2842.5 + 1.1863)
from here
http://openkinect.org/wiki/Imaging_Information

But, I got unreasonable value of the depth, including some negative
values. Could someone help to point where it went wrong?

Second question is if I record as video using libfreenect (record). it
uses the ffmpeg and save the depth as rgb24 (3 channel). How should
the distance be restore from here?

Thanks in advanced.

best,
kang


drew.m...@gmail.com

unread,
Feb 10, 2012, 3:14:28 PM2/10/12
to openk...@googlegroups.com
On Fri, Feb 10, 2012 at 11:44, Kang <wandis...@gmail.com> wrote:
> Hi,
>
> I record  depth images  from kinect using libfreenect.
> I have problem in computing the right distance from depth images.
> What I did is convert the values in the depth images to binary and get
> the last 11 bit as described int the web. Then followed the formula
> there:
>
> distance = 0.1236 * tan(rawDisparity / 2842.5 + 1.1863)
> from here
> http://openkinect.org/wiki/Imaging_Information

Try just using the FREENECT_DEPTH_MM depth format, which will give a
distance in millimeters using a slightly smarter distance
reconstruction algorithm. If you want the RGB and depth images to
overlay directly, try using the FREENECT_DEPTH_REGISTERED depth
format, which will also align the depth image with the RGB image.

> Second question is if I record as video using libfreenect (record). it
> uses the ffmpeg and save the depth as rgb24 (3 channel). How should
> the distance be restore from here?

The output of the record program is meant to be used with fakenect:

http://openkinect.org/wiki/Fakenect

At this point, fakenect/record don't have support for depth formats
other than FREENECT_DEPTH_11BIT, but you could probably hack it to use
your format of choice.

-Drew

Kang

unread,
Feb 10, 2012, 3:25:41 PM2/10/12
to OpenKinect
Hi Drew,

Thanks for your reply. But for the 11 bit depth in pgm images.
Is the callculation I described in previous message correct?

Best,
Kang

On Feb 10, 9:14 pm, "drew.m.fis...@gmail.com"
<drew.m.fis...@gmail.com> wrote:

drew.m...@gmail.com

unread,
Feb 10, 2012, 3:33:25 PM2/10/12
to openk...@googlegroups.com
On Fri, Feb 10, 2012 at 12:25, Kang <wandis...@gmail.com> wrote:
> Hi Drew,
>
> Thanks for your reply. But for the 11 bit depth in pgm images.
> Is the callculation I described in previous message correct?

The formula you gave was an approximation empirically derived during
the very early days of OpenKinect. Since then, we've added functions
that use more precise trigonometry and take into account the internal
parameters of the Kinect, so I suggest using those instead via
FREENECT_DEPTH_MM.

-Drew

Kang

unread,
Feb 13, 2012, 6:26:53 AM2/13/12
to OpenKinect
Hi Drew,

Thanks. I tried the registered one. It seems reasonable now, though
not very accurate as I am expecting.
One more question, about transform these depth to cloud, is the one in
the web still up to date?
///////////////
x = (i - w / 2) * (z + minDistance) * scaleFactor * (w/h)
y = (j - h / 2) * (z + minDistance) * scaleFactor
z = z
Where
minDistance = -10
scaleFactor = .0021.
//////////////

best,
kang

Kang

unread,
Feb 13, 2012, 8:06:59 AM2/13/12
to OpenKinect
Hi Drew,

If I use the FREENECT_DEPTH_REGISTERED (instead of
FREENECT_DEPTH_11BIT ) in the record.c code,
without any calculation, the 16 bit pixel in pgm depth image should be
already in millimeters right? (in range of 0-10000 if there is data).
I got most pixel value more than 10000.

best,
Kang

Sweety Pie

unread,
Feb 13, 2012, 9:19:18 AM2/13/12
to OpenKinect
Hi there,
Sorry for this but I really need your help. I need to record depth
images from kinect using libfreenect as well. I have a x64 bit
Windows machine so will it work with it??
Thanks in advance.

On Feb 10, 10:44 pm, Kang <wandisusa...@gmail.com> wrote:
> Hi,
>
> I record  depth images  from kinect using libfreenect.
> I have problem in computing the right distance from depth images.
> What I did is convert the values in the depth images to binary and get
> the last 11 bit as described int the web. Then followed the formula
> there:
>
> distance = 0.1236 * tan(rawDisparity / 2842.5 + 1.1863)
> from herehttp://openkinect.org/wiki/Imaging_Information

Armin Kazim

unread,
Mar 18, 2015, 6:28:16 AM3/18/15
to openk...@googlegroups.com
Hi everyone this is my code in opencv with libfreenect to get depth information;
Freenect::Freenect freenect;
MyFreenectDevice& device = freenect.createDevice<MyFreenectDevice>(0);
Freenect::Freenect freenect2;
MyFreenectDevice& device2 = freenect2.createDevice<MyFreenectDevice>(1);
device.setDepthFormat(FREENECT_DEPTH_REGISTERED);
device2.setDepthFormat(FREENECT_DEPTH_REGISTERED);
device.startVideo();
device.startDepth();
device2.startVideo();
device2.startDepth();
Mat picright,depthright(Size(640,480),CV_16UC1);
Mat picleft,depthleft(Size(640,480),CV_16UC1);
unsigned int frame_count = 0;
while(char(waitKey(1)) != 'q') {
double t0 = getTickCount();
device.getVideo(picright);
device.getDepth(depthright);
device2.getVideo(picleft);
device2.getDepth(depthleft);
//cout << left.size() <<right.size()<< endl;
if(!(depthleft.empty()) && !(depthright.empty())){
int z = depthright.at<uint16_t>(200, 200);
uint16_t b = z;
cout << b <<endl;
z = depthright.at<uint16_t>(200, 200);
b =z;
cout << b <<endl;
z = depthleft.at<uint16_t>(200,200);
b =z;
cout << b <<endl;
z = depthleft.at<uint16_t>(210, 210);
b = z;
cout << b <<endl;
for(int h=0;h<2;h++){
int ans = 0;
int falseva = 0;
int sum = 0;
for(int x=300;x<340;x++){
for(int y=250;y<270;y++){
if(h==1){ z = depthleft.at<uint16_t>(x, y);}
else{ z = depthright.at<uint16_t>(x, y);}
if(z > 200){
sum = sum + (int) z;
//cout << (int) z <<endl;
ans++;
}
if(z <200){
falseva++;
}
}
}
//while(char(waitKey(1)) != ' ') {}
if(ans != 0){
if(h == 0){
cout << "average: "<<sum/ans <<" bei " << ans<<"und: "<<falseva<<"around left 320 260"<< endl;
}
else{
cout << "average: "<<sum/ans <<" bei " << ans<<"und: "<<falseva<<"around right 320 260"<<endl;
}
}
}
}
notice that i use two cameras and get therefore the informations two times this is not neccassary hope i could help you also you should know that distance smaller than 400 mm can't be measured
Reply all
Reply to author
Forward
0 new messages