1. 程式人生 > >windows下用kinect V2 識別人體骨骼

windows下用kinect V2 識別人體骨骼

配置環境:windows10+vs2015+opencv3.0
首先到windows官網下載kinect for windows sdk ,我用的是2.0版本,下載後安裝即可。安裝完成後,將Kinect V2連線到電腦USB3.0的口,我的電腦是左手邊最下面的那個,然後開啟裝置管理器,檢視kinect是否連線正常,如下圖所示即為連線正常,如果有感嘆號,就把這個驅動刪了,然後拔掉Kinect,再連線到電腦上,電腦會再次自動安裝驅動,如果還不行,就重啟一下。
這裡寫圖片描述
裝好驅動後,開啟剛剛安裝好的SDK Browser(Kinect for windows)v2.0軟體,找到如下圖所示的選項,我只測試了其中有Run按鍵的幾個,這幾個點選Run之後,會出現一個黑色的視窗,這時候不要以為是壞的,當你在kinect攝像頭前面動的時候,它才會顯示東西,並且只顯示人體骨骼。
這裡寫圖片描述


現在我們算是把整個kinect都安裝好了,接下來就配置系統了。
首先是安裝好opencv,官網上下載解壓即可,還有vs2015也是到windows官網下載安裝,網上相應的安裝教程特別多,找一下就好。
接下來是把opencv和kinect sdk for windows配置到vs2015裡面。
1.新建環境變數,變數名:OPENCV,變數值:D:…\opencv\build,要修改為你自己的opencv安裝路徑,然後再環境變數Path裡面,輸入D:…\opencv\build\x86\vc12\bin,也是相應的你的opencv的安裝路徑。
2.開啟vs2015,新建一個C++專案,然後在【解決方案資源管理器】中右鍵專案名,選擇【屬性】,在【C/C++】的【常規】裡,【附加包含目錄】中加入
(
KINECTSDK20DIR)\inc
(KINECTSDK20_DIR)\Lib\x86】,在【連結器】的【輸入】裡,【附加依賴項】中加入【kinect20.lib】
上面做完之後應該就可以編譯運行了,但是我發現寫程式碼時不會對【Kinect.h】中出現的函式這些進行自動補全,而且語法檢查時提示【Kinect.h】找不到,如果你也出現此問題,那就在【解決方案資源管理器】中的【標頭檔案】這裡右鍵新增【Kinect.h】,它位於【C:\Program Files\Microsoft SDKs\Kinect\v2.0_1409\inc】中。
參考於:http://www.cnblogs.com/xz816111/p/5184273.html

3.配置opencv,可參考這篇文章:http://blog.csdn.net/lanergaming/article/details/48689841
最後,也是我們最終的目的,識別人體骨骼,程式碼如下(宣告:程式碼是我借鑑的複製的別人的,連結在後面):

#include <iostream>
#include <opencv2\imgproc.hpp>  //opencv標頭檔案
#include <opencv2\calib3d.hpp>
#include <opencv2\highgui.hpp>
#include <Kinect.h> //Kinect標頭檔案

using   namespace   std;
using   namespace   cv;

void    draw(Mat & img, Joint & r_1, Joint & r_2, ICoordinateMapper * myMapper);
int main(void)
{
    IKinectSensor   * mySensor = nullptr;
    GetDefaultKinectSensor(&mySensor);
    mySensor->Open();

    IColorFrameSource   * myColorSource = nullptr;
    mySensor->get_ColorFrameSource(&myColorSource);

    IColorFrameReader   * myColorReader = nullptr;
    myColorSource->OpenReader(&myColorReader);

    int colorHeight = 0, colorWidth = 0;
    IFrameDescription   * myDescription = nullptr;
    myColorSource->get_FrameDescription(&myDescription);
    myDescription->get_Height(&colorHeight);
    myDescription->get_Width(&colorWidth);

    IColorFrame * myColorFrame = nullptr;
    Mat original(colorHeight, colorWidth, CV_8UC4);

    //**********************以上為ColorFrame的讀取前準備**************************

    IBodyFrameSource    * myBodySource = nullptr;
    mySensor->get_BodyFrameSource(&myBodySource);

    IBodyFrameReader    * myBodyReader = nullptr;
    myBodySource->OpenReader(&myBodyReader);

    int myBodyCount = 0;
    myBodySource->get_BodyCount(&myBodyCount);

    IBodyFrame  * myBodyFrame = nullptr;

    ICoordinateMapper   * myMapper = nullptr;
    mySensor->get_CoordinateMapper(&myMapper);

    //**********************以上為BodyFrame以及Mapper的準備***********************
    while (1)
    {

        while (myColorReader->AcquireLatestFrame(&myColorFrame) != S_OK);
        myColorFrame->CopyConvertedFrameDataToArray(colorHeight * colorWidth * 4, original.data, ColorImageFormat_Bgra);
        Mat copy = original.clone();        //讀取彩色影象並輸出到矩陣

        while (myBodyReader->AcquireLatestFrame(&myBodyFrame) != S_OK); //讀取身體影象
        IBody   **  myBodyArr = new IBody *[myBodyCount];       //為存身體資料的陣列做準備
        for (int i = 0; i < myBodyCount; i++)
            myBodyArr[i] = nullptr;

        if (myBodyFrame->GetAndRefreshBodyData(myBodyCount, myBodyArr) == S_OK)     //把身體資料輸入陣列
            for (int i = 0; i < myBodyCount; i++)
            {
                BOOLEAN     result = false;
                if (myBodyArr[i]->get_IsTracked(&result) == S_OK && result) //先判斷是否偵測到
                {
                    Joint   myJointArr[JointType_Count];
                    if (myBodyArr[i]->GetJoints(JointType_Count, myJointArr) == S_OK)   //如果偵測到就把關節資料輸入到陣列並畫圖
                    {
                        draw(copy, myJointArr[JointType_Head], myJointArr[JointType_Neck], myMapper);
                        draw(copy, myJointArr[JointType_Neck], myJointArr[JointType_SpineShoulder], myMapper);

                        draw(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_ShoulderLeft], myMapper);
                        draw(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_SpineMid], myMapper);
                        draw(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_ShoulderRight], myMapper);

                        draw(copy, myJointArr[JointType_ShoulderLeft], myJointArr[JointType_ElbowLeft], myMapper);
                        draw(copy, myJointArr[JointType_SpineMid], myJointArr[JointType_SpineBase], myMapper);
                        draw(copy, myJointArr[JointType_ShoulderRight], myJointArr[JointType_ElbowRight], myMapper);

                        draw(copy, myJointArr[JointType_ElbowLeft], myJointArr[JointType_WristLeft], myMapper);
                        draw(copy, myJointArr[JointType_SpineBase], myJointArr[JointType_HipLeft], myMapper);
                        draw(copy, myJointArr[JointType_SpineBase], myJointArr[JointType_HipRight], myMapper);
                        draw(copy, myJointArr[JointType_ElbowRight], myJointArr[JointType_WristRight], myMapper);

                        draw(copy, myJointArr[JointType_WristLeft], myJointArr[JointType_ThumbLeft], myMapper);
                        draw(copy, myJointArr[JointType_WristLeft], myJointArr[JointType_HandLeft], myMapper);
                        draw(copy, myJointArr[JointType_HipLeft], myJointArr[JointType_KneeLeft], myMapper);
                        draw(copy, myJointArr[JointType_HipRight], myJointArr[JointType_KneeRight], myMapper);
                        draw(copy, myJointArr[JointType_WristRight], myJointArr[JointType_ThumbRight], myMapper);
                        draw(copy, myJointArr[JointType_WristRight], myJointArr[JointType_HandRight], myMapper);

                        draw(copy, myJointArr[JointType_HandLeft], myJointArr[JointType_HandTipLeft], myMapper);
                        draw(copy, myJointArr[JointType_KneeLeft], myJointArr[JointType_FootLeft], myMapper);
                        draw(copy, myJointArr[JointType_KneeRight], myJointArr[JointType_FootRight], myMapper);
                        draw(copy, myJointArr[JointType_HandRight], myJointArr[JointType_HandTipRight], myMapper);
                    }
                }
            }
        delete[]myBodyArr;
        myBodyFrame->Release();
        myColorFrame->Release();

        imshow("TEST", copy);
        if (waitKey(30) == VK_ESCAPE)
            break;
    }
    myMapper->Release();

    myDescription->Release();
    myColorReader->Release();
    myColorSource->Release();

    myBodyReader->Release();
    myBodySource->Release();
    mySensor->Close();
    mySensor->Release();

    return  0;
}

void    draw(Mat & img, Joint & r_1, Joint & r_2, ICoordinateMapper * myMapper)
{
    //用兩個關節點來做線段的兩端,並且進行狀態過濾
    if (r_1.TrackingState == TrackingState_Tracked && r_2.TrackingState == TrackingState_Tracked)
    {
        ColorSpacePoint t_point;    //要把關節點用的攝像機座標下的點轉換成彩色空間的點
        Point   p_1, p_2;
        myMapper->MapCameraPointToColorSpace(r_1.Position, &t_point);
        p_1.x = t_point.X;
        p_1.y = t_point.Y;
        myMapper->MapCameraPointToColorSpace(r_2.Position, &t_point);
        p_2.x = t_point.X;
        p_2.y = t_point.Y;

        line(img, p_1, p_2, Vec3b(0, 255, 0), 5);
        circle(img, p_1, 10, Vec3b(255, 0, 0), -1);
        circle(img, p_2, 10, Vec3b(255, 0, 0), -1);
    }
}