Kinect For Windows V2開發日志六:人體的輪廓的表示


> Kinect中帶了一種數據源,叫做`BodyIndex`,簡單來說就是它利用深度攝像頭識別出最多6個人體,並且用數據將屬於人體的部分標記,將人體和背景區別開來。利用這一特性,就可以在環境中顯示出人體的輪廓而略去背景的細節。我采用了下面兩種方式來實現。

用OpenCV表示

代碼

#include <iostream>
#include <Kinect.h>
#include <opencv2\highgui.hpp>

using	namespace	std;
using	namespace	cv;

int	main(void)
{
	IKinectSensor	* mySensor = nullptr;			    //Sensor
	GetDefaultKinectSensor(&mySensor);
	mySensor->Open();

	IBodyIndexFrameSource	* mySource = nullptr;		//Source
	mySensor->get_BodyIndexFrameSource(&mySource);

	int	height = 0, width = 0;
	IFrameDescription	* myDescription = nullptr;	
	mySource->get_FrameDescription(&myDescription);
	myDescription->get_Height(&height);
	myDescription->get_Width(&width);

	IBodyIndexFrameReader	* myReader = nullptr;		//Reader
	mySource->OpenReader(&myReader);

	IBodyIndexFrame		* myFrame = nullptr;		    //Frame
	Mat	img(height,width,CV_8UC3);
	Vec3b	color[7] = { Vec3b(0,0,255),Vec3b(0,255,255),Vec3b(255,255,255),Vec3b(0,255,0),Vec3b(255,0,0),Vec3b(255,0,255),Vec3b(0,0,0) };

	while (1)
	{
		if (myReader->AcquireLatestFrame(&myFrame) == S_OK)
		{
			UINT	size = 0;
			BYTE	* buffer = nullptr;
			myFrame->AccessUnderlyingBuffer(&size,&buffer);
			for (int i = 0; i < height; i++)
				for (int j = 0; j < width; j++)
				{
					int	index = buffer[i * width + j];		//0-5代表人體,其它值代表背景,用此將人體和背景渲染成不同顏色
					if (index <= 5)
						img.at<Vec3b>(i, j) = color[index];
					else
						img.at<Vec3b>(i, j) = color[6];

				}
			imshow("TEST",img);
			myFrame->Release();
		}
		if (waitKey(30) == VK_ESCAPE)
			break;
	}
	myReader->Release();
	myDescription->Release();
	mySource->Release();
	mySensor->Close();
	mySensor->Release();

	return	0;
}

詳細說明

步驟和前面相似,不再贅述,關鍵在於對數據的處理。IBodyIndexFrame 里的數據分兩種,值在0-5之間的點代表的是人體(因此最多識別出6個人),大於5的值代表的是背景。所以要顯示人體時,只要簡單的把代表人體的點渲染成一種顏色,背景渲染成另外一種顏色就可以了。值得注意的是在寫顏色表color時,要用Vec3b把數據強轉一下,不然會有問題。

最終的效果就是這樣:


直接用數據勾畫出人體

代碼:

#include <iostream>
#include <Kinect.h>
#include <Windows.h>

using	namespace	std;
using	namespace	cv;

int	main(void)
{
	IKinectSensor	* mySensor = nullptr;			//Sensor
	GetDefaultKinectSensor(&mySensor);
	mySensor->Open();

	IBodyIndexFrameSource	* mySource = nullptr;		//Source
	mySensor->get_BodyIndexFrameSource(&mySource);

	int	height = 0, width = 0;
	IFrameDescription	* myDescription = nullptr;	
	mySource->get_FrameDescription(&myDescription);
	myDescription->get_Height(&height);
	myDescription->get_Width(&width);

	IBodyIndexFrameReader	* myReader = nullptr;		//Reader
	mySource->OpenReader(&myReader);

	IBodyIndexFrame		* myFrame = nullptr;		    //Frame
	while (1)
	{
		Sleep(1000);
		if (myReader->AcquireLatestFrame(&myFrame) == S_OK)
		{
			UINT	size = 0;
			BYTE	* buffer = nullptr;
			myFrame->AccessUnderlyingBuffer(&size,&buffer);
			for (int i = 50; i < 350; i++)		    //調出一個合適的尺寸
			{
				for (int j = 0; j < width; j++)
				{
					int	index = buffer[i * width + j];
					if (index <= 5)
						cout << 0;
					else
						cout << 1;
				}
				cout << endl;
			}
			cout << endl << endl;
			myFrame->Release();
		}
	}
	myReader->Release();
	myDescription->Release();
	mySource->Release();
	mySensor->Close();
	mySensor->Release();

	return	0;
}

說明

實際上,因為有可以用數字來區別人體和背景這一特性,所以甚至可以不用openCV,直接用數據來顯示人體。將識別為人體的數據作為0輸出,背景作為1輸出,同時把控制台的窗口調大一些,字體調到最小,每秒鍾輸出一幀,就能直接看到數據畫出的圖。真是有趣。

效果如下:






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM