skelecton.cpp
上传用户:jsylhbnbhn
上传日期:2013-11-03
资源大小:119k
文件大小:17k
源码类别:

OpenCV

开发平台:

Visual C++

  1. // skelecton.cpp: implementation of the skelecton class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "skelecton.h"
  5. #include "kalman.h"
  6. #include <string.h>
  7. #include <math.h>
  8. #include "vector3f.h"
  9. #include <assert.h>
  10. //////////////////////////////////////////////////////////////////////
  11. // Construction/Destruction
  12. //////////////////////////////////////////////////////////////////////
  13. int coordinator_X,coordinator_Y=0; //图像中心坐标
  14. const double MaxMinZero=0.0000001;  //小于这个值认为是0
  15. const double f=200;  //pin-hole的有效焦距
  16. const double StardardLength=500;  //对应现实世界的人体的高度,实际上是对应的象素
  17. const double StardardLengthNoiseRatio = 0.3 ; //测量误差占整个测量的比率
  18. double arc_y= 0;//y轴旋转15度
  19. double arc_z= 0;//z轴旋转15度
  20. skelecton::skelecton()
  21. {
  22. bone *pbone = new bone (1,"neck",0);
  23. bonevec.push_back (*pbone);
  24. pbone = new bone (2,"head",1);
  25. pbone->start_arc_x = 30.0;   //角度定义为右手坐标系
  26. pbone->end_arc_x = -30.0;
  27. pbone->start_arc_z = 10.0;
  28. pbone->end_arc_z = -80.0;
  29. bonevec.push_back (*pbone);
  30. pbone = new bone (3,"rShoulder",1);
  31. bonevec.push_back (*pbone);
  32. pbone = new bone (4,"lShoulder",1);
  33. bonevec.push_back (*pbone);
  34. pbone = new bone (5,"rElbow",3);
  35. pbone->start_arc_y = -90;
  36. pbone->end_arc_y = 90;
  37. pbone->start_arc_z = 90;
  38. pbone->end_arc_z = -60.0;
  39. pbone->CID = 7;
  40. bonevec.push_back (*pbone);
  41. pbone = new bone  (6,"lElbow",4);
  42. pbone->start_arc_y = -90;
  43. pbone->end_arc_y = 90;
  44. pbone->start_arc_z = -90;
  45. pbone->end_arc_z = 60.0;
  46. pbone->LengthRatio = 0.15;
  47. pbone->CID = 8;
  48. bonevec.push_back (*pbone);
  49. pbone = new bone (7,"rWrist",5);
  50. bonevec.push_back (*pbone);
  51. pbone = new bone (8,"lWrist",6);
  52. bonevec.push_back (*pbone);
  53. bonevec.push_back (bone (9,"Waist",1));
  54. pbone = new bone (10,"rKnee",9);
  55. pbone->CID = 12;
  56. bonevec.push_back (*pbone);
  57. pbone = new bone(11,"lKnee",9);
  58. pbone->CID = 13;
  59. bonevec.push_back (*pbone);
  60. bonevec.push_back (bone (12,"rAnkle",10));
  61. bonevec.push_back (bone (13,"lAnkle",11));
  62. delete pbone; 
  63. pbone=NULL;
  64. pre_ske=NULL;
  65. //pgl = m_OpenGL;
  66. //pgl->Init();
  67. }
  68. skelecton::~skelecton()
  69. {
  70.   //这里释放出错,需要再次检查是否有循环引用
  71. /*
  72. if(pre_ske!=NULL) 
  73. {
  74. delete pre_ske;
  75. pre_ske = NULL;
  76. }
  77. if(pgl!=NULL) 
  78. {
  79. delete pgl;
  80. pgl = NULL;
  81. }
  82. */
  83. bonevec.empty(); 
  84. }
  85. int skelecton::draw2D(CvArr* motion_track_img)
  86. {
  87. bone_vector::iterator theIterator;
  88. bone *pbone = 0;
  89. bone *ppbone = 0;
  90.     for (theIterator = bonevec.begin(); theIterator != bonevec.end();
  91.          theIterator++)
  92.     {
  93.   pbone = theIterator;    
  94.   cvCircle( motion_track_img, cvPoint(pbone->x,pbone->y),10, CV_RGB(0,255,0),3, CV_AA, 0 );
  95.   if ( 0 != pbone->PID )  
  96.   {
  97.   ppbone = get_bone_by_ID(pbone->PID); 
  98.   cvLine( motion_track_img, cvPoint(pbone->x,pbone->y),cvPoint(ppbone->x,ppbone->y),CV_RGB(0,255,0),2,CV_AA, 0 );
  99.   }
  100. return 0;
  101. }
  102. bone* skelecton::get_bone_by_name(char *name)
  103. {
  104. bone_vector::iterator theIterator;
  105. bone_vector::iterator theIterator2;
  106. theIterator2  = 0;
  107.     for (theIterator = bonevec.begin(); theIterator != bonevec.end();
  108.          theIterator++)
  109.     {
  110.  if (0 == strncmp(theIterator->name, name , 4 ))
  111.  {
  112.  theIterator2=theIterator;
  113.  break;
  114.  }                                         
  115. return (theIterator2);
  116. }
  117. bone* skelecton::get_bone_by_ID(int ID)
  118. {
  119. return (&bonevec[ID-1]);
  120. }
  121. int skelecton::reset()
  122. {
  123. bone_vector::iterator theIterator;
  124. bone *pbone = 0;
  125.     for (theIterator = bonevec.begin(); theIterator != bonevec.end();
  126.          theIterator++)
  127.     {
  128.   pbone = theIterator;    
  129.   pbone->x =0 ;
  130.   pbone->y =0 ;
  131.   pbone->is_marked = 0;
  132.  
  133. return 0;
  134. }
  135. int skelecton::draw3D(CvArr *motion_track_img)
  136. {
  137. //2d坐标转化为3d坐标
  138. bone_vector::iterator theIterator;
  139. bone *pbone = 0;
  140. bone *ppbone = 0;
  141. ppbone = get_bone_by_name("head"); 
  142. ppbone->r_z =0;  //初始化head的坐标为0
  143. ppbone->r_x=ppbone->x - coordinator_X;
  144. ppbone->r_y=ppbone->y - coordinator_Y;
  145. CvSize ImageSize; 
  146. ImageSize = cvGetSize(motion_track_img);
  147. coordinator_X = (int)ImageSize.width/2;
  148. coordinator_Y = (int)ImageSize.height/2;
  149. CalcBonePosition();
  150. //绘制3d坐标系
  151. if(ske_pause) arc_y+=5;
  152. const double pi = 3.1415926535;
  153. double cosx = cos(arc_y/90*pi);
  154. double sinx = sin(arc_y/90*pi);
  155. double cosx_z = cos(arc_z/90*pi);
  156. double sinx_z = sin(arc_z/90*pi);
  157. const float ZX[] = { 1, 0, 0, 0,
  158. 0,cosx,sinx,0,
  159. 0,-sinx,cosx,0,
  160. 0,0,0,1
  161. };
  162. const float ZY[] = { cosx,0,sinx,0,
  163.  0,1,0,0,
  164. -sinx,0,cosx,0,
  165. 0,0,0,1
  166. };
  167. const float ZZ[] = { cosx_z,sinx_z, 0, 0,
  168. -sinx_z,cosx_z,0,0,
  169. 0,0,1,0,
  170. 0,0,0,1
  171. };
  172. const float Zoom[] = { 
  173. 1,0,0,0,
  174. 0,1,0,0,
  175. 0,0,1,0,
  176. coordinator_X,coordinator_Y,coordinator_X,1
  177. };  //缩放比率,并且平移100
  178. CvMat* RotateMatrix = cvCreateMat( 4, 4, CV_32FC1 ); //旋转矩阵
  179. memcpy( RotateMatrix->data.fl, ZY, sizeof(ZY));      
  180. CvMat* tempMatrix = cvCreateMat( 4, 4, CV_32FC1 );
  181. memcpy( tempMatrix->data.fl, ZZ, sizeof(ZZ));
  182. cvMatMul( RotateMatrix, tempMatrix, RotateMatrix);
  183. memcpy( tempMatrix->data.fl, Zoom, sizeof(Zoom));
  184. cvMatMul( RotateMatrix, tempMatrix, RotateMatrix);  
  185. CvMat* PointVector = cvCreateMat( 1, 4, CV_32FC1 ); //点矢量矩阵
  186. float pt[] = { 0,0, 0, 1};
  187. int ox,oy=0; //原点
  188. memcpy( PointVector->data.fl, pt, sizeof(pt));
  189. cvMatMul(PointVector,RotateMatrix,PointVector);
  190. ox = PointVector->data.fl[0];
  191. oy = PointVector->data.fl[1];
  192. pt[0]=300 ;
  193. pt[1]=0 ;
  194. pt[2]=0;
  195. memcpy( PointVector->data.fl, pt, sizeof(pt));
  196. cvMatMul(PointVector,RotateMatrix,PointVector);
  197. cvLine( motion_track_img, cvPoint(ox,oy),cvPoint(PointVector->data.fl[0],PointVector->data.fl[1]),CV_RGB(255,255,255),2,CV_AA, 0 );
  198. //printf( "PointVector->data.fl[0,1]: %f,%f n",PointVector->data.fl[0],PointVector->data.fl[1]);
  199. pt[0]=0 ;
  200. pt[1]=300 ;
  201. pt[2]=0;
  202. memcpy( PointVector->data.fl, pt, sizeof(pt));
  203. cvMatMul(PointVector,RotateMatrix,PointVector);
  204. cvLine( motion_track_img, cvPoint(ox,oy),cvPoint(PointVector->data.fl[0],PointVector->data.fl[1]),CV_RGB(0,255,255),2,CV_AA, 0 );
  205. //printf( "PointVector->data.fl[0,1]: %f,%f n",PointVector->data.fl[0],PointVector->data.fl[1]);
  206. pt[0]=0 ;
  207. pt[1]=0 ;
  208. pt[2]=300;
  209. memcpy( PointVector->data.fl, pt, sizeof(pt));
  210. cvMatMul(PointVector,RotateMatrix,PointVector);
  211. cvLine( motion_track_img, cvPoint(ox,oy),cvPoint(PointVector->data.fl[0],PointVector->data.fl[1]),CV_RGB(255,255,0),2,CV_AA, 0 );
  212. //printf( "PointVector->data.fl[0,1]: %f,%f n",PointVector->data.fl[0],PointVector->data.fl[1]);
  213.     for (theIterator = bonevec.begin(); theIterator != bonevec.end();
  214.          theIterator++)
  215.     {
  216.   pbone = theIterator;
  217.   
  218. pt[0]=pbone->r_x ;
  219. pt[1]=pbone->r_y ;
  220. pt[2]=pbone->r_z ;
  221. memcpy( PointVector->data.fl, pt, sizeof(pt));
  222. cvMatMul(PointVector,RotateMatrix,PointVector);
  223. pbone->rotated_X = PointVector->data.fl[0];
  224. pbone->rotated_Y = PointVector->data.fl[1];
  225. if(pbone->is_marked==0)  continue; //未标记则不画
  226. /*
  227. printf( "%s,r_x,r_y,r_z: %d,%d,%d n",pbone->name,pbone->r_x,pbone->r_y,pbone->r_z);
  228. printf( "rotated_X,Y: %d,%d n",pbone->rotated_X,pbone->rotated_Y);
  229. printf( "---------------------------------------------------n");
  230. */
  231. cvCircle( motion_track_img, cvPoint(pbone->rotated_X,pbone->rotated_Y),5, CV_RGB(0,255,0),2, CV_AA, 0 );
  232.   if ( 0 != pbone->PID )  
  233.   {
  234.   ppbone = get_bone_by_ID(pbone->PID); 
  235.   cvLine( motion_track_img, cvPoint(pbone->rotated_X,pbone->rotated_Y),cvPoint(ppbone->rotated_X,ppbone->rotated_Y),CV_RGB(0,255,0),2,CV_AA, 0 );
  236.   
  237.   }
  238. pgl->display();
  239.     return 0;
  240. }
  241. //假设pin hole模型
  242. int skelecton::CalcBoneRealWorldPosition(char *pname, char *ppName,double LengthRatio)
  243. {
  244. bone *ppbone = 0;
  245. bone *pbone = 0;
  246. int cx0,cy0=0; //校正后的坐标
  247. int cx,cy=0; //校正后的坐标
  248. double A,B,C,det,sqdet,x1,x2=0;
  249. ppbone = get_bone_by_name(pname); 
  250. pbone = get_bone_by_name(ppName); 
  251. cx0= ppbone->r_x;
  252. cy0= ppbone->r_y;
  253. cx= pbone->x - coordinator_X ;
  254. cy= pbone->y - coordinator_Y ;
  255. //'求解二元一次方程
  256. A = pow(cx/f,2)  + pow(cy/f,2) + 1;
  257. B = -2*(cx/f)*ppbone ->r_x -2*(cy/f)*ppbone ->r_y - 2*ppbone->r_z;
  258. C = pow(ppbone->r_x,2) + pow(ppbone->r_y,2) + pow(ppbone->r_z,2) - pow(LengthRatio*StardardLength,2);
  259. //'B^2-4AC
  260. det = pow(B,2) - 4*A*C;
  261. //'det>0 两个解
  262. if (det>MaxMinZero)
  263. {
  264. //需要舍弃一个无意义的解
  265. sqdet = sqrt(det);
  266. x1=(-B+sqdet)/(2*A);
  267. x2=(-B-sqdet)/(2*A);
  268. }
  269. //'det==0 单解
  270. else if (det<MaxMinZero && det>0)
  271. {
  272. x1=x2=(-B)/(2*A);
  273. //'det<0 无解
  274. else if (det<0)
  275. {
  276. //需要再次探索
  277. x1=x2=0;
  278. }
  279. pbone->r_z =x1;
  280. pbone ->r_x = pbone->x * pbone->r_z / f;
  281. pbone ->r_y = pbone->y * pbone->r_z / f;
  282. /*
  283. printf( "A: %f n",A);
  284. printf( "B: %f n",B);
  285. printf( "C: %f n",C);
  286. */
  287. return 0;
  288. }
  289. //假设平行光模型
  290. int skelecton::CalcBoneRealWorldPosition_parallel(char *pname, char *ppName)
  291. {
  292. bone *ppbone = 0;
  293. bone *pbone = 0;
  294. int cx0,cy0=0; //校正后的坐标
  295. ppbone = get_bone_by_name(pname); 
  296. pbone = get_bone_by_name(ppName); 
  297. if(pbone!=NULL && pbone->is_marked)
  298. {
  299. cx0= ppbone->x - coordinator_X ;
  300. cy0= ppbone->y - coordinator_Y ;
  301. ppbone ->r_x = cx0;
  302. ppbone ->r_y = cy0;
  303. double A,B,C,det,sqdet,x1,x2=0;
  304. int cx,cy=0; //校正后的坐标
  305. cx= pbone->x - coordinator_X ;
  306. cy= pbone->y - coordinator_Y ;
  307. //'求解二元一次方程
  308. A = 1;
  309. B = - 2*ppbone->r_z;
  310. C = pow(cx-cx0,2) + pow(cy-cy0,2) + pow(ppbone->r_z,2) - pow(pbone->LengthRatio*StardardLength,2);
  311. //'B^2-4ACy
  312. det = pow(B,2) - 4*A*C;
  313. //'det>0 两个解
  314. if (det>MaxMinZero)
  315. {
  316. //需要舍弃一个无意义的解
  317. sqdet = sqrt(det);
  318. x1=(-B+sqdet)/(2*A);
  319. x2=(-B-sqdet)/(2*A);
  320. x1=get_porper_Z(x1,x2,pbone);
  321. }
  322. //'det==0 单解
  323. else if (det<MaxMinZero && det>0)
  324. {
  325. x1=x2=(-B)/(2*A);
  326. //'det<0 无解
  327. else if (det<0)
  328. {
  329. //需要再次探索
  330. x1=x2=0;
  331. }
  332. pbone->r_z =x1;
  333. pbone ->r_x = cx ;
  334. pbone ->r_y = cy ;
  335. /*
  336. printf( "A: %f n",A);
  337. printf( "B: %f n",B);
  338. printf( "C: %f n",C);
  339. */
  340. }
  341. return 0;
  342. }
  343. void skelecton::CorrectPosition(int ID,CvPoint2D32f &pt,kalman &bone_kalman,const CvArr* grey)
  344. {
  345. /*
  346. 一些假设:1。neck为支点不动,
  347.   2。支点坐标轴不偏斜,始终y向上,x向左,z向外,即人体运动垂直与摄像位置,
  348.   没有明显的侧身运动等。躯干运动不受限制。
  349.   head: L*-sinx2 < r_x < L*sinx1 ,   x^2 + y^2 <= L^2 ; 
  350.   shoulder: shoulder.x  <= neck.x + L ;
  351.   eblow: x^2 + y^2 <= L^2 ;
  352.   rWrist: x^2 + y^2 <= L^2 ; 
  353.   waist: waist.y = neck.y + L
  354.   keen:  x^2 + y^2 <= L^2 ; x<0;
  355.   ankle: x^2 + y^2 <= L^2 ;
  356. */
  357. //检查坐标,将经过跟踪后的2D坐标,代入表达式
  358. //如果位于人体运动范围内
  359. //
  360. //如果超出人体运动范围内(如丢掉特征点,自遮挡),开始利用kalman滤波,
  361. //如果kalman滤波位于人体运动范围内,以kalman预测的点周围寻找新的特征点
  362. //如果kalman滤波超出人体运动范围内,按照线性插值给一个特征点
  363. bone *pbone;
  364. bone *ppbone;
  365. bool is_inarea=true;
  366. CvPoint2D32f predict_point;
  367. double bone_length = 0; //对应骨架的长度
  368. pbone = get_bone_by_ID (ID);
  369. pbone->is_marked =1;
  370. double x,y,x0,y0;
  371. x=pt.x;
  372. y=pt.y;
  373. if(0!=pbone->PID)
  374. {
  375. bone_length = (pbone->LengthRatio * (1+StardardLengthNoiseRatio)) * StardardLength;
  376. ppbone = get_bone_by_ID(pbone->PID); 
  377. x0=ppbone->x;
  378. y0=ppbone->y;
  379. if(pow(x-x0,2) + pow(y-y0,2) > pow(bone_length,2)) 
  380. is_inarea = false;
  381. }
  382. //printf("before  : %f %f n",x,y); 
  383. predict_point = bone_kalman.get_predict(x,y);
  384. //printf("predict : %f %f n",predict_point.x,predict_point.y); 
  385. if(is_inarea) 
  386. {
  387. //左肩右肩,脖子,腰部,加刚性三角形约束
  388. }
  389. else
  390. {
  391. if(pow(predict_point.x-x0,2) + pow(predict_point.y-y0,2) > pow(bone_length,2)) 
  392. {
  393. //预测点也不在刚体约束内,则宣布特征点丢失
  394. //特征点丢失,利用运动连续性,根据上五帧的情况,按照匀速线性插值,预测一个点
  395. //to do list
  396. if (pre_ske!=NULL)
  397. {
  398. bone* pre_pbone =NULL;
  399. //pre_pbone = pre_ske->get_bone_by_ID (pbone->ID);
  400. //pt.x = pre_pbone->r_x;
  401. //pt.y = pre_pbone->r_y;
  402. }
  403. }
  404. else
  405. {
  406. //预测点在刚体约束内,添加在指定范围寻找特征点
  407. //to do list
  408. pt.x = predict_point.x;
  409. pt.y = predict_point.y;
  410. }
  411. /*
  412. cvFindCornerSubPix( grey, &pt, 1,
  413.         cvSize(10,10), cvSize(-1,-1),
  414.     cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
  415. */
  416. }
  417. pbone->x = (int)pt.x;
  418. pbone->y = (int)pt.y;
  419. }
  420. void skelecton::CalcLengthRatio(int ID,CvPoint2D32f pt)
  421. {
  422. bone *pbone;
  423. bone *ppbone;
  424. double bone_length;
  425. double x,y,x0,y0;
  426. pbone = get_bone_by_ID(ID); 
  427. if(pbone!=NULL) 
  428. {
  429. if(0!=pbone->PID)
  430. {
  431. x=pt.x;
  432. y=pt.y;
  433. ppbone = get_bone_by_ID(pbone->PID); 
  434. x0=ppbone->x;
  435. y0=ppbone->y;
  436. bone_length = sqrt(pow(x-x0,2) + pow(y-y0,2));
  437. pbone->LengthRatio = bone_length/StardardLength ;
  438. }
  439. else
  440. pbone->LengthRatio = 0;
  441. pbone->x = (int)pt.x;
  442. pbone->y = (int)pt.y;
  443. }
  444. }
  445. //根据人体模型来消除z坐标的二义性
  446. int skelecton::get_porper_Z(int x1, int x2, bone *pbone)
  447. {
  448. //return x2;
  449. //利用上一状态估计当前状态,取离上一状态最近的点
  450. bone *pre_pbone=NULL;
  451. int result = 0;
  452. int pre_z = 0 ;
  453. if (pre_ske!=NULL)
  454. {
  455. pre_pbone = pre_ske->get_bone_by_ID (pbone->ID);
  456. pre_z = pre_pbone->r_z ;
  457. if(abs(pre_z-x1)>abs(pre_z-x2)) 
  458. result= x2;
  459. else
  460. result= x1;
  461. }
  462. result= x1;
  463. //肢体本身的二义性
  464. if(pre_pbone!=NULL)
  465. {
  466. switch(pbone->ID)
  467. {
  468. case 5: //rElbow 胳膊肘不能向外拐
  469. result = check_porper_Z(x1,x2,pre_pbone,false);
  470. break;
  471. case 6: //lElbow 胳膊肘不能向外拐
  472. result = check_porper_Z(x1,x2,pre_pbone,true);
  473. break;
  474. case 10: //rKnee 膝盖不能内弯
  475. result = check_porper_Z(x1,x2,pre_pbone,false);
  476. break;
  477. case 11: //lKnee 膝盖不能内弯
  478. result = check_porper_Z(x1,x2,pre_pbone,true);
  479. break;
  480. }
  481. }
  482. return result;
  483. }
  484. void skelecton::CalcBonePosition()
  485. {
  486. CalcBoneRealWorldPosition_parallel("neck","head");
  487. CalcBoneRealWorldPosition_parallel("neck","rShoulder");
  488. CalcBoneRealWorldPosition_parallel("neck","lShoulder");
  489. CalcBoneRealWorldPosition_parallel("rShoulder","rElbow");
  490. CalcBoneRealWorldPosition_parallel("lShoulder","lElbow");
  491. CalcBoneRealWorldPosition_parallel("rElbow","rWrist");
  492. CalcBoneRealWorldPosition_parallel("lElbow","lWrist");
  493. CalcBoneRealWorldPosition_parallel("neck","Waist");
  494. CalcBoneRealWorldPosition_parallel("Waist","rKnee");
  495. CalcBoneRealWorldPosition_parallel("Waist","lKnee");
  496. CalcBoneRealWorldPosition_parallel("rKnee","rAnkle");
  497. CalcBoneRealWorldPosition_parallel("lKnee","lAnkle");
  498. }
  499. void skelecton::set_previous_skelecton(skelecton *pre_skelecton)
  500. {
  501. pre_ske = pre_skelecton;
  502. }
  503. //将坐标旋转到肩膀与手腕的向量上,求得到点的值是否在向量上方
  504. int skelecton::check_porper_Z(int x1, int x2, bone *pbone,bool IsLeft)
  505. {
  506. int xx0,zz0,xx1,xx2,zz1,zz2,result=0;
  507. float sinx,cosx,radiolen;
  508. float zz,zzz;
  509. bone *ppbone,*cpbone;
  510. ppbone = pre_ske->get_bone_by_ID (pbone->PID);
  511. cpbone = pre_ske->get_bone_by_ID (pbone->CID);
  512. if (ppbone!=NULL && cpbone!=NULL)
  513. {
  514. xx1 = ppbone->r_x;
  515. zz1 = ppbone->r_z;
  516. xx2 = cpbone->r_x;
  517. zz2 = cpbone->r_z;
  518. xx0=xx2-xx1;
  519. zz0=zz2-zz1;
  520. radiolen = sqrt(xx0*xx0 + zz0*zz0);
  521. sinx=xx0/radiolen;
  522. cosx=zz0/radiolen;
  523. zz=(x1-zz1)*sinx+(x1-zz1)*cosx;  
  524. zzz=(x2-zz1)*sinx+(x2-zz1)*cosx;
  525. if(IsLeft)
  526. {
  527. if(zz<0) 
  528. result = x1;
  529. if(zzz<0)
  530. result = x2;
  531. }
  532. else
  533. {
  534. if(zz>0) 
  535. result = x1;
  536. if(zzz>0)
  537. result = x2;
  538. }
  539. }
  540. return result;
  541. }
  542. int skelecton::drawOpenGL3D(CvArr *motion_track_img)
  543. {
  544. bone_vector::iterator theIterator;
  545. bone *pbone = 0;
  546. bone *ppbone = 0;
  547. Vector3f  vt1,vt2;
  548. ppbone = get_bone_by_name("neck"); 
  549. ppbone->r_z =0;  //初始化head的坐标为0
  550. CvSize ImageSize; 
  551. ImageSize = cvGetSize(motion_track_img);
  552. coordinator_X = (int)ImageSize.width/2;
  553. coordinator_Y = (int)ImageSize.height/2;
  554. CalcBonePosition();
  555. assert(pgl!=NULL);
  556. if(pgl!=NULL)  pgl->clear();
  557.     for (theIterator = bonevec.begin(); theIterator != bonevec.end();
  558.          theIterator++)
  559.     {
  560.   pbone = theIterator;
  561. if(pbone->is_marked==0)  continue; //未标记则不画
  562.   if ( 0 != pbone->PID )  
  563.   {
  564.   ppbone = get_bone_by_ID(pbone->PID);    
  565.   vt1.x = pbone->r_x;
  566.   vt1.y = pbone->r_y;
  567.   vt1.z = pbone->r_z;
  568.   vt2.x = ppbone->r_x;
  569.   vt2.y = ppbone->r_y;
  570.   vt2.z = ppbone->r_z;
  571.   if(pgl!=NULL)  pgl->draw2point(vt1,vt2);   
  572.   }
  573. if(pgl!=NULL) 
  574. {
  575. //pgl->Correct_3D_Layout(vt1,vt2);
  576. pgl->display();
  577. }
  578.     return 0;
  579. }
  580. void skelecton::view_up()
  581. {
  582. if(pgl!=NULL) 
  583.  pgl->x_arc = (pgl ->x_arc + 5) % 360;
  584. }
  585. void skelecton::view_down()
  586. {
  587. if(pgl!=NULL) 
  588. pgl->x_arc = (pgl ->x_arc - 5) % 360;
  589. }
  590. void skelecton::view_left()
  591. {
  592. if(pgl!=NULL) 
  593. pgl->y_arc = (pgl ->y_arc + 5) % 360;
  594. }
  595. void skelecton::view_right()
  596. {
  597. if(pgl!=NULL) 
  598. pgl->y_arc = (pgl ->y_arc - 5) % 360;
  599. }