通过Kinect SDK v2预览版,取得BodyIndex(人体区域)的方法和示例代码。
上一节,介绍了从Kinect v2预览版用Kinect SDK v2预览版获取Depth数据的方法。
这一节,介绍从Kinect取得BodyIndex(人体区域)的方法。
BodyIndex
基于从Kinect取得的Depth数据(传感器的距离信息)获取人体区域。
因为人体区域基于Depth数据,同时也依赖Depth传感器的分辨率。像上一节介绍的一样,
因为Kinect v2
预览版(512×424)的Depth传感器的分辨率大幅提高,
和Kinect v1相比,
手指等细小部分的人体区域
也变得可以准确的取得。
但是,
能检测出的人体区域
的数量还是6个人这一点没有发生改变。
关于人体区域,在Kinect SDK v1里被称为
「Player」,
不过到了
Kinect SDK v2
预览版里更名为
「BodyIndex」。
这一节,介绍取得
「BodyIndex」的方法。
![](https://i-blog.csdnimg.cn/blog_migrate/faa1f55f2b33dd215ee548089640426c.jpeg)
图1 Kinect SDK v2预览版的示例程序(BodyBasics)
把
BodyIndex在Color坐标的位置匹配截取,
手指等细小部分都可以清晰得在人体
身上保留下来了。
(注:因为Color和Depth的Camera位置不同,所以需要进行坐标空间的转换)
样品程序
使用Kinect SDK v2预览版取得BodyIndex,把每个人体用颜色区分出来并显示的示例程序展示。第2节有介绍的取得数据的阶段
摘录解说。这个示例程序的全部内容,
在下面的github里公开。
![](https://i-blog.csdnimg.cn/blog_migrate/141ef26289e44cb3aa0c75628e75a4bc.png)
图2 Kinect SDK v2预览版的数据取得流程(重发)
「Sensor」
取得「Sensor」
// Sensor IKinectSensor* pSensor; ……1 HRESULT hResult = S_OK; hResult = GetDefaultKinectSensor( &pSensor ); ……2 if( FAILED( hResult ) ){ std::cerr << "Error : GetDefaultKinectSensor" << std::endl; return -1; } hResult = pSensor->Open(); ……3 if( FAILED( hResult ) ){ std::cerr << "Error : IKinectSensor::Open()" << std::endl; return -1; }
列表1.1 相当于图1「Source」的部分
1 处理Kinect v2预览版的Sensor接口。
2 取得默认的
Sensor。
3 打开Sensor。
「Source」
从「Sensor」取得「Source」。
// Source IBodyIndexFrameSource* pBodyIndexSource; ……1 hResult = pSensor->get_BodyIndexFrameSource( &pBodyIndexSource ); ……2 if( FAILED( hResult ) ){ std::cerr << "Error : IKinectSensor::get_BodyIndexFrameSource()" << std::endl; return -1; }
列表1.2
相当于图1「Source」的部分
1 取得BodyIndex Frame的Source接口。
2 从Sensor取得
Source。
「Reader」
「Source」从打开「Reader」。
// Reader IBodyIndexFrameReader* pBodyIndexReader; ……1 hResult = pBodyIndexSource->OpenReader( &pBodyIndexReader ); ……2 if( FAILED( hResult ) ){ std::cerr << "Error : IBodyIndexFrameSource::OpenReader()" << std::endl; return -1; }
列表1.3 相当于图1「Reader」的部分
1 取得BodyIndex Frame的Reader接口。
2 从Source打开Reader。
「Frame」~「Data」
从「Reader」取得最新的「Frame」。
int width = 512; ……1 int height = 424; ……1 cv::Mat bodyIndexMat( height, width, CV_8UC3 ); ……2 cv::namedWindow( "BodyIndex" ); // Color Table cv::Vec3b color[6]; ……3 color[0] = cv::Vec3b( 255, 0, 0 ); color[1] = cv::Vec3b( 0, 255, 0 ); color[2] = cv::Vec3b( 0, 0, 255 ); color[3] = cv::Vec3b( 255, 255, 0 ); color[4] = cv::Vec3b( 255, 0, 255 ); color[5] = cv::Vec3b( 0, 255, 255 ); while( 1 ){ // Frame IBodyIndexFrame* pBodyIndexFrame = nullptr; ……4 hResult = pBodyIndexReader->AcquireLatestFrame( &pBodyIndexFrame ); ……5 if( SUCCEEDED( hResult ) ){ unsigned int bufferSize = 0; unsigned char* buffer = nullptr; hResult = pBodyIndexFrame->AccessUnderlyingBuffer( &bufferSize, &buffer ); ……6 if( SUCCEEDED( hResult ) ){ for( int y = 0; y < height; y++ ){ for( int x = 0; x < width; x++ ){ unsigned int index = y * width + x; if( buffer[index] != 0xff ){ bodyIndexMat.at<cv::Vec3b>( y, x ) = color[buffer[index]]; ……7 } else{ bodyIndexMat.at<cv::Vec3b>( y, x ) = cv::Vec3b( 0, 0, 0 ); ……7 } } } } } SafeRelease( pBodyIndexFrame ); // Show Window cv::imshow( "BodyIndex", bodyIndexMat ); if( cv::waitKey( 30 ) == VK_ESCAPE ){ break; } }
列表1.4 相当于图1「Frame」,「Data」的部分
1 BodyIndex的尺寸(512×424)。
这里为了简化说明,画像尺寸用硬代码来设定,示例程序可以Source取得着Frame信息。
2 为了从BodyIndex获得人体区域来绘制,使用OpenCV的cv::Mat。
3 绘制人体区域的color table。
4 取得BodyIndex用的Frame接口。
5 从Reader取得最新的Frame。
6 从Frame取得BodyIndex。
取得保存BodyIndex数组的指针。
7 绘制BodyIndex的人体区域。
每个BodyIndex参照color table着色。
如果可以从取得「Frame」的里获取BodyIndex的数据。
取出的BodyIndex的数据,
像图3一样,
把人体区域
和非人体区域
的按各自对应的值来填入。
Kinect SDK v1的「Player」是按人体区域是
「1」~「6」(因为是6个人),
非人体区域
「0」来填入;
Kinect SDK v2
预览版的「BodyIndex」是按照人体区域
「0」~「5」,非人体領域
「255(0xff)」来填入(图1)。
![](https://i-blog.csdnimg.cn/blog_migrate/6c258382cb3fd5cf7b2a33d1ad596534.png)
图3 BodyIndex数据
Kinect SDK v1 | Kinect SDK v2预览版 | |
---|---|---|
名称 | Player | BodyIndex |
检测支持人数 | 6人 | 6人 |
人体領域的値 | 1~6 | 0~5 |
非人体領域的値 | 0 | 255(0xff) |
表1 Kinect SDK v1和Kinect SDK v2预览版的人体区域(Player,BodyIndex)的比较
示例程序是,把
BodyIndex的值,
在人体区域
用
color table的颜色
(=「cv::Vec3b(B,
G,
R )」),
在非人体区域
用黑色
(=「cv::Vec3b(0,
0,
0)」)
进行着色来实现可视化。
运行结果
运行这个示例程序,就像图4一样,从v2
预览版取得的人体区域
被着色显示。
![](https://i-blog.csdnimg.cn/blog_migrate/dc51bf10739953ef3e4a483f2facffdd.png)
图4 运行结果
手指的细小形状可以清楚的分割取出。
总结
这一节是使用
Kinect SDK v2
预览版取得
BodyIndex的示例程序的介绍,下一节是取得
Body(人体
姿势)的示例程序的介绍。