KINECT SDK C++彩色与深度图像获取(结合OpenCV2.4.4)

来源:互联网 发布:淘宝一千零一夜怎么看 编辑:程序博客网 时间:2024/06/05 16:47
//最远距离(mm)const int MAX_DISTANCE = 3500;//最近距离(mm)const int MIN_DISTANCE = 300;int main(){//彩色图像Mat image_rgb;//深度图像Mat image_depth;//创建一个MATimage_rgb.create(480,640,CV_8UC3);image_depth.create(240,320,CV_8UC1);//一个KINECT实例指针INuiSensor* m_pNuiSensor = NULL;if (m_pNuiSensor != NULL){return 0;}//记录当前连接KINECT的数量(为多连接做准备)int iSensorCount;//获得当前KINECT的数量HRESULT hr = NuiGetSensorCount(&iSensorCount);//cout << iSensorCount << endl;//按照序列初始化KINETC实例,这里就连接了一个KINECT,所以没有用到循环hr = NuiCreateSensorByIndex(iSensorCount - 1, &m_pNuiSensor);//初始化,让其可以接收彩色和深度数据流hr = m_pNuiSensor->NuiInitialize(NUI_INITIALIZE_FLAG_USES_COLOR | NUI_INITIALIZE_FLAG_USES_DEPTH);//判断是否出错if (FAILED(hr)){cout<<"NuiInitialize failed"<NuiImageStreamOpen(NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, 0,2,nextColorFrameEvent,&colorStreamHandle);if( FAILED( hr ) )//判断是否提取正确{cout<<"Could not open color image stream video"<NuiShutdown();return hr;}//实例打开数据流,这里NUI_IMAGE_TYPE_DEPTH表示深度图像hr = m_pNuiSensor->NuiImageStreamOpen(NUI_IMAGE_TYPE_DEPTH, NUI_IMAGE_RESOLUTION_320x240, 0,2, nextDepthFrameEvent, &depthStreamHandle);if( FAILED( hr ) )//判断是否提取正确{cout<<"Could not open color image stream video"<NuiShutdown();return hr;}cv::namedWindow("depth", CV_WINDOW_AUTOSIZE);moveWindow("depth",300,600);cv::namedWindow("colorImage",CV_WINDOW_AUTOSIZE);moveWindow("colorImage",0,200);while (1){NUI_IMAGE_FRAME pImageFrame_rgb;NUI_IMAGE_FRAME pImageFrame_depth;//无限等待新的彩色数据,等到后返回if (WaitForSingleObject(nextColorFrameEvent, 0) == 0){//从刚才打开数据流的流句柄中得到该帧数据,读取到的数据地址存于pImageFramehr = m_pNuiSensor->NuiImageStreamGetNextFrame(colorStreamHandle, 0, &pImageFrame_rgb);if (FAILED(hr)){cout<<"Could not get color image"<NuiShutdown();return -1;}INuiFrameTexture *pTexture = pImageFrame_rgb.pFrameTexture;NUI_LOCKED_RECT lockedRect;//提取数据帧到LockedRect,它包括两个数据对象:pitch每行字节数,pBits第一个字节地址//并锁定数据,这样当我们读数据的时候,kinect就不会去修改它pTexture->LockRect(0, &lockedRect, NULL, 0);//确认获得的数据是否有效if (lockedRect.Pitch != 0){//将数据转换为OpenCV的Mat格式for (int i = 0; i < image_rgb.rows; i++){//第i行的指针uchar *prt = image_rgb.ptr(i);//每个字节代表一个颜色信息,直接使用ucharuchar *pBuffer = (uchar*)(lockedRect.pBits) + i * lockedRect.Pitch;for (int j = 0; j < image_rgb.cols; j++){prt[3 * j] = pBuffer[4 * j];//内部数据是4个字节,0-1-2是BGR,第4个现在未使用prt[3 * j + 1] = pBuffer[4 * j + 1];prt[3 * j + 2] = pBuffer[4 * j + 2];}}imshow("colorImage",image_rgb);//解除锁定pTexture->UnlockRect(0);//释放帧m_pNuiSensor->NuiImageStreamReleaseFrame(colorStreamHandle, &pImageFrame_rgb );}else{cout<<"Buffer length of received texture is bogus\r\n"<NuiImageStreamGetNextFrame(depthStreamHandle, 0 , &pImageFrame_depth);if (FAILED(hr)){cout<<"Could not get color image"<LockRect(0, &lockedRect, NULL, 0);//归一化for (int i = 0; i < image_depth.rows; i++){uchar *prt = image_depth.ptr(i);uchar* pBuffer = (uchar*)(lockedRect.pBits) + i * lockedRect.Pitch;//这里需要转换,因为每个深度数据是2个字节,应将BYTE转成USHORTUSHORT *pBufferRun = (USHORT*)pBuffer;for (int j = 0; j < image_depth.cols; j++){//先向,将数据归一化处理,对深度距离在300mm-3500mm范围内的像素,映射到【0—255】内,//超出范围的,都去做是边缘像素if (pBufferRun[j] << 3 > MAX_DISTANCE) prt[j] = 255;else if(pBufferRun[j] << 3 < MIN_DISTANCE) prt[j] = 0;else prt[j] = (BYTE)(256 * (pBufferRun[j] << 3)/ MAX_DISTANCE);}}imshow("depth", image_depth);pTexture->UnlockRect(0);m_pNuiSensor->NuiImageStreamReleaseFrame(depthStreamHandle, &pImageFrame_depth); }else{cout<<"Buffer length of received texture is bogus\r\n"<<endl;}}if (cvWaitKey(20) == 27)break;}return 0;}
0 1