简体   繁体   English

Kinect v2:空间分辨率/深度分辨率/相机校准

[英]Kinect v2: Spatial resolution/ depth resolution / camera calibration

For my application, I analyzed the spatial resolution of the Kinect v2. 对于我的应用程序,我分析了Kinect v2的空间分辨率。

To analyze the spatial resolution, I recorded a perpendicular and planar plane to a given distance and converted the depth map of the plane to a point cloud. 为了分析空间分辨率,我记录了垂直平面和给定距离的平面,并将该平面的深度图转换为点云。 Then I compare a point to his neighbors by calculating the euclidian distance. 然后,我通过计算欧几里得距离,将一个点与他的邻居进行比较。

Calculating the euclidian distance for this case (1 meter between plane and kinect) the resolution is close to 3 mm between the points. 计算这种情况下的欧式距离(平面与kinect之间1米),点之间的分辨率接近3 mm。 For a plane with 2 meters distance I got a resolution up to 3 mm. 对于2米距离的飞机,我的分辨率高达3毫米。

Comparing this to the literature, I think my results are quite bad. 与文献比较,我认为我的结果很差。

For example Yang et al. 例如Yang等。 got for a plane with distance of 4 meters to the kinect a mean resolution of 4mm ( Evaluating and Improving the Depth Accuracy of Kinect for Windows v2 ) 对于与kinect的距离为4米的飞机,平均分辨率为4mm( 评估和提高Kinect for Windows v2的深度精度

Here a example for my point cloud of the planar plane (2 meter distance to my kinect): 这是我的平面点云的示例(距我的Kinect 2米):

距Kinect v2 2米

Anyone made some observation regarding to spatial resolution of the Kinect v2 or an idea why my resolution is bad like that? 任何人都对Kinect v2的空间分辨率有任何观察,或者是为什么我的分辨率如此差的想法?

In my opinion i think there went something wrong when converting my depth image to world coordinates. 我认为将深度图像转换为世界坐标时出了点问题。 Therefore here a code snipped: 因此,这里有一段代码:

%normalize image points by multiply inverse of K
u_n=(u(:)-c_x)/f_x;
v_n=(v(:)-c_y)/f_y;
% u,v are uv-coordinates of my depth image

%calc radial distortion
r=sqrt(power(u_n,2)+power(v_n,2));
radial_distortion =1.0 + radial2nd * power(r,2) + radial4nd * power(r,4) + radial6nd * power(r,6);

%apply radial distortion to uv-coordinates
u_dis=u_n(:).*radial_distortion;
v_dis=v_n(:).*radial_distortion;

%apply cameramatrix to get undistorted depth point
x_depth=u_dis*f_x+c_x;
y_depth=v_dis*f_y+c_y;

%convert 2D to 3D
X=((x_depth(:)-c_x).*d(:))./f_x;
Y=((y_depth(:)-c_y).*d(:))./f_y;
Z=d;  % d is the given depth value at (u,v)

EDIT: So far I also tried to go include the points directly from coordinate mapper without further calibration steps. 编辑:到目前为止,我还试图直接从coordinate mapper包含点,而无需进一步的校准步骤。

The results regarding to the resolution are still the same. 有关分辨率的结果仍然相同。 Has anyone any comparing results? 有谁比较结果吗?

@JavaNullPointer, the way you are converting your information to 3D using Kinect v2 isn't still very well accepted by the community. @JavaNullPointer,使用Kinect v2将信息转换为3D的方式尚未为社区所接受。

Also those calculations that you are making are pretty much following the work of Nicholas Burrus - http://burrus.name/index.php/Research/KinectCalibration 另外,您正在进行的这些计算几乎都遵循Nicholas Burrus的工作-http: //burrus.name/index.php/Research/KinectCalibration

For Kinect v2, there isn't still much information on how to this as well. 对于Kinect v2,关于如何执行此操作的信息仍然很少。 Nevertheless, the new SDK features allows you to save a Kinect Calibration table space. 不过,新的SDK功能可让您节省Kinect校准表空间。

The procedure is quite simple: 程序非常简单:

1- you need to save this table information - https://msdn.microsoft.com/en-us/library/windowspreview.kinect.coordinatemapper.getdepthframetocameraspacetable.aspx 1-您需要保存此表信息-https://msdn.microsoft.com/zh-cn/library/windowspreview.kinect.coordinatemapper.getdepthframetocameraspacetable.aspx

2- once you save this information to file, you can then indeed convert your depth points (2D) into 3D camera space. 2-将这些信息保存到文件后,便可以将深度点(2D)转换为3D相机空间。

Here goes the code you should use: 这是您应该使用的代码:

// Get the depth for this pixel
ushort depth = frameData[y * depthFrameDescription.Height + x];

// Get the value from the x/y table
PointF lutValue = this.cameraSpaceTable[y * depthFrameDescription.Height + x];

// create the CameraSpacePoint for this pixel
// values are in meters so convert
CameraSpacePoint csp = new CameraSpacePoint();
csp.X = lutValue.X * depth * 0.001f;
csp.Y = lutValue.Y * depth * 0.001f;
csp.Z = depth * 0.001f;

Also, take a lot at: 另外,请注意以下几点:

https://msdn.microsoft.com/en-us/library/windowspreview.kinect.coordinatemapper.mapdepthframetocameraspace.aspx https://msdn.microsoft.com/zh-CN/library/windowspreview.kinect.coordinatemapper.mapdepthframetocameraspace.aspx

or 要么

https://msdn.microsoft.com/en-us/library/windowspreview.kinect.coordinatemapper.mapdepthframetocameraspaceusingibuffer.aspx https://msdn.microsoft.com/zh-CN/library/windowspreview.kinect.coordinatemapper.mapdepthframetocameraspaceusingibuffer.aspx

In addition, depth, infrared, bodyindex streams are all aligned (same resolution) therefore you just really this. 此外,深度,红外,身体指数流都对齐(相同的分辨率),因此您确实是这样。 If you need to get the color points as well, you should save that mapping as well. 如果还需要获取色点,则还应保存该映射。 All this information is available in the Kinect MSDN 2.0 website. 所有这些信息都可以在Kinect MSDN 2.0网站上找到。

I hope you are able to save this information and then re-do this spatial resolution test. 我希望您能够保存此信息,然后重新执行此空间分辨率测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM