zoukankan      html  css  js  c++  java
  • Kinect For Windows V2开发日志六:人体的轮廓的表示

    > Kinect中带了一种数据源,叫做`BodyIndex`,简单来说就是它利用深度摄像头识别出最多6个人体,并且用数据将属于人体的部分标记,将人体和背景区别开来。利用这一特性,就可以在环境中显示出人体的轮廓而略去背景的细节。我采用了下面两种方式来实现。

    用OpenCV表示

    代码

    #include <iostream>
    #include <Kinect.h>
    #include <opencv2highgui.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输出,同时把控制台的窗口调大一些,字体调到最小,每秒钟输出一帧,就能直接看到数据画出的图。真是有趣。

    效果如下:





  • 相关阅读:
    memcache的最佳实践方案。
    ehcache memcache redis 三大缓存男高音
    微服务-----(网站架构演变)
    分布式job-任务调度(一)
    rocketmq(三 java操作rocket API, rocketmq 幂等性)
    rocketMQ(二 )Centos7 集群
    go基础三 数组,切片,map,list
    go语言基础二 函数 ,递归函数 ,指针
    go语言基础一:数据类型,变量和常量,类型转化
    Spring AOP 学习(一) 代理模式
  • 原文地址:https://www.cnblogs.com/xz816111/p/5185010.html
Copyright © 2011-2022 走看看