Kinect For Windows V2开发日志六:人体的轮廓的表示

Kinect中带了一种数据源,叫做BodyIndex,简单来说就是它利用深度摄像头识别出最多6个人体,并且用数据将属于人体的部分标记,将人体和背景区别开来。利用这一特性,就可以在环境中显示出人体的轮廓而略去背景的细节。我采用了下面两种方式来实现。

用OpenCV表示

代码

#include <iostream>
#include <Kinect.h>
#include <opencv2\highgui.hpp>

using   namespace   std;
using   namespace   cv;

int main(void)
{
    IKinectSensor   * mySensor = nullptr;               //Sensor
    GetDefaultKinectSensor(&mySensor);
    mySensor->Open();

    IBodyIndexFrameSource   * mySource = nullptr;       //Source
    mySensor->get_BodyIndexFrameSource(&mySource);

    int height = 0, width = 0;
    IFrameDescription   * myDescription = nullptr;  
    mySource->get_FrameDescription(&myDescription);
    myDescription->get_Height(&height);
    myDescription->get_Width(&width);

    IBodyIndexFrameReader   * myReader = nullptr;       //Reader
    mySource->OpenReader(&myReader);

    IBodyIndexFrame     * myFrame = nullptr;            //Frame
    Mat img(height,width,CV_8UC3);
    Vec3b   color[7] = { Vec3b(0,0,255),Vec3b(0,255,255),Vec3b(255,255,255),Vec3b(0,255,0),Vec3b(255,0,0),Vec3b(255,0,255),Vec3b(0,0,0) };

    while (1)
    {
        if (myReader->AcquireLatestFrame(&myFrame) == S_OK)
        {
            UINT    size = 0;
            BYTE    * buffer = nullptr;
            myFrame->AccessUnderlyingBuffer(&size,&buffer);
            for (int i = 0; i < height; i++)
                for (int j = 0; j < width; j++)
                {
                    int index = buffer[i * width + j];      //0-5代表人体,其它值代表背景,用此将人体和背景渲染成不同颜色
                    if (index <= 5)
                        img.at<Vec3b>(i, j) = color[index];
                    else
                        img.at<Vec3b>(i, j) = color[6];

                }
            imshow("TEST",img);
            myFrame->Release();
        }
        if (waitKey(30) == VK_ESCAPE)
            break;
    }
    myReader->Release();
    myDescription->Release();
    mySource->Release();
    mySensor->Close();
    mySensor->Release();

    return  0;
}

详细说明

步骤和前面相似,不再赘述,关键在于对数据的处理。IBodyIndexFrame里的数据分两种,值在0-5之间的点代表的是人体(因此最多识别出6个人),大于5的值代表的是背景。所以要显示人体时,只要简单的把代表人体的点渲染成一种颜色,背景渲染成另外一种颜色就可以了。值得注意的是在写颜色表color时,要用Vec3b把数据强转一下,不然会有问题。

最终的效果就是这样:
Kinect For Windows V2开发日志六:人体的轮廓的表示_第1张图片

直接用数据勾画出人体

代码:

#include <iostream>
#include <Kinect.h>
#include <Windows.h>

using   namespace   std;
using   namespace   cv;

int main(void)
{
    IKinectSensor   * mySensor = nullptr;           //Sensor
    GetDefaultKinectSensor(&mySensor);
    mySensor->Open();

    IBodyIndexFrameSource   * mySource = nullptr;       //Source
    mySensor->get_BodyIndexFrameSource(&mySource);

    int height = 0, width = 0;
    IFrameDescription   * myDescription = nullptr;  
    mySource->get_FrameDescription(&myDescription);
    myDescription->get_Height(&height);
    myDescription->get_Width(&width);

    IBodyIndexFrameReader   * myReader = nullptr;       //Reader
    mySource->OpenReader(&myReader);

    IBodyIndexFrame     * myFrame = nullptr;            //Frame
    while (1)
    {
        Sleep(1000);
        if (myReader->AcquireLatestFrame(&myFrame) == S_OK)
        {
            UINT    size = 0;
            BYTE    * buffer = nullptr;
            myFrame->AccessUnderlyingBuffer(&size,&buffer);
            for (int i = 50; i < 350; i++)          //调出一个合适的尺寸
            {
                for (int j = 0; j < width; j++)
                {
                    int index = buffer[i * width + j];
                    if (index <= 5)
                        cout << 0;
                    else
                        cout << 1;
                }
                cout << endl;
            }
            cout << endl << endl;
            myFrame->Release();
        }
    }
    myReader->Release();
    myDescription->Release();
    mySource->Release();
    mySensor->Close();
    mySensor->Release();

    return  0;
}

说明

实际上,因为有可以用数字来区别人体和背景这一特性,所以甚至可以不用openCV,直接用数据来显示人体。将识别为人体的数据作为0输出,背景作为1输出,同时把控制台的窗口调大一些,字体调到最小,每秒钟输出一帧,就能直接看到数据画出的图。真是有趣。

效果如下:
Kinect For Windows V2开发日志六:人体的轮廓的表示_第2张图片




你可能感兴趣的:(Kinect For Windows V2开发日志六:人体的轮廓的表示)