Kinect For Windows V2开发日志九:侦测并绘制人体骨架
# 简介
在上一篇[《侦测、追踪人体骨架》](http://www.cnblogs.com/xz816111/p/5187424.html)里,介绍了关节点的使用办法,这一篇记录将关节点与`OpenCV`结合的绘图方法。
代码
#include <iostream>
#include <opencv2\imgproc.hpp>
#include <opencv2\calib3d.hpp>
#include <opencv2\highgui.hpp>
#include <Kinect.h>
using namespace std;
using namespace cv;
void draw(Mat & img, Joint & r_1, Joint & r_2, ICoordinateMapper * myMapper);
int main(void)
{
IKinectSensor * mySensor = nullptr;
GetDefaultKinectSensor(&mySensor);
mySensor->Open();
IColorFrameSource * myColorSource = nullptr;
mySensor->get_ColorFrameSource(&myColorSource);
IColorFrameReader * myColorReader = nullptr;
myColorSource->OpenReader(&myColorReader);
int colorHeight = 0, colorWidth = 0;
IFrameDescription * myDescription = nullptr;
myColorSource->get_FrameDescription(&myDescription);
myDescription->get_Height(&colorHeight);
myDescription->get_Width(&colorWidth);
IColorFrame * myColorFrame = nullptr;
Mat original(colorHeight, colorWidth, CV_8UC4);
//**********************以上为ColorFrame的读取前准备**************************
IBodyFrameSource * myBodySource = nullptr;
mySensor->get_BodyFrameSource(&myBodySource);
IBodyFrameReader * myBodyReader = nullptr;
myBodySource->OpenReader(&myBodyReader);
int myBodyCount = 0;
myBodySource->get_BodyCount(&myBodyCount);
IBodyFrame * myBodyFrame = nullptr;
ICoordinateMapper * myMapper = nullptr;
mySensor->get_CoordinateMapper(&myMapper);
//**********************以上为BodyFrame以及Mapper的准备***********************
while (1)
{
while (myColorReader->AcquireLatestFrame(&myColorFrame) != S_OK);
myColorFrame->CopyConvertedFrameDataToArray(colorHeight * colorWidth * 4, original.data, ColorImageFormat_Bgra);
Mat copy = original.clone(); //读取彩色图像并输出到矩阵
while (myBodyReader->AcquireLatestFrame(&myBodyFrame) != S_OK); //读取身体图像
IBody ** myBodyArr = new IBody *[myBodyCount]; //为存身体数据的数组做准备
for (int i = 0; i < myBodyCount; i++)
myBodyArr[i] = nullptr;
if (myBodyFrame->GetAndRefreshBodyData(myBodyCount, myBodyArr) == S_OK) //把身体数据输入数组
for (int i = 0; i < myBodyCount; i++)
{
BOOLEAN result = false;
if (myBodyArr[i]->get_IsTracked(&result) == S_OK && result) //先判断是否侦测到
{
Joint myJointArr[JointType_Count];
if (myBodyArr[i]->GetJoints(JointType_Count, myJointArr) == S_OK) //如果侦测到就把关节数据输入到数组并画图
{
draw(copy, myJointArr[JointType_Head], myJointArr[JointType_Neck], myMapper);
draw(copy, myJointArr[JointType_Neck], myJointArr[JointType_SpineShoulder], myMapper);
draw(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_ShoulderLeft], myMapper);
draw(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_SpineMid], myMapper);
draw(copy, myJointArr[JointType_SpineShoulder], myJointArr[JointType_ShoulderRight], myMapper);
draw(copy, myJointArr[JointType_ShoulderLeft], myJointArr[JointType_ElbowLeft], myMapper);
draw(copy, myJointArr[JointType_SpineMid], myJointArr[JointType_SpineBase], myMapper);
draw(copy, myJointArr[JointType_ShoulderRight], myJointArr[JointType_ElbowRight], myMapper);
draw(copy, myJointArr[JointType_ElbowLeft], myJointArr[JointType_WristLeft], myMapper);
draw(copy, myJointArr[JointType_SpineBase], myJointArr[JointType_HipLeft], myMapper);
draw(copy, myJointArr[JointType_SpineBase], myJointArr[JointType_HipRight], myMapper);
draw(copy, myJointArr[JointType_ElbowRight], myJointArr[JointType_WristRight], myMapper);
draw(copy, myJointArr[JointType_WristLeft], myJointArr[JointType_ThumbLeft], myMapper);
draw(copy, myJointArr[JointType_WristLeft], myJointArr[JointType_HandLeft], myMapper);
draw(copy, myJointArr[JointType_HipLeft], myJointArr[JointType_KneeLeft], myMapper);
draw(copy, myJointArr[JointType_HipRight], myJointArr[JointType_KneeRight], myMapper);
draw(copy, myJointArr[JointType_WristRight], myJointArr[JointType_ThumbRight], myMapper);
draw(copy, myJointArr[JointType_WristRight], myJointArr[JointType_HandRight], myMapper);
draw(copy, myJointArr[JointType_HandLeft], myJointArr[JointType_HandTipLeft], myMapper);
draw(copy, myJointArr[JointType_KneeLeft], myJointArr[JointType_FootLeft], myMapper);
draw(copy, myJointArr[JointType_KneeRight], myJointArr[JointType_FootRight], myMapper);
draw(copy, myJointArr[JointType_HandRight], myJointArr[JointType_HandTipRight], myMapper);
}
}
}
delete[]myBodyArr;
myBodyFrame->Release();
myColorFrame->Release();
imshow("TEST", copy);
if (waitKey(30) == VK_ESCAPE)
break;
}
myMapper->Release();
myDescription->Release();
myColorReader->Release();
myColorSource->Release();
myBodyReader->Release();
myBodySource->Release();
mySensor->Close();
mySensor->Release();
return 0;
}
void draw(Mat & img, Joint & r_1, Joint & r_2, ICoordinateMapper * myMapper)
{
//用两个关节点来做线段的两端,并且进行状态过滤
if (r_1.TrackingState == TrackingState_Tracked && r_2.TrackingState == TrackingState_Tracked)
{
ColorSpacePoint t_point; //要把关节点用的摄像机坐标下的点转换成彩色空间的点
Point p_1, p_2;
myMapper->MapCameraPointToColorSpace(r_1.Position, &t_point);
p_1.x = t_point.X;
p_1.y = t_point.Y;
myMapper->MapCameraPointToColorSpace(r_2.Position, &t_point);
p_2.x = t_point.X;
p_2.y = t_point.Y;
line(img, p_1, p_2, Vec3b(0, 255, 0), 5);
circle(img, p_1, 10, Vec3b(255, 0, 0), -1);
circle(img, p_2, 10, Vec3b(255, 0, 0), -1);
}
}
详细说明
不难发现代码跟前面一篇非常类似,不同的地方就在于绘图部分。首先要将关节点用的CameraSpace转换到ColorSpace,这一操作可以借助ICoordinateMapper完成,然后就用两个关节点来作为线段的两端画线。这里采用了广度优先的办法,从上到下一层一层选取关节点。
效果图

Kinect For Windows V2开发日志九:侦测并绘制人体骨架的更多相关文章
- Kinect For Windows V2开发日志八:侦测、追踪人体骨架
简介 Kinect一个很强大的功能就是它可以侦测到人体的骨骼信息并追踪,在Kinect V2的SDK 2.0中,它最多可以同时获取到6个人.每个人25个关节点的信息,并且通过深度摄像头,可以同时获取到 ...
- Kinect For Windows V2开发日志一:开发环境的配置
算是正式进军Kinect了,前段时间学的东西现在就忘了,于是从此开始记录一下. 目前为止大部分的学习资料来自于Heresy的博客,写的非常优秀,清晰明了,十分感谢.开发语言为C++,应该会一直使用,但 ...
- Kinect For Windows V2开发日志六:人体的轮廓的表示
Kinect中带了一种数据源,叫做BodyIndex,简单来说就是它利用深度摄像头识别出最多6个人体,并且用数据将属于人体的部分标记,将人体和背景区别开来.利用这一特性,就可以在环境中显示出人体的轮廓 ...
- Kinect For Windows V2开发日志五:使用OpenCV显示彩色图像及红外图像
彩色图像 #include <iostream> #include <Kinect.h> #include <opencv2\highgui.hpp> using ...
- Kinect For Windows V2开发日志七:照片合成与背景消除
上一篇里讲到了Kinect可以从环境中区分出人体来.因此可以利用这个功能,来把摄像头前的人合成进照片里,和利用Photoshop不同的是,这样合成进去的人是动态且实时的. 简单的思路 BodyInde ...
- Kinect For Windows V2开发日志四:使用OpenCV显示深度图像
代码示例: #include <Kinect.h> #include <iostream> #include <opencv2\highgui.hpp> using ...
- Kinect For Windows V2开发日志三:简单的深度读取
代码示例: #include <Kinect.h> #include <iostream> using namespace std; int main(void) { IKin ...
- Kinect For Windows V2开发日志二:Kinect V2的基本参数
以下内容节选自Heresy的博客: 彩色影像:1920 x 1080 @ 30 / 15 FPS(根据环境亮度) 深度影像:512 x 424 @ 30 FPS.16bit 距离值(mm).可侦测 ...
- Kinect for Windows V2开发教程
教程 https://blog.csdn.net/openbug/article/details/80921437 Windows版Kinect SDK https://docs.microsoft. ...
随机推荐
- 使用struts2实现文件上传
action中 private File file;//文件 private String fileFileName;//文件名字 固定格式name+FileName private String f ...
- 测试rest接口的两个工具使用详解(restclient+soapUI)
http://www.cnblogs.com/lanxuezaipiao/archive/2013/05/31/3110764.html http://www.oschina.net/news/618 ...
- jqGrid初次使用遇到的问题及解决方法
问题一:初始化定义翻页用的导航栏时,表中出现"undefined"方框: 解决:需要导入grid.locale-cn.js文件. 问题二:页面只有一页,无法翻页: 解决:初始化设置 ...
- 由“大数据量Excel入库高效方式”瞥见“并联系统”之优势
使用场景: 当你有一个Excel文件,需要把其中的数据高速录入到数据库中,文件中包含10万条以上数据. 设计方案: 我们将整个过程分成三个阶段,A(装载Excel文件). ...
- centos7.2安装配置
VMware12上安装Centos7,如果电脑是64位,这必须选择64位的centos系统,不然安装完会找不到网卡.安装过程中应当开启网卡选项. 安装完想用ifconfig命令查找IP地址会提示错误: ...
- Educational Codeforces Round 7 E. Ants in Leaves 贪心
E. Ants in Leaves 题目连接: http://www.codeforces.com/contest/622/problem/E Description Tree is a connec ...
- 【JavaScript】关于JS中的constructor与prototype
最初对js中 object.constructor 的认识: 在学习JS的面向对象过程中,一直对constructor与prototype感到很迷惑,看了一些博客与书籍,觉得自己弄明白了,现在记录如下 ...
- impdp的一些实际问题解决方法
之前在http://blog.csdn.net/bisal/article/details/19067515写过一篇关于expdp和impdp的实践的帖子.今天碰到个问题,有些内容没有介绍全,这里再补 ...
- 三星Galaxy S4(GT-I9500)获取ROOT权限教程(转)
http://news.candou.com/2013-05-20/453695_1.shtml 获取root权限的方法
- SQL Server如何截断(Truncate)和收缩(Shrink)事务日志
当SQL Server截断事务日志时,它仅仅是在虚拟日志文件中做个标记,以便不再使用它,然后准备以重用形式来做备份(假如运载在完整或是批量日志恢复模型).也就是说,在使用简单恢复模型时,事务日志包括如 ...