我正在尝试将 Kinect 深度图转换为以米为单位的距离。问题是对于深度图值“1080”及其周围,距离太大,因为分母中的项变得非常接近“0”。对于“1090”以上的值,距离为负数。
if (depthValue < 2047)
{
depthM = 1.0 / (depthValue*-0.0030711016 + 3.3309495161);
}
正确答案实际上是对您的问题的评论。给出的数字实际上是以毫米为单位的距离。要获得这个数字,您要么需要使用骨架关节并调用 DepthImageFrame 的 MapFromSkeletonPoint,要么将原始短值右移 DepthImageFrame.PlayerIndexBitmaskWidth。
例如骨架
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!
}
}
例如换档
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!
}
下面的原始解决方案不再正确:
基于本文的内容 - http://openkinect.org/wiki/Imaging_Information:
if (depthValue <= 2047) {
depthM = 0.1236 * Math.Tan(depthValue / 2842.5 + 1.1863);
}
旧的不活跃问题,但无论如何这对我有用我有一个旧的 kinect 模型(1414 用于 XBOX360 + PC 减少),最近有时间做一些代码和测量:
我的原始数据是 16 位而不是 10/11/12/13 位!!!
所以可能你的数据非常相似。测量的最小距离是~0.95m
未知的最大距离(没有足够大的区域进行测试),最小有效值6408 ... ~0.95m
来自传感器。另一个有效值15800 ... ~2.5m
来自用于插值的传感器
朴素(线性)转换为米
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
当我有更多时间时,我会检查线性度并使其更精确
为此,我需要进行一些编程以进行更好的测量并设置工作区域以进行更精确的距离测量。如果需要,更精确的常数可能会添加余弦校正。我不知道设备/驱动程序是否自己制作或不必测量它。当我到达它时会更新我的答案,但我很懒,所以可能需要一段时间......
[编辑 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);
raw
数据已经由驱动程序或kinect本身进行余弦校正,因此raw
表示与传感器的垂直距离。raw
数据与垂直距离呈线性关系(至少在 0.8 - 2.0 m 范围内),经过更精确的测量,深度范围为<0.8 - 4.0> [m]
. 之前的测量是不准确的。
raw = 0
is too close 值
raw >= 32768
太远/未知值甚至是别的东西(有更多的可能性)