博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Kinect For Windows V2开发日志九:侦测并绘制人体骨架
阅读量:6984 次
发布时间:2019-06-27

本文共 6295 字,大约阅读时间需要 20 分钟。

简介

在上一篇里,介绍了关节点的使用办法,这一篇记录将关节点与OpenCV结合的绘图方法。


代码

#include 
#include
#include
#include
#include
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完成,然后就用两个关节点来作为线段的两端画线。这里采用了广度优先的办法,从上到下一层一层选取关节点。


效果图

o_fasd.jpg

转载于:https://www.cnblogs.com/xz816111/p/5193052.html

你可能感兴趣的文章
函数计算的 Python手册小问题
查看>>
<转载>一直以来伴随我的一些学习习惯 – 2
查看>>
Transaction 'IREG', Abend 'APCT', at '????'.
查看>>
30343上机过程
查看>>
304413存储过程和触发器
查看>>
性能测试之数据准备
查看>>
Django艺术起点(初探)
查看>>
EXT.NET复杂布局(二)——报表
查看>>
Multipart forms from C# client
查看>>
过滤及分析数据包
查看>>
STM32中断名词
查看>>
[转]Java数组扩容算法及Java对它的应用
查看>>
01.Java安装及环境变量的设置
查看>>
十四、curator recipes之DistributedAtomicLong
查看>>
模板中的名字查找问题
查看>>
StringUtils工具类用法
查看>>
QListView的子项的ViewMode
查看>>
erlang的erl文件的编码方式
查看>>
Kosaraju算法解决强连通问题
查看>>
做一个完整的Java Web项目需要掌握的技能
查看>>