Подтвердить что ты не робот

Найти размер груди с помощью Kinect v2

Мне нужно узнать переднюю часть сундука для любого человека, использующего 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.

  1. Второе предположение = > Начиная с 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;
    
    }
    
  2. findElement вернет объект BodyMember, который содержит farLeftX, farRightX, farLeftY и farRightY.

  3. Я создаю 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();
    
  4. Чтобы получить координаты реального мира в метрах, эти точки должны быть преобразованы в объект CameraSpacePoint. Для этого я использую совместное значение z, которое я сохранил ссылку назад в точке 4.

    CameraSpacePoint chestLeft = _sensor.CoordinateMapper.MapDepthPointToCameraSpace(chestX1,spineShoulderZ);
    CameraSpacePoint chestRight = _sensor.CoordinateMapper.MapDepthPointToCameraSpace(chestX1,spineShoulderZ);
    
  5. Теперь Если мой код и предположения верны, я должен иметь возможность получить правильное расстояние в метрах для переднего сундука.

    double chestLength = (chestLeft.X > chestRight.X) ? chestLeft - chestRight : chestRight - chestLeft;
    

Однако это, похоже, не возвращает правильные значения. Я искал решение для этого в течение недель, но я, кажется, застрял.

4b9b3361

Ответ 1

Я работал с Kinect V2 и могу сказать, что только данные скелета дикие, чтобы получить надежные результаты. Даже одежда влияет на то, как Kinect интерпретирует части тела, поэтому вам придется комбинировать результаты с данными других датчиков.

Кроме того, я предлагаю вам проявить творческий подход к этому, например, вы можете исследовать некоторые возможные анатомические корреляции в отношении человеческого тела, скорее всего, высота является индикатором прокси, может быть, возраст от распознавания лица, а высота - еще один намек и т.д.

Ответ 2

Используете ли вы kinect One? Измерения в старых kinects, вероятно, недостаточно точны, чтобы соответствовать вашим требованиям.

Однако, с моей точки зрения, также стоит сделать извлечение движущегося объекта внутри фреймов (если есть только один человек перед Kinect, вы получите этот контур лица, но убедитесь, что вы можете сравните его положение с каркасом Kinect).

Вы можете сказать человеку, чтобы он поднял руки на короткий промежуток времени. Затем используйте расстояние Kinect до скелета лиц и в зависимости от размера контура и заданного расстояния. Вычислите конечное измерение груди чуть ниже плеч (позиция взята из скелета). Я также не совсем понимаю, насколько точно Kinect обрабатывает "более крупных" людей.

Ниже описан один из методов: http://onlinelibrary.wiley.com/doi/10.1002/scj.10237/abstract Вы также можете использовать много других документов с данным предметом (бесплатно).

Что вы думаете об этой идее? Приветствия