我正在尝试将Kinect深度图转换为米数距离。问题在于,对于深度图值“1080”及其周围的值,分母中的项变得非常接近“0”,因此距离过大。而对于大于“1090”的值,距离则为负数。
if (depthValue < 2047)
{
depthM = 1.0 / (depthValue*-0.0030711016 + 3.3309495161);
}
我正在尝试将Kinect深度图转换为米数距离。问题在于,对于深度图值“1080”及其周围的值,分母中的项变得非常接近“0”,因此距离过大。而对于大于“1090”的值,距离则为负数。
if (depthValue < 2047)
{
depthM = 1.0 / (depthValue*-0.0030711016 + 3.3309495161);
}
正确答案实际上是对您问题的评论。给出的数字实际上是毫米单位的距离。要获取此数字,您需要使用骨架关节并调用DepthImageFrame的MapFromSkeletonPoint方法,或者将原始短值向右移DepthImageFrame.PlayerIndexBitmaskWidth位。
例如:Skeleton
using (var skeletonFrame= e.OpenSkeletonFrame())
using (var depthFrame = e.OpenDepthImageFrame())
{
skeletonFrame.CopySkeletonDataTo(skeletons);
var skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
foreach (var skeleton in skeletons)
{
if (skeleton.TrackingState != SkeletonTrackingState.Tracked) continue;
var head = skeleton.Joints[JointType.Head];
if (head.TrackingState == JointTrackingState.NotTracked) continue;
var depthImagePoint = depthFrame.MapFromSkeletonPoint(head.Position);
int depthInMillimeters = depthImagePoint.Depth; // TADA!
}
}
例如,shift
using (var depthFrame = e.OpenDepthImageFrame())
{
var depthArray = new short[depthFrame.PixelDataLength];
depthFrame.CopyPixelDataTo(depthArray);
for (int i = 0; i < depthArray.Length; i++) {
int depthInMillimeters =
depthArray[i] >> DepthImageFrame.PlayerIndexBitmaskWidth;
// TADAx2!
}
以下的原解决方案已经不再正确:
根据这篇文章所述的内容:
if (depthValue <= 2047) {
depthM = 0.1236 * Math.Tan(depthValue / 2842.5 + 1.1863);
}
虽然这是一个旧问题,但对我有用的是我有一款旧版的 kinect (XBOX360 + PC reduction 的1414型号)。最近我有时间编写了一些代码和测量:
my raw data is 16 bit not 10/11/12/13 bit !!!
so probably your data is very similar. Min distance measured is ~0.95m
max distance unknown (have not big enough area for testing) and min valid value is 6408 ... ~0.95m
from sensor . Another valid value is 15800 ... ~2.5m
from sensor for interpolation
naive (linear) transformation to meters
float z,m=(2.5-0.9)/(15800.0-6408.0);
WORD raw;
raw=... raw depth form camera/image;
z=0.0;
if ((raw>=6408)&&(raw< 0xFFF0))
z=0.9+(float(raw-6408)*m);
// here z is range in [m] or 0 for invalid depth
when I will have more time then I will check the linearity and make it more precise
to do that I need to make some programing for better measurement and setup working area for more precise distance measurements. More precise constants maybe add cosine correction if its needed. I do not know if device/driver make it itself or not have to measure it. When I get to it will update my answer but I am very lazy so it can be a while ...
[编辑1] 进行了一些几何测量设置和代码更改
因此,这里有一些新的更精确的结论:
if (raw==0x0000) z=0.0;
else if (p.raw>=0x8000) p.z=4.0;
else p.z=0.8+(float(p.raw-6576)*0.00012115165336374002280501710376283);
原始
数据已经通过驱动程序或kinect
本身进行余弦校正,因此原始
表示与传感器垂直的距离。 原始
数据与垂直距离成线性关系(至少在0.8-2.0米的范围内),经过更精确的测量,深度范围为<0.8-4.0>[m]
。之前的测量不准确。
原始 = 0
是太近的值
原始 >= 32768
是太远/未知的值,甚至可能是其他东西(还有更多可能性)