Kinect For Windows V2开发日志五:使用OpenCV显示彩色图像及红外图像


# 彩色图像 ```CPP #include #include #include

using namespace std;
using namespace cv;

int main(void)
{
IKinectSensor * mySensor = nullptr; //第1步打开Sensor
GetDefaultKinectSensor(&mySensor);
mySensor->Open();

IColorFrameSource	* mySource = nullptr;		//第2步获取Source
mySensor->get_ColorFrameSource(&mySource);

int		height = 0, width = 0;			        //取得宽和高等下用
IFrameDescription	* myDescription = nullptr;
mySource->get_FrameDescription(&myDescription);
myDescription->get_Height(&height);
myDescription->get_Width(&width);

IColorFrameReader	* myReader = nullptr;		//第3步打开Reader
mySource->OpenReader(&myReader);

Mat	img(height,width,CV_8UC4);
IColorFrame		* myFrame = nullptr;
while (1)
{
	if (myReader->AcquireLatestFrame(&myFrame) == S_OK)	//第4步获取Frame
	{
		UINT	size = 0;
		myFrame->CopyConvertedFrameDataToArray(width * height * 4,(BYTE *)img.data,ColorImageFormat_Bgra);
		imshow("TEST",img);
		myFrame->Release();
	}
	if (waitKey(30) == VK_ESCAPE)
		break;
}
myReader->Release();		//记得要释放
myDescription->Release();
mySource->Release();
mySensor->Close();
mySensor->Release();

return	0;

}

- - -
## 详细解释:
读取彩色图像的步骤和读取深度图像的是一样的,区别在于数据输出的处理上。Kinect V2使用的图像格式是YUY2,不太好处理,好在彩色帧自带了一个转换函数`CopyConvertedFrameDataToArray()`,它的:

- 第一个参数是所需的大小
- 第二个参数是目标数组
- 第三个参数是要转换的格式,其中第三个参数的类型可以在[这里](https://msdn.microsoft.com/en-us/library/microsoft.kinect.kinect.colorimageformat.aspx)找到。

第一个参数的大小为图像的长乘上宽再乘上4个通道。
因为我们要转成RGB,但是枚举量里带RGB的都还有一个A,这个A代表的是透明度,成了`RGBA`,所以开Mat时要开成四通道的(另外选8位而不选16位的原因我个人理解是,那个转换函数第二个参数要求类型是`BYTE`,而一个`BYTE`是8位的)。


令我费解的是,`Rgba`和`Bgra`只是通道的顺序不同,混合出来的效果应该是一样的,但是如果选用`Rgba`,显示出来的颜色就不正确。懂了以后更新。<font color=red>(更新:原来OpenCV在使用数据时,不是简单的把输入的三种颜色叠加,而是把输入的值当成对应的颜色的值,然后叠加这些值,OpenCV用的颜色模式是BGR,所以RGB中R的量就成了B的量,B的量就成了R的量,因此显示出的图像色彩就不对了)。</font>

- - -
# 红外图像
```CPP
#include <iostream>
#include <Kinect.h>
#include <opencv2\highgui.hpp>

using	namespace	std;
using	namespace	cv;

int	main(void)
{
	IKinectSensor	* mySensor = nullptr;			    //第1步打开Sensor
	GetDefaultKinectSensor(&mySensor);
	mySensor->Open();

	IInfraredFrameSource	* mySource = nullptr;		//第2步获取Source
	mySensor->get_InfraredFrameSource(&mySource);

	int		height = 0, width = 0;		                //取得宽和高等下用
	IFrameDescription	* myDescription = nullptr;
	mySource->get_FrameDescription(&myDescription);
	myDescription->get_Height(&height);
	myDescription->get_Width(&width);

	IInfraredFrameReader	* myReader = nullptr;		//第3步打开Reader
	mySource->OpenReader(&myReader);

	Mat	img(height,width,CV_16UC1);
	IInfraredFrame	* myFrame = nullptr;
	while (1)
	{
		if (myReader->AcquireLatestFrame(&myFrame) == S_OK)	//第4步获取Frame
		{
			myFrame->CopyFrameDataToArray(height * width,(UINT16 *)img.data);
			imshow("TEST",img);
			myFrame->Release();
		}
		if (waitKey(30) == VK_ESCAPE)
			break;
	}
	myReader->Release();		//记得要释放
	myDescription->Release();
	mySource->Release();
	mySensor->Close();
	mySensor->Release();

	return	0;
}

详细解释

可见此段代码于上一段几乎一样,只是输出数据时换个函数就行了,Mat开16位是因为CopyFrameDataToArray()中第2个参数指定16位,因此这样的推论应该是正确的。





免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM