Kinect开发教程五OpenNI获取人体骨架Word文档格式.docx
- 文档编号:16339711
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:10
- 大小:49.42KB
Kinect开发教程五OpenNI获取人体骨架Word文档格式.docx
《Kinect开发教程五OpenNI获取人体骨架Word文档格式.docx》由会员分享,可在线阅读,更多相关《Kinect开发教程五OpenNI获取人体骨架Word文档格式.docx(10页珍藏版)》请在冰豆网上搜索。
6#include<
XnModuleCppInterface.h>
7#include"
cv.h"
8#include"
highgui.h"
9
10usingnamespacestd;
11usingnamespacecv;
12
13//#pragmacomment(lib,"
cv210"
)
14//#pragmacomment(lib,"
cxcore210"
15//#pragmacomment(lib,"
highgui210"
16//#pragmacomment(lib,"
OpenNI"
17
18//【1】
19xn:
:
UserGeneratoruserGenerator;
20xn:
DepthGeneratordepthGenerator;
21xn:
ImageGeneratorimageGenerator;
22
23/*
24XN_SKEL_HEAD=1,XN_SKEL_NECK=2,
25XN_SKEL_TORSO=3,XN_SKEL_WAIST=4,
26XN_SKEL_LEFT_COLLAR=5,XN_SKEL_LEFT_SHOULDER=6,
27XN_SKEL_LEFT_ELBOW=7,XN_SKEL_LEFT_WRIST=8,
28XN_SKEL_LEFT_HAND=9,XN_SKEL_LEFT_FINGERTIP=10,
29XN_SKEL_RIGHT_COLLAR=11,XN_SKEL_RIGHT_SHOULDER=12,
30XN_SKEL_RIGHT_ELBOW=13,XN_SKEL_RIGHT_WRIST=14,
31XN_SKEL_RIGHT_HAND=15,XN_SKEL_RIGHT_FINGERTIP=16,
32XN_SKEL_LEFT_HIP=17,XN_SKEL_LEFT_KNEE=18,
33XN_SKEL_LEFT_ANKLE=19,XN_SKEL_LEFT_FOOT=20,
34XN_SKEL_RIGHT_HIP=21,XN_SKEL_RIGHT_KNEE=22,
35XN_SKEL_RIGHT_ANKLE=23,XN_SKEL_RIGHT_FOOT=24
36*/
37//alinewillbedrawnbetweenstartpointandcorrespondingendpoint
38intstartSkelPoints[14]={1,2,6,6,12,17,6,7,12,13,17,18,21,22};
39intendSkelPoints[14]={2,3,12,21,17,21,7,9,13,15,18,20,22,24};
40
41//callbackfunctionofusergenerator:
newuser
42voidXN_CALLBACK_TYPENewUser(xn:
UserGenerator&
generator,XnUserIDuser,void*pCookie)
43{
44cout<
<
"
Newuseridentified:
<
user<
endl;
45//userGenerator.GetSkeletonCap().LoadCalibrationDataFromFile(user,"
UserCalibration.txt"
);
46generator.GetPoseDetectionCap().StartPoseDetection("
Psi"
user);
47}
48
49//callbackfunctionofusergenerator:
lostuser
50voidXN_CALLBACK_TYPELostUser(xn:
51{
52cout<
User"
lost"
53}
54
55//callbackfunctionofskeleton:
calibrationstart
56voidXN_CALLBACK_TYPECalibrationStart(xn:
SkeletonCapability&
skeleton,XnUserIDuser,void*pCookie)
57{
58cout<
Calibrationstartforuser"
59}
60
61//callbackfunctionofskeleton:
calibrationend
62voidXN_CALLBACK_TYPECalibrationEnd(xn:
skeleton,XnUserIDuser,XnCalibrationStatuscalibrationError,void*pCookie)
63{
64cout<
Calibrationcompleteforuser"
"
;
65if(calibrationError==XN_CALIBRATION_STATUS_OK)
66{
67cout<
Success"
68skeleton.StartTracking(user);
69//userGenerator.GetSkeletonCap().SaveCalibrationDataToFile(user,"
70}
71else
72{
73cout<
Failure"
74//ForthecurrentversionofOpenNI,onlyPsiposeisavailable
75((xn:
UserGenerator*)pCookie)->
GetPoseDetectionCap().StartPoseDetection("
user);
76}
77}
78
79//callbackfunctionofposedetection:
posestart
80voidXN_CALLBACK_TYPEPoseDetected(xn:
PoseDetectionCapability&
poseDetection,constXnChar*strPose,XnUserIDuser,void*pCookie)
81{
82cout<
Pose"
strPose<
detectedforuser"
83((xn:
GetSkeletonCap().RequestCalibration(user,FALSE);
84poseDetection.StopPoseDetection(user);
85}
86
87voidclearImg(IplImage*inputimg)
88{
89CvFontfont;
90cvInitFont(&
font,CV_FONT_VECTOR0,1,1,0,3,5);
91memset(inputimg->
imageData,255,640*480*3);
92}
93
94
95intmain(intargc,char**argv)
96{
97charkey=0;
98intimgPosX=0;
99intimgPosY=0;
100
101//initialcontext
102xn:
Contextcontext;
103context.Init();
104xn:
ImageMetaDataimageMD;
105
106IplImage*cameraImg=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
107cvNamedWindow("
Camera"
1);
108
109//mapoutputmode
110XnMapOutputModemapMode;
111mapMode.nXRes=640;
112mapMode.nYRes=480;
113mapMode.nFPS=30;
114
115//creategenerator
116depthGenerator.Create(context);
117depthGenerator.SetMapOutputMode(mapMode);
118imageGenerator.Create(context);
119userGenerator.Create(context);
120
121//【2】
122//Registercallbackfunctionsofusergenerator
123XnCallbackHandleuserCBHandle;
124userGenerator.RegisterUserCallbacks(NewUser,LostUser,NULL,userCBHandle);
125
126//【3】
127//Registercallbackfunctionsofskeletoncapability
128xn:
SkeletonCapabilityskeletonCap=userGenerator.GetSkeletonCap();
129skeletonCap.SetSkeletonProfile(XN_SKEL_PROFILE_ALL);
130XnCallbackHandlecalibCBHandle;
131skeletonCap.RegisterToCalibrationStart(CalibrationStart,&
userGenerator,calibCBHandle);
132skeletonCap.RegisterToCalibrationComplete(CalibrationEnd,&
133
134//【4】
135//RegistercallbackfunctionsofPoseDetectioncapability
136XnCallbackHandleposeCBHandle;
137userGenerator.GetPoseDetectionCap().RegisterToPoseDetected(PoseDetected,&
userGenerator,poseCBHandle);
138
139
140//startgeneratedata
141context.StartGeneratingAll();
142while(key!
=27)
143{
144context.WaitAndUpdateAll();
145
146imageGenerator.GetMetaData(imageMD);
147memcpy(cameraImg->
imageData,imageMD.Data(),640*480*3);
148cvCvtColor(cameraImg,cameraImg,CV_RGB2BGR);
149//getusers
150XnUInt16userCounts=userGenerator.GetNumberOfUsers();
151if(userCounts>
0)
152{
153XnUserID*userID=newXnUserID[userCounts];
154userGenerator.GetUsers(userID,userCounts);
155for(inti=0;
i<
userCounts;
++i)
156{
157//【5】
158//ifistrackingskeleton
159if(skeletonCap.IsTracking(userID[i]))
160{
161XnPoint3DskelPointsIn[24],skelPointsOut[24];
162XnSkeletonJointTransformationmJointTran;
163for(intiter=0;
iter<
24;
iter++)
164{
165//XnSkeletonJointfrom1to24
166skeletonCap.GetSkeletonJoint(userID[i],XnSkeletonJoint(iter+1),mJointTran);
167skelPointsIn[iter]=mJointTran.position.position;
168}
169depthGenerator.ConvertRealWorldToProjective(24,skelPointsIn,skelPointsOut);
170
171//【6】
172for(intd=0;
d<
14;
d++)
173{
174CvPointstartpoint=cvPoint(skelPointsOut[startSkelPoints[d]-1].X,skelPointsOut[startSkelPoints[d]-1].Y);
175CvPointendpoint=cvPoint(skelPointsOut[endSkelPoints[d]-1].X,skelPointsOut[endSkelPoints[d]-1].Y);
176
177cvCircle(cameraImg,startpoint,3,CV_RGB(0,0,255),12);
178cvCircle(cameraImg,endpoint,3,CV_RGB(0,0,255),12);
179cvLine(cameraImg,startpoint,endpoint,CV_RGB(0,0,255),4);
180}
181}
182}
183delete[]userID;
184}
185cvShowImage("
cameraImg);
186
187key=cvWaitKey(20);
188
189
190}
191//stopandshutdown
192cvDestroyWindow("
);
193cvReleaseImage(&
cameraImg);
194context.StopGeneratingAll();
195context.Shutdown();
196
197return0;
198}
【1】对于人体骨架的获取,小斤声明了UserGenerator这个生成器,UserGenerator具有检测新的User(以下称为人物)出现或者离开,获取画面中的人物数,人物位置信息,与上一教程介绍的GestureGenerator类似,通过注册回调函数的方式,一旦其检测到了动静(如人物出现),那么相应的回调函数就会被调用。
【2】小斤为UserGenerator注册了NewUser和LostUser两个回调函数,对应人物出现和人物消失。
【3】这里出现了一个新的Capability,SkeletonCapability。
小斤为了避免混淆,常常将Capability理解为生成器的一种能力,比如SkeletonCapability就可以理解UserGenerator获取人物骨架信息的能力。
在获取人物骨架前,首先要进行标定的工作,因此SkeletonCapability需要注册两个回调函数CalibrationStart和CalibrationEnd,分别在人物标定开始与结束时调用。
(在较早版本的OpenNI中,接口名可能有所变化)
【4】与【3】类似,userGenerator.GetPoseDetectionCap()获取了一个PoseDetectionCapability,这个Capability可以检测人物的特定姿势,目前来说,只支持Psi姿势,如图:
小斤并为其注册了回调函数PoseDetected,在检测到人物的Psi姿势时,会调用该函数。
将【2】【3】【4】的回调函数串联起来看,
(1)人物出现会触发NewUser(),开始Pose检测;
(2)检测到Pose会触发PoseDetected(),请求标定;
(3)标定开始触发CalibrationStart();
(4)标定结束触发CalibrationEnd(),如果标定成功,那么调用SkeletonCapability的StartTracking()开始跟踪对应的人物。
【5】通过GetSkeletonJoint()方法,可以得到对应关节的XnSkeletonJointTransformation,这个结构体包含position和orientation,position中又包含一个position和fConfidence,分别代表关节的位置和可信度,orientation同样如此,包含关节的运动方向和可信度。
这里小斤对24个关节都进行了操作,但能得到位置信息的只有14个。
这些步骤得到的position信息,是一个真实场景的3D坐标,需要通过投影转换到屏幕坐标,转换过程通过ConvertRealWorldToProjective()方法实现。
【6】为了更直观地输出显示,可以各个关节通过直线连接起来,形成一个人体的骨架。
小斤定义了startSkelPoints和endSkelPoints数组,两个数组的值一一对应,代表一组起点终点的关节对,将每组起点和终点通过直线连接,比如HEAD与NECT与TORSO等。
整个程序启动后,先将身体正对摄像头(至少露出头部和上半身),控制台会显示“Newuseridentified”,然后做出Psi姿势,在PosePsidetected后,程序开始标定工作,此时维持Psi姿势数秒,标定成功后,骨架就会正确显示出来了。
祝大家玩得愉快。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Kinect 开发 教程 OpenNI 获取 人体 骨架