Kinect使用(二)——Kinect获取深度图RGB-D

新建C++项目,打开属性

找到VC++目录

  • 包含目录下添加:C:\Program Files\Microsoft SDKs\Kinect\v1.7\inc  
  • 库目录下添加:C:\Program Files\Microsoft SDKs\Kinect\v1.7\lib\x86

找到 链接器->输入

  • 附加依赖项 里添加:Kinect10.lib

新建CPP文件并输入如下代码:

#include <windows.h>
#include <iostream> 
#include <NuiApi.h>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(int argc, char *argv[])
{
    Mat image;
    //这里我们用灰度图来表述深度数据,越远的数据越暗。
    image.create(240, 320, CV_8UC1);

    //1、初始化NUI,注意:这里传入的参数就不一样了,是DEPTH
    HRESULT hr = NuiInitialize(NUI_INITIALIZE_FLAG_USES_DEPTH);
    if (FAILED(hr))
    {
        cout << "NuiInitialize failed" << endl;
        return hr;
    }

    //2、定义事件句柄 
    //创建读取下一帧的信号事件句柄,控制KINECT是否可以开始读取下一帧数据
    HANDLE nextColorFrameEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    HANDLE depthStreamHandle = NULL; //保存图像数据流的句柄,用以提取数据 

                                     //3、打开KINECT设备的深度图信息通道,并用depthStreamHandle保存该流的句柄,以便于以后读取
    hr = NuiImageStreamOpen(NUI_IMAGE_TYPE_DEPTH, NUI_IMAGE_RESOLUTION_320x240,
        0, 2, nextColorFrameEvent, &depthStreamHandle);
    if (FAILED(hr))//判断是否提取正确 
    {
        cout << "Could not open color image stream video" << endl;
        NuiShutdown();
        return hr;
    }
    namedWindow("depthImage", CV_WINDOW_AUTOSIZE);

    //4、开始读取深度数据 
    while (1)
    {
        const NUI_IMAGE_FRAME * pImageFrame = NULL;

        //4.1、无限等待新的数据,等到后返回
        if (WaitForSingleObject(nextColorFrameEvent, INFINITE) == 0)
        {
            //4.2、从刚才打开数据流的流句柄中得到该帧数据,读取到的数据地址存于pImageFrame
            hr = NuiImageStreamGetNextFrame(depthStreamHandle, 0, &pImageFrame);
            if (FAILED(hr))
            {
                cout << "Could not get depth image" << endl;
                NuiShutdown();
                return -1;
            }

            INuiFrameTexture * pTexture = pImageFrame->pFrameTexture;
            NUI_LOCKED_RECT LockedRect;

            //4.3、提取数据帧到LockedRect,它包括两个数据对象:pitch每行字节数,pBits第一个字节地址
            //并锁定数据,这样当我们读数据的时候,kinect就不会去修改它
            pTexture->LockRect(0, &LockedRect, NULL, 0);
            //4.4、确认获得的数据是否有效

            if (LockedRect.Pitch != 0)
            {
                //4.5、将数据转换为OpenCV的Mat格式
                for (int i = 0; i<image.rows; i++)
                {
                    uchar *ptr = image.ptr<uchar>(i);  //第i行的指针

                                                       //深度图像数据含有两种格式,这里像素的低12位表示一个深度值,高4位未使用;
                                                       //注意这里需要转换,因为每个数据是2个字节,存储的同上面的颜色信息不一样,
                    uchar *pBufferRun = (uchar*)(LockedRect.pBits) + i * LockedRect.Pitch;
                    USHORT * pBuffer = (USHORT*)pBufferRun;

                    for (int j = 0; j<image.cols; j++)
                    {

                        ptr[j] = 255 - (uchar)(256 * pBuffer[j] / 0x0fff);  //直接将数据归一化处理
                    }
                }
                //cout << "均值: " << (sum/a++) << endl;
                imshow("depthImage", image); //显示图像 

            }
            else
            {
                cout << "Buffer length of received texture is bogus\r\n" << endl;
            }

            //5、这帧已经处理完了,所以将其解锁
            pTexture->UnlockRect(0);

            //6、释放本帧数据,准备迎接下一帧 

            NuiImageStreamReleaseFrame(depthStreamHandle, pImageFrame);
        }
        if (cvWaitKey(20) == 27)
            break;
    }
    //7、关闭NUI链接 
    NuiShutdown();
    return 0;
}

运行结果:

欢迎关注我的公众号:

编程技术与生活(ID:hw_cchang)

 

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cchangcs

谢谢你的支持~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值