Мне нужно узнать переднюю часть сундука для любого человека, использующего Kinect, находясь напротив камеры. Мое текущее решение:
-
Когда приходит MultiFrameSource, вы получаете цвет (чтобы отобразить тело в ui) (чтобы получить суставы) и кадры bodyIndex.
-
скопируйте BodyIndexFrame в байт [] _bodyData, используя:
bodyIndexFrame.CopyFrameDataToArray(_bodyData);
-
Я получаю объекты Joint для: spineShoulder и spineMid. Я предположил, что сундук всегда будет между этими точками.
-
Я конвертирую оба соединения в CameraSpacePoint (x, y, z) и из CameraSpacePoint в DepthSpacePoint (x, y) с помощью
_sensor.CoordinateMapper.MapCameraPointToDepthSpace(jointPosition);
Я все еще сохраняю ссылку на значение z spineShoulder.
-
Второе предположение = > Начиная с spineShoulderY до spineMidY Я пытаюсь найти самую широкую точку, которая находится в области игрока. для этого я попытаюсь найти самый длинный сегмент между spineShoulderX и найденным первым левым регионом, который не принадлежит игроку, и самый длинный сегмент между spineShoulderX и первым правым участком, найденным, который не принадлежит игроку. Оба найденных 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.
-
Я создаю 2 объекта 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;
Однако это, похоже, не возвращает правильные значения. Я искал решение для этого в течение недель, но я, кажется, застрял.