使用Kinect v2查找胸部大小
本文关键字:胸部 查找 Kinect v2 使用 | 更新日期: 2024-10-18 23:50:31
我需要找出任何一个在面对相机时使用Kinect的人的胸部正面尺寸。我目前的解决方案是:
-
当MultiFrameSource到达时,获取颜色(在ui中显示主体)body(获取关节)和bodyIndex框架。
-
使用将BodyIndexFrame复制到byte[]_bodyData
bodyIndexFrame.CopyFrameDataToArray(_bodyData);
-
我得到了以下对象的关节:spineShoulder和spineMid我假设胸部总是在这些点之间。
-
我使用将两个关节转换为CameraSpacePoint(x,y,z),并将CameraSpacePoint转换为DepthSpacePoint(x,y)
_sensor.CoordinateMapper.MapCameraPointToDepthSpace(jointPosition);
我仍然引用spineShoulder的z值。
-
第二个假设=>从spineSshoulderY到spineMidY,我试图找到玩家区域中最宽的点。为了做到这一点,我将尝试找到spineShoulderX和找到的不属于玩家的第一个左侧区域之间的最长片段,以及SpineShowderX和发现的不属于该玩家的第一右侧区域之间的最大片段。找到的两个x线段必须位于同一个y坐标中
/*************** * Returns the distance between 2 points */ private static int getDistanceToMid(int pointX, int midX) { if (midX > pointX) { return (midX - pointX); } else if (pointX > midX) { return (pointX - midX); } else { return 0; } } /********* * Loops through the bodyData array * It will look for the longest x distance from midX to the last left x value * which still belongs to a player in the y coordinate */ private static int findFarLeftX(byte[] bodyData,int depthWidth, int midX, int y) { int farLeftX = -1; for (int x = midX; x >= 0; --x) { int depthIndex = (y * depthWidth) + x; if (depthIndex > 0 && depthIndex < bodyData.Length) { byte player = bodyData[depthIndex]; if (player != 0xff){ if (farLeftX == -1 || farLeftX > x) { farLeftX = x; } } else{ return farLeftX; } } } return farLeftX; } /********* * Loops through the bodyData array * It will look for the longest x distance from midX to the last right x value * which still belongs to a player in the y coordinate */ private static int findFarRightX(byte[] bodyData, int depthWidth, int midX, int y) { int farRightX = -1; for (int x = midX; x < depthWidth; ++x) { int depthIndex = (y * depthWidth) + x; if (depthIndex > 0 && depthIndex < bodyData.Length) { byte player = bodyData[depthIndex]; if (player != 0xff) { if (farRightX == -1 || farRightX < x) { farRightX = x; } else{ return farRightX; } } } } return farRightX; } private static BodyMember findElement(byte[] bodyData, int depthHeight, int depthWidth, int startX, int startY, int endY) { BodyMember member = new BodyMember(-1, -1, -1, -1); int totalMaxSum = 0; int farLeftX = -1; int farRightX = -1; int selectedY = -1; for (int y = startY; y < depthHeight && y <= endY; ++y) { int leftX = findFarLeftX(bodyData, depthWidth, startX, y); int rightX = findFarRightX(bodyData, depthWidth, startX, y); if (leftX > -1 && rightX > -1) { int leftToMid = getDistanceToMid(leftX, startX); int rightToMid = getDistanceToMid(rightX, startX); int sum = leftToMid + rightToMid; if (sum > totalMaxSum) { totalMaxSum = sum; farLeftX = leftX; farRightX = rightX; selectedY = y; } } } member.setFarLeftX(farLeftX); member.setFarLeftY(selectedY); member.setFarRightX(farRightX); member.setFarRightY(selectedY); return member; }
-
findElement将返回一个BodyMember对象,该对象包含farLeftX、farRightX、farLeftY和farRightY。
-
我创建了两个DepthSpacePoint对象:DepthSpacePoint chestX1=新的DepthSpacePoint();chestX1.X=bodyMemberObj.getFarLeftX();chestX1.Y=bodyMemberObj.getFarLeftY();
DepthSpacePoint chestX2 = new DepthSpacePoint(); chestX2.X = bodyMemberObj.getFarRightX(); chestX2.Y = bodyMemberObj.getFarRightY();
-
为了获得以米为单位的真实世界坐标,必须将这些点转换为CameraSpacePoint对象。为了做到这一点,我将使用关节的z值,我在第4点保留了它的参考。
CameraSpacePoint chestLeft = _sensor.CoordinateMapper.MapDepthPointToCameraSpace(chestX1,spineShoulderZ); CameraSpacePoint chestRight = _sensor.CoordinateMapper.MapDepthPointToCameraSpace(chestX1,spineShoulderZ);
-
现在,如果我的代码和假设是正确的我应该能够获得前胸的正确距离(以米为单位)。
double chestLength = (chestLeft.X > chestRight.X) ? chestLeft - chestRight : chestRight - chestLeft;
然而,这似乎并没有返回正确的值。几周来,我一直在寻找解决方案,但我似乎陷入了困境。
我使用过Kinect V2,可以说,仅凭骨骼数据不足以获得可靠的结果。即使是衣服也会影响Kinect对身体部位的解释,所以你必须结合其他传感器数据的结果。
此外,我建议你在处理这件事时要有创造性,例如,你可以研究一些可能的人体解剖学相关性,很可能身高是一个代理指标,可能人脸识别的年龄和身高是另一个提示,等等。
您正在使用kinect One吗?旧运动学中的测量可能不够准确,无法满足您的要求。
然而,从我的角度来看,提取帧内的移动对象也是值得的(如果Kinect前面只有一个人,你会收到这个人的轮廓,但要确保你可以将其位置与Kinect骨架进行比较)。
你们可以告诉人们在短时间内举手。然后使用Kinect到人骨架的距离,并根据轮廓的大小和给定的距离,计算肩膀下方的最终胸部测量值(从骨架上取下的位置)。我也不完全清楚Kinect处理"大"人物的准确度。
下面介绍其中一种方法:http://onlinelibrary.wiley.com/doi/10.1002/scj.10237/abstract你也可以在谷歌上搜索许多其他主题的论文(免费)。
你觉得这个主意怎么样?干杯