最近在做基于Kinect的手势识别,这里介绍一下Kinect的使用

1.Kinect在Qt中的安装

下载Kinect的安装包,按照流程按照即可。

pro文件中需要填写opencv以及kinect的头文件以及库文件路径,我把它们都放在工程目录下了,如下代码所示。

#openCV路径
INCLUDEPATH += $$PWD/opencv/build/include\
               $$PWD/opencv/build/include/opencv\
               $$PWD/opencv/build/include/opencv2\
               $$PWD/inc\
 
LIBS += $$PWD/Lib/x64/Kinect20.lib
 
CONFIG(debug, debug|release): {
LIBS += -L$$PWD/opencv/build/x64/vc14/lib \
-lopencv_world342d \
} else:CONFIG(release, debug|release): {
LIBS += -L$$PWD/opencv/build/x64/vc14/lib \
-lopencv_world342 \
}

然后使用时包含头文件,即可使用。

#include "Kinect.h"
#include "Kinect.VisualGestureBuilder.h"
#include "Kinect.Face.h"
#include "Kinect.INPC.h"

2. 获取深度图像

IKinectSensor*          m_pKinectSensor;
    IDepthFrameReader*      m_pDepthFrameReader;
    IDepthFrameSource*      pDepthFrameSource = NULL;
    IFrameDescription*      depthFrameDescription = NULL;
 
    GetDefaultKinectSensor(&m_pKinectSensor);      //获取默认kinect传感器
    printf("打开kinect传感器成功\n");
    //打开传感器
    m_pKinectSensor->Open();
 
    //获得深度信息传感器
    m_pKinectSensor->get_DepthFrameSource(&pDepthFrameSource);
    //打开深度信息帧读取器
    pDepthFrameSource->OpenReader(&m_pDepthFrameReader);
 
    while (true)
    {
        IDepthFrame*       pDepthFrame = NULL;
 
        while(pDepthFrame == NULL){
            //由于有时候获取不到,因此循环获取最近的帧
            m_pDepthFrameReader->AcquireLatestFrame(&pDepthFrame);
        }
        pDepthFrame->get_FrameDescription(&depthFrameDescription);
        int depth_width, depth_height;
        //获取帧的像素信息(宽和高)
        depthFrameDescription->get_Width(&depth_width);
        depthFrameDescription->get_Height(&depth_height);
        printf("width=%d height=%d\n", depth_width, depth_height);
        UINT nBufferSize_depth = 0;
        UINT16 *pBuffer_depth = NULL;
        //获取图像像素个数和指向图像的指针
        pDepthFrame->AccessUnderlyingBuffer(&nBufferSize_depth, &pBuffer_depth);
        //转换为8位的mat
        Mat depthImg_show = ConvertMat(pBuffer_depth, depth_width, depth_height);
        //均衡化,为了提高显示效果
        equalizeHist(depthImg_show, depthImg_show);
    }

3.获取彩色图像

IKinectSensor*          m_pKinectSensor;
 
    IColorFrameSource*      pColorFrameSource;
    IColorFrameReader*      m_pColorFrameReader;
    IFrameDescription*      colorFrameDescription = NULL;
    ColorImageFormat        imageFormat = ColorImageFormat_None;
 
    GetDefaultKinectSensor(&m_pKinectSensor);      //获取默认kinect传感器
    printf("打开kinect传感器成功\n");
    //打开传感器
    m_pKinectSensor->Open();
 
    //获得彩色信息传感器
    m_pKinectSensor->get_ColorFrameSource(&pColorFrameSource);
    //打开彩色信息帧读取器
    pColorFrameSource->OpenReader(&m_pColorFrameReader);
 
    while (true)
    {
        IColorFrame*       pColorFrame = NULL;
 
        //获取彩色图像
        while(pColorFrame == NULL){
            //由于有时候获取不到,因此循环获取最近的帧
            m_pColorFrameReader->AcquireLatestFrame(&pColorFrame);
        }
        //获取图片描述信息
        pColorFrame->get_FrameDescription(&colorFrameDescription);
        int nWidth, nHeight;
        uchar *pBuffer = NULL;
        UINT nBufferSize = 0;
        colorFrameDescription->get_Width(&nWidth);
        colorFrameDescription->get_Height(&nHeight);
        cout << "width=" << nWidth << endl;
        cout << "Height=" << nHeight << endl;
        pColorFrame->get_RawColorImageFormat(&imageFormat);
        //输出结果为 ColorImageFormat_Yuy2    = 5,为Yuy2格式
        cout << "imageformat is " << imageFormat << endl;
        //新建一个mat对象,用于保存读入的图像,注意参数的高在前,宽在后
        Mat colorImg(nHeight, nWidth, CV_8UC4);
        pBuffer = colorImg.data;
        nBufferSize = colorImg.rows*colorImg.step;
        pColorFrame->CopyConvertedFrameDataToArray(nBufferSize,reinterpret_cast<BYTE*>(pBuffer), ColorImageFormat_Bgra);
    }

4.Kinect v2在python中调用


官网链接:https://github.com/Kinect/PyKinect2

功能介绍:这个版本只支持颜色、深度和人体骨骼和人体骨骼帧。其中,PyKinectBodyGame样例是一个样例游戏,它着重阐述怎么使用Kinect得当颜色和人体骨骼帧。

6.基础知识

6.1 坐标系定义

坐标系参考博客:https://blog.csdn.net/jiaojialulu/article/details/53088170

相机知识参考博客:https://blog.csdn.net/osean_li/article/details/91046166

  • 红外投影机 :发射红外线 提供深度数据
  • 彩色摄像头 :提供彩色图像
  • 红外摄像头 :接收红外线 提供深度数据

深度的量程:

物理限制:0.4米到3米

舒适区:    0.8米到2.5米

相机空间指的是kinect使用的3D空间坐标。它是这样定义的: 
- 坐标原点(x=0,y=0,z=0)位于kinect的红外相机中心。 
- X轴方向为顺着kinect的照射方向的左方向 
- Y轴方向为顺着kinect的照射方向的上方向 
- z轴方向为顺着kinect的照射方向 
- 坐标单位为米(m) 


image

PS:注意!这是一个右手坐标系,这与计算机图形学中定义的相机空间是一致的.

6.2 Kinectv2频繁重启

原因,驱动程序版本不对。解决方法:更新驱动程序(或者在如下的图片中联网自动更新,或者手动下载更新)

参考链接:https://blog.csdn.net/muchunpeng/article/details/102523465?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1.nonecase

查看自己的版本如下:通过设备管理器,右键WDF KinectSensor接口0,选择属性。

我的版本为:2.2.1905.16000    或者如网上说的(应为2.2.1811.10000)