kinect2.0+opencv获取图像和深度图像



参考这篇博客的程序,http://blog.csdn.net/yongshengsilingsa/article/details/37935975

//师兄写的获取深度信息的程序,并且将深度信息存储为txt格式

/*#include <iostream>
#include <Kinect.h>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;

string getname(int num, UINT size, int height, int width,int minds,int maxds)
{
 ostringstream os;
 os << num << "_SHWminHmaxH_"
  << size << "_"
  << height << "_"
  << width << "_"
  << minds << "_"
  << maxds << ".txt";
 return os.str();
}
void writedata(string path, UINT16* buff, UINT size)
{
 ofstream fout;
 fout.open(path, ios::binary);
 if (!fout.is_open())
 {
  cout << "Open file fail ->" << path;
  return;
 }
 fout.write((char*)buff, size*sizeof(UINT16)/sizeof(char));
 fout.close();
}

void printBuffer(UINT16* buff, UINT size)
{
 for (int i = 0; i < 1000; i++)
 {
  cout << i << " " << int(buff[i]) << endl;
 }
}


int main()
{
 IKinectSensor* bb;  //设备指针
 HRESULT hr = GetDefaultKinectSensor(&bb); //获得设备
 if (FAILED(hr))
 {
  cout << "No Kinect connect" << endl;
  return 0;
 }
 BOOLEAN bIsOpen = 0;
 bb->get_IsOpen(&bIsOpen);

 if (!bIsOpen)
 {
  hr = bb->Open();
  if (FAILED(hr))
  {
   cout << "No Kinect connect" << endl;
   return 0;
  }
  cout << "wait 3000ms " << endl;
  Sleep(3000);
 }
 bIsOpen = 0;
 bb->get_IsOpen(&bIsOpen); // 是否已经打开
 if (!bIsOpen)
 {
  cout << "Open Kinect fail" << endl;
  return 0;
 }
 DWORD dwCapability = 0;
 bb->get_KinectCapabilities(&dwCapability); // 获取容量
 cout << "dwCapability: " << dwCapability << endl;

 TCHAR bbuid[256] = { 0 };
 bb->get_UniqueKinectId(256, bbuid); // 获取唯一ID
 cout << "UID: " << bbuid << endl;

 //深度信息
 IDepthFrameSource * depths = nullptr;
 hr = bb->get_DepthFrameSource(&depths);
 if (FAILED(hr))
 {
  cout << "Open DepthFrame fail" << endl;
  bb->Close();
  return 0;
 }
 IDepthFrameReader * depthr = nullptr;
 depths->OpenReader(&depthr); // 打开深度解析器 

 //读取深度数据
 int snum = 1;
 while (true)
 {
  IDepthFrame* depthf = nullptr;
  depthr->AcquireLatestFrame(&depthf); // 获取最近的深度数据

  if (!depthf)
  {
   Sleep(200);
   continue;
  }
  USHORT minds, maxds;
  depthf->get_DepthMinReliableDistance(&minds); // 获取最近的有效距离,500
  depthf->get_DepthMaxReliableDistance(&maxds); // 获取最远的有效距离,4500
  cout << "Depth min: " << minds << " ,max: " << maxds << endl;
  IFrameDescription* frameDs = nullptr;
  depthf->get_FrameDescription(&frameDs); // 获取深度信息的属性
  int height, width;
  frameDs->get_Height(&height);
  frameDs->get_Width(&width);
  cout << "Depth height: " << height << " ,width: " << width << endl;
  
  UINT ncaps = 0;
  UINT16* buff = nullptr;
  depthf->AccessUnderlyingBuffer(&ncaps, &buff); // 获取深度数据的指针和大小
  //depthf->CopyFrameDataToArray(...); // 讲深度数据Copy到制定的buffer中
  cout << "Buffer size: " << ncaps << endl;
  printBuffer(buff, ncaps);
  writedata(getname(snum, ncaps,height, width, minds, maxds), buff, ncaps);

  depthf->Release();
  frameDs->Release();
  Sleep(200);
  if (snum++ == 1)
   break;
 }
 bb->Close();
 cout << "Enter to close" << endl;
 cin.get();
 return 0;
}*/


//博客里面的程序,头文件更改了,并且里面saferelease的写了

#include <iostream>
#include <Kinect.h>
#include <fstream>
#include <sstream>
#include <string>

//#include <config.h>
#include "stdafx.h"
#include <opencv2/opencv.hpp>
//#include "DepthBasics.h"
#include "opencv\highgui.h"


//自己添加的

template<class Interface>
inline void SafeRelease(Interface *& pInterfaceToRelease)
{
 if (pInterfaceToRelease != NULL)
 {
  pInterfaceToRelease->Release();
  pInterfaceToRelease = NULL;
 }
}

// 转换depth图像到cv::Mat
cv::Mat ConvertMat(const UINT16* pBuffer, int nWidth, int nHeight, USHORT nMinDepth, USHORT nMaxDepth)
{
 cv::Mat img(nHeight, nWidth, CV_8UC3);
 uchar* p_mat = img.data;

 const UINT16* pBufferEnd = pBuffer + (nWidth * nHeight);

 while (pBuffer < pBufferEnd)
 {
  USHORT depth = *pBuffer;

  BYTE intensity = static_cast<BYTE>((depth >= nMinDepth) && (depth <= nMaxDepth) ? (depth % 256) : 0);

  *p_mat = intensity;
  p_mat++;
  *p_mat = intensity;
  p_mat++;
  *p_mat = intensity;
  p_mat++;

  ++pBuffer;
 }
 return img;
}
// 转换color图像到cv::Mat
cv::Mat ConvertMat(const RGBQUAD* pBuffer, int nWidth, int nHeight)
{
 cv::Mat img(nHeight, nWidth, CV_8UC3);
 uchar* p_mat = img.data;

 const RGBQUAD* pBufferEnd = pBuffer + (nWidth * nHeight);

 while (pBuffer < pBufferEnd)
 {
  *p_mat = pBuffer->rgbBlue;
  p_mat++;
  *p_mat = pBuffer->rgbGreen;
  p_mat++;
  *p_mat = pBuffer->rgbRed;
  p_mat++;

  ++pBuffer;
 }
 return img;
}


void main()
{
 
 int depth_width = 512; //depth图像就是这么小
 int depth_height = 424;
 int color_widht = 1920; //color图像就是辣么大
 int color_height = 1080;

 cv::Mat depthImg_show = cv::Mat::zeros(depth_height, depth_width, CV_8UC3);//原始UINT16 深度图像不适合用来显示,所以需要砍成8位的就可以了,但是显示出来也不是非常好,最好能用原始16位图像颜色编码,凑合着看了
 cv::Mat depthImg = cv::Mat::zeros(depth_height, depth_width, CV_16UC1);//the depth image
 cv::Mat colorImg = cv::Mat::zeros(color_height, color_widht, CV_8UC3);//the color image
 // Current Kinect
 IKinectSensor* m_pKinectSensor = NULL;
 // Depth reader
 IDepthFrameReader*  m_pDepthFrameReader = NULL;
 // Color reader
 IColorFrameReader*  m_pColorFrameReader = NULL;
 RGBQUAD* m_pColorRGBX = new RGBQUAD[color_widht * color_height];
 //open it!
 HRESULT hr;

 hr = GetDefaultKinectSensor(&m_pKinectSensor);
 if (FAILED(hr))
 {
  std::cout << "FUCK! Can not find the Kinect!" << std::endl;
  cv::waitKey(0);
  exit(0);
 }

 if (m_pKinectSensor)
 {
  // Initialize the Kinect and get the depth reader
  IDepthFrameSource* pDepthFrameSource = NULL;

  hr = m_pKinectSensor->Open();

  if (SUCCEEDED(hr))
  {
   hr = m_pKinectSensor->get_DepthFrameSource(&pDepthFrameSource);
  }

  if (SUCCEEDED(hr))
  {
   hr = pDepthFrameSource->OpenReader(&m_pDepthFrameReader);
  }

  SafeRelease(pDepthFrameSource);

  // for color
  // Initialize the Kinect and get the color reader
  IColorFrameSource* pColorFrameSource = NULL;
  if (SUCCEEDED(hr))
  {
   hr = m_pKinectSensor->get_ColorFrameSource(&pColorFrameSource);
  }

  if (SUCCEEDED(hr))
  {
   hr = pColorFrameSource->OpenReader(&m_pColorFrameReader);
  }

  SafeRelease(pColorFrameSource);
 }

 //valify the depth reader
 if (!m_pDepthFrameReader)
 {
  std::cout << "FUCK! Can not find the m_pDepthFrameReader!" << std::endl;
  cv::waitKey(0);
  exit(0);
 }
 //valify the color reader
 if (!m_pDepthFrameReader)
 {
  std::cout << "FUCK! Can not find the m_pColorFrameReader!" << std::endl;
  cv::waitKey(0);
  exit(0);
 }
 // get the data!
 UINT nBufferSize_depth = 0;
 UINT16 *pBuffer_depth = NULL;
 UINT nBufferSize_coloar = 0;
 RGBQUAD *pBuffer_color = NULL;

 char key = 0;

 while (true) // 貌似要一直尝试,不一定每次都能读取到图像
 {
  IDepthFrame* pDepthFrame = NULL;
  HRESULT hr = m_pDepthFrameReader->AcquireLatestFrame(&pDepthFrame);
  if (SUCCEEDED(hr))
  {
   USHORT nDepthMinReliableDistance = 0;
   USHORT nDepthMaxReliableDistance = 0;
   if (SUCCEEDED(hr))
   {
    hr = pDepthFrame->get_DepthMinReliableDistance(&nDepthMinReliableDistance);
   }

   if (SUCCEEDED(hr))
   {
    hr = pDepthFrame->get_DepthMaxReliableDistance(&nDepthMaxReliableDistance);
   }
   if (SUCCEEDED(hr))
   {
    hr = pDepthFrame->AccessUnderlyingBuffer(&nBufferSize_depth, &pBuffer_depth);
    depthImg_show = ConvertMat(pBuffer_depth, depth_width, depth_height, nDepthMinReliableDistance, nDepthMaxReliableDistance);
   }
  }
  SafeRelease(pDepthFrame);


  //for color
  IColorFrame* pColorFrame = NULL;
  hr = m_pColorFrameReader->AcquireLatestFrame(&pColorFrame);
  ColorImageFormat imageFormat = ColorImageFormat_None;
  if (SUCCEEDED(hr))
  {
   ColorImageFormat imageFormat = ColorImageFormat_None;
   if (SUCCEEDED(hr))
   {
    hr = pColorFrame->get_RawColorImageFormat(&imageFormat);
   }
   if (SUCCEEDED(hr))
   {
    hr = pColorFrame->get_RawColorImageFormat(&imageFormat);
   }
   if (SUCCEEDED(hr))
   {
    if (imageFormat == ColorImageFormat_Bgra)//这里有两个format,不知道具体含义,大概一个预先分配内存,一个需要自己开空间吧
    {
     hr = pColorFrame->AccessRawUnderlyingBuffer(&nBufferSize_coloar, reinterpret_cast<BYTE**>(&pBuffer_color));
    }
    else if (m_pColorRGBX)
    {
     pBuffer_color = m_pColorRGBX;
     nBufferSize_coloar = color_widht * color_height * sizeof(RGBQUAD);
     hr = pColorFrame->CopyConvertedFrameDataToArray(nBufferSize_coloar, reinterpret_cast<BYTE*>(pBuffer_color), ColorImageFormat_Bgra);
    }
    else
    {
     hr = E_FAIL;
    }
    colorImg = ConvertMat(pBuffer_color, color_widht, color_height);
   }

   SafeRelease(pColorFrame);
  }

  cv::imshow("depth", depthImg_show);
  cv::imshow("color", colorImg);


//加的,把信息保存下来
  cv::imwrite("de.jpg", depthImg_show);
  cv::imwrite("co.jpg", colorImg);
  key = cv::waitKey(1);
  if (key == 27)
  {
   break;
  }
 }


 if (m_pColorRGBX)
 {
  delete[] m_pColorRGBX;
  m_pColorRGBX = NULL;
 }
 // close the Kinect Sensor
 if (m_pKinectSensor)
 {
  m_pKinectSensor->Close();
 }
 SafeRelease(m_pKinectSensor);

}


在调试的之前,要把opencv安装并且配置好

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值