PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/journal/OpenCV_AAM/VO_ASM.cpp

http://shaobohou-matlabcodes.googlecode.com/
C++ | 2013 lines | 1258 code | 356 blank | 399 comment | 163 complexity | 406e44c23ed08a380e15ba22a427ae32 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. #include <fstream>
  2. #include <set>
  3. #include <boost/filesystem.hpp>
  4. #include "VO_ASM.h"
  5. using namespace std;
  6. /** Default Constructor */
  7. VO_ASM::VO_ASM()
  8. {
  9. this->init();
  10. }
  11. /** Initialization */
  12. void VO_ASM::init()
  13. {
  14. this->m_CVMShapes = NULL;
  15. this->m_CVMAlignedShapes = NULL;
  16. this->m_CVMAlignedShapesProject2Truncated = NULL;
  17. this->m_CVMTruancatedAlignedShapesMean = NULL;
  18. this->m_CVMTruancatedAlignedShapesSD = NULL;
  19. this->m_CVMAlignedShapesMean = NULL;
  20. this->m_CVMAlignedShapesSD = NULL;
  21. this->m_CVMAlignedShapesEigenVectors = NULL;
  22. this->m_CVMAlignedShapesEigenValues = NULL;
  23. this->m_CVMTruncatedAlignedShapesEigenVectors = NULL;
  24. this->m_CVMTruncatedAlignedShapesEigenValues = NULL;
  25. this->m_CVMSimilarityTransformMatrix = NULL;
  26. this->m_CVMPoints = NULL;
  27. this->m_CVMConvexHull = NULL;
  28. this->m_iNbOfSamples = 0;
  29. this->m_iNbOfPoints = 0;
  30. this->m_iNbOfShapes = 0;
  31. this->m_iNbOfTruncatedShapes = 0;
  32. this->m_iNbOfEigenShapesAtMost = 0;
  33. this->m_fAverageShapeSize = 0.0f;
  34. this->m_iNbOfPointsOnConvexHull = 0;
  35. this->m_iNbOfEdges = 0;
  36. this->m_iNbOfTriangles = 0;
  37. this->m_fTruncatedPercent_Shape = 0.95f;
  38. }
  39. /** Destructor */
  40. VO_ASM::~VO_ASM()
  41. {
  42. if (this->m_CVMShapes) cvReleaseMat (&this->m_CVMShapes);
  43. if (this->m_CVMAlignedShapes) cvReleaseMat (&this->m_CVMAlignedShapes);
  44. if (this->m_CVMAlignedShapesProject2Truncated) cvReleaseMat (&this->m_CVMAlignedShapesProject2Truncated);
  45. if (this->m_CVMTruancatedAlignedShapesMean) cvReleaseMat (&this->m_CVMTruancatedAlignedShapesMean);
  46. if (this->m_CVMTruancatedAlignedShapesSD) cvReleaseMat (&this->m_CVMTruancatedAlignedShapesSD);
  47. if (this->m_CVMAlignedShapesMean) cvReleaseMat (&this->m_CVMAlignedShapesMean);
  48. if (this->m_CVMAlignedShapesSD) cvReleaseMat (&this->m_CVMAlignedShapesSD);
  49. if (this->m_CVMAlignedShapesEigenVectors) cvReleaseMat (&this->m_CVMAlignedShapesEigenVectors);
  50. if (this->m_CVMAlignedShapesEigenValues) cvReleaseMat (&this->m_CVMAlignedShapesEigenValues);
  51. if (this->m_CVMTruncatedAlignedShapesEigenVectors) cvReleaseMat (&this->m_CVMTruncatedAlignedShapesEigenVectors);
  52. if (this->m_CVMTruncatedAlignedShapesEigenValues) cvReleaseMat (&this->m_CVMTruncatedAlignedShapesEigenValues);
  53. if (this->m_CVMSimilarityTransformMatrix) cvReleaseMat (&this->m_CVMSimilarityTransformMatrix);
  54. if (this->m_CVMPoints) cvReleaseMat (&this->m_CVMPoints);
  55. if (this->m_CVMConvexHull) cvReleaseMat (&this->m_CVMConvexHull);
  56. }
  57. /**
  58. @author JIA Pei
  59. @version 2008-03-04
  60. @brief Align all shapes before PCA
  61. @param vShapes Input - all shapes before alignment
  62. @param alignedShapes Output - all shapes after alignment
  63. @return float return average shape size of all shapes
  64. @note make sure all alignedShapes, meanshape as well, are of size "1" !!!
  65. */
  66. float VO_ASM::VO_AlignAllShapes(const vector<VO_AAMShape2D>& vShapes, vector<VO_AAMShape2D>& alignedShapes)
  67. {
  68. unsigned int numberOfSamples = vShapes.size();
  69. unsigned int numberOfPoints = vShapes[0].GetSize();
  70. float averageShapeSize = 0.0f;
  71. alignedShapes = vShapes;
  72. VO_AAMShape2D meanAlignedShape;
  73. meanAlignedShape.SetSize(numberOfPoints);
  74. // Instead of Normalising all shapes to unit size, which makes some shape loose their actual scale, we compute the average shape norm first and then normalise all shapes based on this average shape size -- Salil 09/01/10
  75. for(unsigned int i = 0; i < numberOfSamples; i++)
  76. {
  77. averageShapeSize += alignedShapes[i].NormalizeNoScale(); // move to origin and scale to unit size (scale to unit size is not desirable because the relative scale of the shape is lost. Thus, it has been removed -- Salil Deena 11/01/10)
  78. }
  79. averageShapeSize /= numberOfSamples; // Why this is the average shape size without minor errors?
  80. // Because later do-while loop doesn't change the normalized shape size
  81. for(unsigned int i = 0; i < numberOfSamples; i++)
  82. {
  83. alignedShapes[i].Scale(1/averageShapeSize); // move to origin and scale to unit size
  84. }
  85. VO_ASM::VO_CalcMeanShape( alignedShapes, meanAlignedShape );
  86. meanAlignedShape.SetHostImage("");
  87. // do a number of alignment iterations until the mean shape estimate is stable
  88. float diff, diff_max = FLT_EPSILON;
  89. int max_iter = EPOCH, iter = 1;
  90. VO_AAMShape2D tempMeanShape;
  91. float theta;
  92. CvMat * rot = cvCreateMat (1, numberOfSamples, CV_32FC1);
  93. do
  94. {
  95. // normalize and align all other shapes to the mean shape estimate
  96. for(unsigned int i=0;i < numberOfSamples;i++)
  97. {
  98. // cout << "Aligning shape " << i + 1 << endl;
  99. // align the i-th shape to the estimate of the mean shape
  100. alignedShapes[i].AlignToNoScale( meanAlignedShape, &theta );
  101. CV_MAT_ELEM( *rot, float, 0, i ) = theta; // record the rotation
  102. // Rotate the shape so as to make the 0th and 10th shape to form a horizontal line -- Need to parameterise the indices later -- Salil 11/01/10
  103. alignedShapes[i].AlignPointsHorizontal(0,14);
  104. // We no longer need that since the align does not take shape into account -- Salil 09/10/09
  105. // re-scale to unit size to avoid the so-called 'shrinking effect'
  106. // i.e. the alignment error goes towards zero, when the shapes are downscaled
  107. //alignedShapes[i].Scale( 1.0f/alignedShapes[i].GetShapeNorm () );
  108. //alignedShapes[i].Scale( 1.0f/averageShapeSize );
  109. }
  110. tempMeanShape = meanAlignedShape;
  111. // estimate the new mean shape
  112. VO_ASM::VO_CalcMeanShape( alignedShapes, meanAlignedShape );
  113. // if first iteration, adjust the orientation of the mean shape, so the rotation of the training set to the mean shape is
  114. // -- on average -- zero or put more clearly: "make the meanshape have a mean orientation"
  115. if (iter==1)
  116. {
  117. CvScalar rotMean = cvAvg( rot );
  118. meanAlignedShape.Rotate ( (float) ( -rotMean.val[0] ) );
  119. }
  120. diff = (tempMeanShape-meanAlignedShape).GetShapeSize();
  121. ++iter;
  122. }while( fabs(diff)/meanAlignedShape.GetShapeSize() > diff_max && iter < max_iter );
  123. cvReleaseMat (&rot);
  124. return averageShapeSize;
  125. }
  126. /**
  127. @author JIA Pei
  128. @version 2008-03-04
  129. @brief Rescale the alignedshapes so that meanshape's 2-norm could be "1"
  130. @param meanAlignedShape Input - meanalignedshape that all alignedshapes should rescale to
  131. @param alignedShapes Input and Output - aligned shape and aligned rescaled shape
  132. */
  133. float VO_ASM::VO_RescaleAllAlignedShapes(const VO_AAMShape2D& meanAlignedShape,
  134. vector<VO_AAMShape2D>& alignedShapes)
  135. {
  136. unsigned int NbOfSamples = alignedShapes.size();
  137. float average_ts = 0.0f;
  138. // Explained by JIA Pei. 2008-03-04. scale back so that the mean shape size is equal to 1.0
  139. for(unsigned int i = 0; i < NbOfSamples; i++)
  140. {
  141. float ts = sqrt (alignedShapes[i]*meanAlignedShape);
  142. //cout << "ts = " << ts << endl;
  143. average_ts += ts;
  144. alignedShapes[i].Scale( 1.0f/ts );
  145. }
  146. return average_ts / NbOfSamples;
  147. }
  148. /**
  149. @author JIA Pei
  150. @version 2008-03-24
  151. @brief Rescale the alignedShape to the already trained meanAligneShape
  152. @param meanAlignedShape Input - meanalignedshape that all alignedshapes should rescale to
  153. @param alignedShape Input and Output - aligned shape and aligned rescaled shape
  154. */
  155. void VO_ASM::VO_RescaleOneAlignedShape(const VO_AAMShape2D& meanAlignedShape, VO_AAMShape2D& alignedShape)
  156. {
  157. float ts = sqrt (alignedShape*meanAlignedShape);
  158. alignedShape.Scale( 1.0f/ts );
  159. }
  160. /**
  161. @author JIA Pei
  162. @version 2008-03-04
  163. @brief Calculate mean shape
  164. @param vShapes Input - all shapes
  165. @param meanShape Output - mean shape
  166. */
  167. void VO_ASM::VO_CalcMeanShape(const vector<VO_AAMShape2D>& vShapes, VO_AAMShape2D &meanShape)
  168. {
  169. unsigned int numberOfSamples = vShapes.size();
  170. unsigned int numberOfShapes = vShapes[0].GetSize();
  171. meanShape.SetSize(numberOfShapes);
  172. meanShape = vShapes[0];
  173. meanShape = 0;
  174. for(unsigned int i = 0; i < numberOfSamples; i++)
  175. {
  176. meanShape += vShapes[i];
  177. }
  178. meanShape = meanShape / (float)numberOfSamples;
  179. }
  180. /**
  181. @author JIA Pei
  182. @version 2008-03-04
  183. @brief Judge is point "pt" inside the convex hull "ch"
  184. @param pt Input - the point
  185. @param ch Input - convex hull
  186. @param includingHull Input flag - whether including the boundary
  187. @return bool including or excluding
  188. */
  189. bool VO_ASM::VO_IsPointInConvexHull(CvPoint2D32f pt, const CvMat* ch, bool includingHull)
  190. {
  191. if(!includingHull)
  192. {
  193. if (cvPointPolygonTest( ch, pt, 0 ) > 0.0 )
  194. return true;
  195. }
  196. else
  197. {
  198. if (cvPointPolygonTest( ch, pt, 0 ) >= 0.0)
  199. return true;
  200. }
  201. return false;
  202. }
  203. /**
  204. @author JIA Pei
  205. @version 2008-03-04
  206. @brief Judge whether edge indexed by (ind1+ind2) is already in the vector of "edges"
  207. @param edges edge collection
  208. @param ind1 first index of the edge to be judged
  209. @param ind2 second index of the edge to be judged
  210. @return bool counted or not
  211. */
  212. bool VO_ASM::VO_IsEdgeCounted(const vector<VO_AAMEdge>& edges, int ind1, int ind2)
  213. {
  214. for (unsigned int i = 0; i < edges.size (); i++)
  215. {
  216. if ( ( (edges[i].GetIndex1() == ind1) && (edges[i].GetIndex2() == ind2) )
  217. || ( (edges[i].GetIndex1() == ind2) && (edges[i].GetIndex2() == ind1) ) )
  218. {
  219. return true;
  220. }
  221. }
  222. return false;
  223. }
  224. /**
  225. @author JIA Pei
  226. @version 2008-03-04
  227. @brief Judge whether triangle t is already in the vector of "triangles".
  228. @param triangles triangle collection
  229. @param t triangle to be judged
  230. */
  231. bool VO_ASM::VO_IsTriangleCounted(const vector<VO_AAMTriangle2D> &triangles, const vector<int> t)
  232. {
  233. set<int> tTriangle;
  234. set<int> sTriangle;
  235. for (unsigned int i = 0; i < triangles.size (); i ++)
  236. {
  237. // These two clear() are very important, cannot be displaced by empty().
  238. tTriangle.clear ();
  239. sTriangle.clear ();
  240. for (unsigned int j = 0; j < 3; j++ )
  241. {
  242. tTriangle.insert (triangles[i].GetVertexIndex(j) );
  243. sTriangle.insert (t[j]);
  244. }
  245. if (tTriangle == sTriangle)
  246. {
  247. return false;
  248. }
  249. }
  250. return true;
  251. }
  252. /**
  253. @author JIA Pei
  254. @version 2008-03-04
  255. @brief Build convex hull
  256. @param vertexes Input - the point
  257. @param ch Output - convex hull
  258. @return int number of edges on the convex hull
  259. */
  260. int VO_ASM::VO_BuildConvexHull(const CvMat* vertexes, CvMat* ch)
  261. {
  262. cvConvexHull2(vertexes, ch, CV_CLOCKWISE, 0 );
  263. return ch->cols;
  264. }
  265. /**
  266. @author JIA Pei
  267. @version 2008-03-04
  268. @brief Build AAM Edges
  269. @param vertexes Input - all vertexes/points composing the shape
  270. @param Subdiv Input - sub division which is already computed beforehand
  271. @param outEdges Output - AAM edges
  272. @return int Number of edges
  273. */
  274. int VO_ASM::VO_BuildEdges(const CvMat* vertexes, const CvSubdiv2D* Subdiv, vector<VO_AAMEdge>& outEdges)
  275. {
  276. unsigned int NbOfPoints = vertexes->cols;
  277. CvSeqReader reader;
  278. cvStartReadSeq( (CvSeq*)(Subdiv->edges), &reader, 0 );
  279. for( unsigned int i = 0; i < Subdiv->edges->total; i++ )
  280. {
  281. CvQuadEdge2D* edge = (CvQuadEdge2D*)(reader.ptr);
  282. if( CV_IS_SET_ELEM( edge ))
  283. {
  284. CvPoint2D32f org;
  285. CvPoint2D32f dst;
  286. CvSubdiv2DPoint* org_pt = cvSubdiv2DEdgeOrg((CvSubdiv2DEdge)edge);
  287. CvSubdiv2DPoint* dst_pt = cvSubdiv2DEdgeDst((CvSubdiv2DEdge)edge);
  288. if( org_pt && dst_pt )
  289. {
  290. org = org_pt->pt;
  291. dst = dst_pt->pt;
  292. for (unsigned int j = 0; j < NbOfPoints; j++)
  293. {
  294. // if the current edge convex (org points, not the dst point) is in our point list
  295. if ( (fabs ( org.x - CV_MAT_ELEM( *vertexes, CvPoint2D32f, 0, j ).x ) < FLT_EPSILON )
  296. && ( fabs ( org.y - CV_MAT_ELEM( *vertexes, CvPoint2D32f, 0, j ).y ) < FLT_EPSILON ) )
  297. {
  298. for (unsigned int k = 0; k < NbOfPoints; k++)
  299. {
  300. // With the above org point, we search around for the dst point(s),
  301. // which make org-dst an edge during cvSubdivDelaunay2DInsert()
  302. if ( ( fabs (dst.x - CV_MAT_ELEM( *vertexes, CvPoint2D32f, 0, k ).x ) < FLT_EPSILON )
  303. && ( fabs (dst.y - CV_MAT_ELEM( *vertexes, CvPoint2D32f, 0, k ).y ) < FLT_EPSILON ) )
  304. {
  305. // Already tested, this->m_vAAMEdge is definitely correct!
  306. outEdges.push_back ( VO_AAMEdge(j,k) );
  307. }
  308. }
  309. }
  310. }
  311. }
  312. }
  313. CV_NEXT_SEQ_ELEM( Subdiv->edges->elem_size, reader );
  314. }
  315. return outEdges.size();
  316. }
  317. /**
  318. @author JIA Pei
  319. @version 2008-03-04
  320. @brief Build AAM Triangles
  321. @param edges Input - to build triangles
  322. @return int Number of triangles
  323. */
  324. int VO_ASM::VO_BuildTriangles(const CvMat* vertexes, const vector<VO_AAMEdge> &edges, vector<VO_AAMTriangle2D> &outTriangles)
  325. {
  326. outTriangles.clear();
  327. unsigned int NbOfPoints = vertexes->cols;
  328. for (unsigned int i = 0; i < edges.size (); i++)
  329. {
  330. int ind1 = edges[i].GetIndex1();
  331. int ind2 = edges[i].GetIndex2();
  332. for (unsigned int j = 0; j < NbOfPoints; j++)
  333. {
  334. // At most, there are only 2 triangles that can be added
  335. if( VO_ASM::VO_IsEdgeCounted(edges, ind1, j) && VO_ASM::VO_IsEdgeCounted(edges, ind2, j) )
  336. {
  337. vector<CvPoint2D32f> vVertexes;
  338. vector<int> iVertexes;
  339. vVertexes.resize (3);
  340. iVertexes.resize (3);
  341. vVertexes[0] = CV_MAT_ELEM( *vertexes, CvPoint2D32f, 0, ind1 );
  342. vVertexes[1] = CV_MAT_ELEM( *vertexes, CvPoint2D32f, 0, ind2 );
  343. vVertexes[2] = CV_MAT_ELEM( *vertexes, CvPoint2D32f, 0, j );
  344. iVertexes[0] = ind1;
  345. iVertexes[1] = ind2;
  346. iVertexes[2] = j;
  347. if (VO_ASM::VO_IsTriangleCounted(outTriangles, iVertexes) )
  348. {
  349. outTriangles.push_back (VO_AAMTriangle2D(vVertexes, iVertexes));
  350. }
  351. }
  352. }
  353. }
  354. return outTriangles.size();
  355. }
  356. /**
  357. @author JIA Pei
  358. @version 2008-03-04
  359. @brief Calculation triangulation mesh
  360. For IMM 58 points dataset, 19 edges on the convex hull, 133 inner edges.
  361. Totally, 133+19=152 edges
  362. (133*2+19)/3=95 triangles
  363. */
  364. void VO_ASM::VO_BuildTemplateMesh(const CvMat* vertexes, CvMat* ch, vector<VO_AAMEdge> & edges, vector<VO_AAMTriangle2D> & triangles )
  365. {
  366. unsigned int NbOfPoints = vertexes->cols;
  367. // Build Convex Hull
  368. unsigned int NbOfEdgesOnConvexHull = VO_ASM::VO_BuildConvexHull(vertexes, ch);
  369. //////////////////////////////////////////////////////////////////////////
  370. // Build Delaunay Triangulation Sub Divisions
  371. // Later VO_BuildEdges need DTSubdiv information
  372. CvSubdiv2D* tempCVSubdiv = NULL;
  373. CvRect rect = cvBoundingRect( ch, 0 );
  374. //CvRect rect = { 0, 0, 288, 302 };
  375. CvMemStorage* DelaunayStorage = cvCreateMemStorage(0);
  376. tempCVSubdiv = VO_ASM::init_delaunay( DelaunayStorage, rect );
  377. // cout << "So far so good again 2" << endl;
  378. // cout << "NbOfPoints = " << NbOfPoints << endl;
  379. // By JIA Pei, 2006-09-20. How to release this storage?
  380. //tempCVSubdiv = cvCreateSubdivDelaunay2D( rect, DelaunayStorage );
  381. CvPoint2D32f tempPoint;
  382. //cout << "VO_BuildTemplateMesh" << endl;
  383. for( unsigned int i = 0; i < NbOfPoints; i++ )
  384. {
  385. tempPoint = CV_MAT_ELEM( *vertexes, CvPoint2D32f, 0, i );
  386. cvSubdivDelaunay2DInsert( tempCVSubdiv, CV_MAT_ELEM( *vertexes, CvPoint2D32f, 0, i ));
  387. }
  388. // cout << "So far so good again 3" << endl;
  389. //exit(1);
  390. //////////////////////////////////////////////////////////////////////////
  391. unsigned int NbOfEdges = VO_ASM::VO_BuildEdges(vertexes, tempCVSubdiv, edges);
  392. unsigned int NbOfTriangles = VO_ASM::VO_BuildTriangles (vertexes, edges, triangles);
  393. // How to release CvSubdiv2D* m_CVSubdiv is still a problem.
  394. if (tempCVSubdiv) cvClearSubdivVoronoi2D( tempCVSubdiv );
  395. cvReleaseMemStorage( &DelaunayStorage );
  396. }
  397. /**
  398. Author Salil Deena
  399. Version 17/09/2009
  400. **/
  401. CvSubdiv2D* VO_ASM::init_delaunay( CvMemStorage* storage, CvRect rect )
  402. {
  403. CvSubdiv2D* subdiv;
  404. subdiv = cvCreateSubdiv2D( CV_SEQ_KIND_SUBDIV2D, sizeof(*subdiv),
  405. sizeof(CvSubdiv2DPoint),
  406. sizeof(CvQuadEdge2D),
  407. storage );
  408. cvInitSubdivDelaunay2D( subdiv, rect );
  409. return subdiv;
  410. }
  411. /**
  412. @author JIA Pei
  413. @version 2008-03-04
  414. @brief Calculate Shape Boundary
  415. @param the shape
  416. @return bool
  417. */
  418. CvRect VO_ASM::VO_CalcShapeBoundaryRect(const VO_AAMShape2D& iShape)
  419. {
  420. CvRect rect;
  421. unsigned int NbOfPoints = iShape.GetSize();
  422. CvMat* tempPoints = cvCreateMat (1, NbOfPoints, CV_32FC2);
  423. for (unsigned int i = 0; i < NbOfPoints; i++)
  424. {
  425. CV_MAT_ELEM( *tempPoints, CvPoint2D32f, 0, i ) = iShape.GetPoint(i).GetXY();
  426. }
  427. rect = cvBoundingRect( tempPoints, 1 );
  428. cvReleaseMat(&tempPoints);
  429. return rect;
  430. }
  431. /**
  432. @author JIA Pei
  433. @version 2008-03-04
  434. @brief Is iShape inside img
  435. @return bool
  436. */
  437. bool VO_ASM::VO_IsShapeInsideImage(const VO_AAMShape2D& iShape, const IplImage* img)
  438. {
  439. CvRect rect = VO_ASM::VO_CalcShapeBoundaryRect(iShape);
  440. if ( (rect.x >= 0) && (rect.y >= 0) && ( (rect.x + rect.width) <= img->width )
  441. && ( (rect.y + rect.height) <= img->height ) )
  442. {
  443. return true;
  444. }
  445. else
  446. {
  447. return false;
  448. }
  449. }
  450. /**
  451. @author JIA Pei
  452. @version 2008-03-04
  453. @brief Aligned shape to reference scale shape
  454. @param inShape Input - aligned shape
  455. @param shapeSD Input - shape standard deviation
  456. @param outShape Output - output reference shape
  457. */
  458. void VO_ASM::VO_AlignedShape2ReferenceScale(const VO_AAMShape2D& inShape, float shapeSD, VO_AAMShape2D& outShape)
  459. {
  460. outShape = const_cast<VO_AAMShape2D&> (inShape) * shapeSD;
  461. outShape.Translate( -outShape.MinX(), -outShape.MinY() );
  462. }
  463. /**
  464. @author JIA Pei
  465. @version 2008-03-04
  466. @brief Reference scale texture back to aligned one
  467. @param inShape Input - reference shape
  468. @param shapeSD Input - shape standard deviation
  469. @param outShape Output - output aligned shape
  470. */
  471. void VO_ASM::VO_ReferenceShapeBack2Aligned(const VO_AAMShape2D& inShape, float shapeSD, VO_AAMShape2D& outShape)
  472. {
  473. outShape = inShape;
  474. // scale first
  475. outShape.Scale(1.0f/shapeSD );
  476. // centralize it
  477. float x, y;
  478. outShape.CenterOfGravity( x, y );
  479. outShape.Translate( -x, -y );
  480. // note: no rotation!!!
  481. }
  482. /**
  483. @author JIA Pei
  484. @version 2008-03-20
  485. @brief shape parameters back project to aligned shape
  486. @param inP Input - input shape parameters
  487. @return VO_AAMShape2D - the back projected shape
  488. */
  489. VO_AAMShape2D VO_ASM::VO_SParamBackProjectToAlignedShape(CvMat* inP)
  490. {
  491. CvMat* oShape = cvCreateMat(1, this->m_iNbOfShapes, CV_32FC1);
  492. // P back to shape
  493. cvBackProjectPCA(inP, this->m_CVMAlignedShapesMean, this->m_CVMTruncatedAlignedShapesEigenVectors, oShape);
  494. VO_AAMShape2D res = VO_AAMShape2D::VO_CvMat2AAMShape2D(oShape);
  495. cvReleaseMat(&oShape);
  496. return res;
  497. }
  498. /**
  499. @author JIA Pei
  500. @version 2008-03-04
  501. @brief build ASM
  502. @param vShapes Input - all input shapes
  503. @param TPShape Input - truncated percentage for shape model
  504. */
  505. void VO_ASM::VO_BuildASM(const vector<VO_AAMShape2D> &vShapes, float TPShape)
  506. {
  507. this->m_iNbOfSamples = vShapes.size();
  508. this->m_iNbOfPoints = vShapes[0].GetSize();
  509. this->m_iNbOfShapes = this->m_iNbOfPoints * 2;
  510. this->m_fTruncatedPercent_Shape = TPShape;
  511. this->m_vAAMShapes = vShapes;
  512. //cout << "So far so good" << endl;
  513. // Calculate meanshape before alignment
  514. VO_ASM::VO_CalcMeanShape(this->m_vAAMShapes, this->m_VOAAMMeanShape);
  515. // Align all shapes
  516. this->m_fAverageShapeSize = VO_ASM::VO_AlignAllShapes(this->m_vAAMShapes, this->m_vAAMAlignedShapes);
  517. VO_ASM::VO_CalcMeanShape(this->m_vAAMAlignedShapes, this->m_VOAAMMeanAlignedShapePrior);
  518. //this->m_fAverageShapeScalingFactor = VO_ASM::VO_RescaleAllAlignedShapes(this->m_VOAAMMeanAlignedShapePrior,this->m_vAAMAlignedShapes);
  519. // Calculate meanshape, now, bear in mind that all alignedshapes and the meanshape are all of size "1"
  520. VO_ASM::VO_CalcMeanShape(this->m_vAAMAlignedShapes, this->m_VOAAMMeanAlignedShapePost); // actually, "1" already
  521. this->m_VOAAMMeanAlignedShapePost.Scale( 1.0f/this->m_VOAAMMeanAlignedShapePost.GetShapeNorm () ); // "1" again
  522. this->m_CVMShapes = cvCreateMat(this->m_iNbOfSamples, this->m_iNbOfShapes, CV_32FC1);
  523. this->m_CVMAlignedShapes = cvCreateMat(this->m_iNbOfSamples, this->m_iNbOfShapes, CV_32FC1);
  524. // VO_AAMShape2D2CvMat() is not available here. For a vector of VO_AAMShape2D
  525. for(unsigned int i=0; i < this->m_iNbOfSamples; i++)
  526. {
  527. for(unsigned int j = 0; j < this->m_iNbOfPoints; j++)
  528. {
  529. CV_MAT_ELEM( *this->m_CVMShapes, float, i, 2*j ) = this->m_vAAMShapes[i].GetPoint(j).GetXY().x;
  530. CV_MAT_ELEM( *this->m_CVMShapes, float, i, 2*j+1 ) = this->m_vAAMShapes[i].GetPoint(j).GetXY().y;
  531. CV_MAT_ELEM( *this->m_CVMAlignedShapes, float, i, 2*j ) = this->m_vAAMAlignedShapes[i].GetPoint(j).GetXY().x;
  532. CV_MAT_ELEM( *this->m_CVMAlignedShapes, float, i, 2*j+1 ) = this->m_vAAMAlignedShapes[i].GetPoint(j).GetXY().y;
  533. }
  534. }
  535. this->m_iNbOfEigenShapesAtMost = MIN(this->m_iNbOfSamples, this->m_iNbOfShapes);
  536. this->m_CVMAlignedShapesEigenValues = cvCreateMat( 1, this->m_iNbOfEigenShapesAtMost, CV_32FC1 );
  537. this->m_CVMAlignedShapesEigenVectors = cvCreateMat( this->m_iNbOfEigenShapesAtMost, this->m_iNbOfShapes, CV_32FC1 );
  538. // void cvCalcPCA( const CvArr* data, CvArr* avg, CvArr* eigenvalues, CvArr* eigenvectors, int flags );
  539. // According to OpenCV cvCalcPCA function description:
  540. // avg - The mean (average) vector, computed inside the function or provided by user.
  541. // Don't forget to specify m_CVMAlignedShapesMean before calculation
  542. this->m_CVMAlignedShapesMean = cvCreateMat( 1, this->m_iNbOfShapes, CV_32FC1 );
  543. this->m_CVMAlignedShapesSD = cvCreateMat( 1, this->m_iNbOfShapes, CV_32FC1 );
  544. this->m_VOAAMMeanAlignedShapePost.VO_AAMShape2D2CvMat(this->m_CVMAlignedShapesMean);
  545. cvCalcPCA( this->m_CVMAlignedShapes, this->m_CVMAlignedShapesMean, this->m_CVMAlignedShapesEigenValues,
  546. this->m_CVMAlignedShapesEigenVectors, CV_PCA_DATA_AS_ROW/* + CV_PCA_USE_AVG */);
  547. VO_Common::VO_CalcSamplesSDWithKnownMean(this->m_CVMAlignedShapes,this->m_CVMAlignedShapesMean, this->m_CVMAlignedShapesSD);
  548. CvScalar SumOfEigenValues = cvSum( this->m_CVMAlignedShapesEigenValues );
  549. float limit = (float) ( FLT_EPSILON * SumOfEigenValues.val[0] );
  550. unsigned int i = 0;
  551. for(i = 0; i < this->m_CVMAlignedShapesEigenValues->cols; i++)
  552. {
  553. if ( CV_MAT_ELEM( *this->m_CVMAlignedShapesEigenValues, float, 0, i ) < limit) break;
  554. }
  555. // NonZero EigenValues
  556. unsigned int NbOfNonZeroEigenValues = i;
  557. for(i = NbOfNonZeroEigenValues; i < this->m_iNbOfEigenShapesAtMost; i++)
  558. {
  559. CV_MAT_ELEM( *this->m_CVMAlignedShapesEigenValues, float, 0, i ) = 0.0f;
  560. }
  561. SumOfEigenValues = cvSum( this->m_CVMAlignedShapesEigenValues );
  562. float ps = 0.0f;
  563. this->m_iNbOfTruncatedShapes = 0;
  564. for(unsigned int i = 0; i < NbOfNonZeroEigenValues; i++)
  565. {
  566. ps += CV_MAT_ELEM( *this->m_CVMAlignedShapesEigenValues, float, 0, i );
  567. ++this->m_iNbOfTruncatedShapes;
  568. if( ps/SumOfEigenValues.val[0] >= this->m_fTruncatedPercent_Shape) break;
  569. }
  570. // Set the Truncated Shape to 140
  571. // this->m_iNbOfTruncatedShapes = 140;
  572. this->m_CVMTruncatedAlignedShapesEigenValues = cvCreateMat( 1, this->m_iNbOfTruncatedShapes, CV_32FC1);
  573. this->m_CVMTruncatedAlignedShapesEigenVectors = cvCreateMat( this->m_iNbOfTruncatedShapes, this->m_iNbOfShapes, CV_32FC1);
  574. for(unsigned int i = 0; i < this->m_iNbOfTruncatedShapes; i++)
  575. {
  576. CV_MAT_ELEM( *this->m_CVMTruncatedAlignedShapesEigenValues, float, 0, i )
  577. = CV_MAT_ELEM( *this->m_CVMAlignedShapesEigenValues, float, 0, i );
  578. for (unsigned int j = 0; j < this->m_iNbOfShapes; j++)
  579. {
  580. CV_MAT_ELEM( *this->m_CVMTruncatedAlignedShapesEigenVectors, float, i, j )
  581. = CV_MAT_ELEM( *this->m_CVMAlignedShapesEigenVectors, float, i, j );
  582. }
  583. }
  584. this->m_CVMAlignedShapesProject2Truncated = cvCreateMat( this->m_iNbOfSamples, this->m_iNbOfTruncatedShapes, CV_32FC1);
  585. cvProjectPCA( this->m_CVMAlignedShapes, this->m_CVMAlignedShapesMean, this->m_CVMTruncatedAlignedShapesEigenVectors,
  586. this->m_CVMAlignedShapesProject2Truncated );
  587. this->m_CVMTruancatedAlignedShapesMean = cvCreateMat( 1, this->m_iNbOfTruncatedShapes, CV_32FC1);
  588. this->m_CVMTruancatedAlignedShapesSD = cvCreateMat( 1, this->m_iNbOfTruncatedShapes, CV_32FC1);
  589. // This time, the mean value is not specified beforehand
  590. VO_Common::VO_CalcSamplesMeanNSD(this->m_CVMAlignedShapesProject2Truncated, this->m_CVMTruancatedAlignedShapesMean, this->m_CVMTruancatedAlignedShapesSD);
  591. // Calculate reference shape
  592. VO_ASM::VO_AlignedShape2ReferenceScale(this->m_VOAAMMeanAlignedShapePost, this->m_fAverageShapeSize, this->m_VOAAMReferenceShape);
  593. // 1) Build template shape mesh
  594. this->m_CVMPoints = cvCreateMat (1, this->m_iNbOfPoints, CV_32FC2);
  595. this->m_CVMConvexHull = cvCreateMat (1, this->m_iNbOfPoints, CV_32FC2);
  596. for( unsigned int i = 0; i < this->m_iNbOfPoints; i++ )
  597. {
  598. CV_MAT_ELEM( *this->m_CVMPoints, CvPoint2D32f, 0, i ) = this->m_VOAAMReferenceShape.GetPoint(i).GetXY();
  599. }
  600. // cout << "So far so good again" << endl;
  601. //exit(1);
  602. VO_ASM::VO_BuildTemplateMesh(this->m_CVMPoints, this->m_CVMConvexHull, this->m_vAAMEdge, this->m_vAAMTriangle2D );
  603. //VO_ASM::VO_BuildTemplateMesh(this->m_CVMAlignedShapesMean, this->m_CVMConvexHull, this->m_vAAMEdge, this->m_vAAMTriangle2D );
  604. this->m_iNbOfPointsOnConvexHull = this->m_CVMConvexHull->cols;
  605. this->m_iNbOfEdges = this->m_vAAMEdge.size();
  606. this->m_iNbOfTriangles = this->m_vAAMTriangle2D.size();
  607. // 2) Calculate m_vAAMNormalizedTriangle2D - make sure the mesh is built first, so that we have m_iNbOfTriangles
  608. vector<CvPoint2D32f> tempVertexes;
  609. vector<int> iVertexes;
  610. tempVertexes.resize(3);
  611. iVertexes.resize(3);
  612. for (unsigned int i = 0; i < this->m_iNbOfTriangles; i++)
  613. {
  614. iVertexes[0] = this->m_vAAMTriangle2D[i].GetVertexIndex(0);
  615. iVertexes[1] = this->m_vAAMTriangle2D[i].GetVertexIndex(1);
  616. iVertexes[2] = this->m_vAAMTriangle2D[i].GetVertexIndex(2);
  617. tempVertexes[0].x = CV_MAT_ELEM( *this->m_CVMAlignedShapesMean, float, 0, 2*iVertexes[0] );
  618. tempVertexes[0].y = CV_MAT_ELEM( *this->m_CVMAlignedShapesMean, float, 0, 2*iVertexes[0] + 1);
  619. tempVertexes[1].x = CV_MAT_ELEM( *this->m_CVMAlignedShapesMean, float, 0, 2*iVertexes[1] );
  620. tempVertexes[1].y = CV_MAT_ELEM( *this->m_CVMAlignedShapesMean, float, 0, 2*iVertexes[1] + 1);
  621. tempVertexes[2].x = CV_MAT_ELEM( *this->m_CVMAlignedShapesMean, float, 0, 2*iVertexes[2] );
  622. tempVertexes[2].y = CV_MAT_ELEM( *this->m_CVMAlignedShapesMean, float, 0, 2*iVertexes[2] + 1);
  623. this->m_vAAMNormalizedTriangle2D.push_back (VO_AAMTriangle2D(tempVertexes, iVertexes));
  624. }
  625. }
  626. /**
  627. @author JIA Pei
  628. @version 2008-03-18
  629. @brief Save ASM to a specified folder
  630. @param fn Input - the folder that ASM to be saved to
  631. */
  632. void VO_ASM::VO_Save(const string& fd)
  633. {
  634. cout << "Saving ASM model ..." << endl;
  635. string fn = fd+"/ASM";
  636. if (!boost::filesystem::is_directory(fn) )
  637. boost::filesystem::create_directory( fn );
  638. fstream fp;
  639. string tempfn;
  640. // ASM
  641. tempfn = fn + "/ASM" + ".txt";
  642. fp.open(tempfn.c_str (), ios::out);
  643. // m_iNbOfSamples
  644. fp << "m_iNbOfSamples" << endl;
  645. fp << this->m_iNbOfSamples << endl;
  646. // m_iNbOfPoints
  647. fp << "m_iNbOfPoints" << endl;
  648. fp << this->m_iNbOfPoints << endl;
  649. // m_iNbOfShapes
  650. fp << "m_iNbOfShapes" << endl;
  651. fp << this->m_iNbOfShapes << endl;
  652. // m_iNbOfTruncatedShapes
  653. fp << "m_iNbOfTruncatedShapes" << endl;
  654. fp << this->m_iNbOfTruncatedShapes << endl;
  655. // m_iNbOfEigenShapesAtMost
  656. fp << "m_iNbOfEigenShapesAtMost" << endl;
  657. fp << this->m_iNbOfEigenShapesAtMost << endl;
  658. // m_fAverageShapeSize
  659. fp << "m_fAverageShapeSize" << endl;
  660. fp << this->m_fAverageShapeSize << endl;
  661. // m_iNbOfPointsOnConvexHull
  662. fp << "m_iNbOfPointsOnConvexHull" << endl;
  663. fp << this->m_iNbOfPointsOnConvexHull << endl;
  664. // m_iNbOfEdges
  665. fp << "m_iNbOfEdges" << endl;
  666. fp << this->m_iNbOfEdges << endl;
  667. // m_iNbOfTriangles
  668. fp << "m_iNbOfTriangles" << endl;
  669. fp << this->m_iNbOfTriangles << endl;
  670. // m_fTruncatedPercent_Shape
  671. fp << "m_fTruncatedPercent_Shape" << endl;
  672. fp << this->m_fTruncatedPercent_Shape << endl;
  673. // m_fAverageShapeScalingFactor
  674. fp << "m_fAverageShapeScalingFactor" << endl;
  675. fp << this->m_fAverageShapeScalingFactor << endl;
  676. fp.close();
  677. // m_CVMShapes
  678. tempfn = fn + "/m_CVMShapes" + ".txt";
  679. fp.open(tempfn.c_str (), ios::out);
  680. fp << "m_CVMShapes" << endl;
  681. for (unsigned int i = 0; i < this->m_CVMShapes->rows; i++)
  682. {
  683. for (unsigned int j = 0; j < this->m_CVMShapes->cols; j++)
  684. {
  685. fp << CV_MAT_ELEM( *this->m_CVMShapes, float, i, j) << " " ;
  686. }
  687. fp << endl;
  688. }
  689. fp.close();
  690. // m_CVMAlignedShapes
  691. tempfn = fn + "/m_CVMAlignedShapes" + ".txt";
  692. fp.open(tempfn.c_str (), ios::out);
  693. fp << "m_CVMAlignedShapes" << endl;
  694. for (unsigned int i = 0; i < this->m_CVMAlignedShapes->rows; i++)
  695. {
  696. for (unsigned int j = 0; j < this->m_CVMAlignedShapes->cols; j++)
  697. {
  698. fp << CV_MAT_ELEM( *this->m_CVMAlignedShapes, float, i, j) << " " ;
  699. }
  700. fp << endl;
  701. }
  702. fp.close();
  703. // m_CVMAlignedShapesProject2Truncated
  704. tempfn = fn + "/m_CVMAlignedShapesProject2Truncated" + ".txt";
  705. fp.open(tempfn.c_str (), ios::out);
  706. fp << "m_CVMAlignedShapesProject2Truncated" << endl;
  707. for (unsigned int i = 0; i < this->m_CVMAlignedShapesProject2Truncated->rows; i++)
  708. {
  709. for (unsigned int j = 0; j < this->m_CVMAlignedShapesProject2Truncated->cols; j++)
  710. {
  711. fp << CV_MAT_ELEM( *this->m_CVMAlignedShapesProject2Truncated, float, i, j) << " " ;
  712. }
  713. fp << endl;
  714. }
  715. fp.close();
  716. // m_CVMTruancatedAlignedShapesMean
  717. tempfn = fn + "/m_CVMTruancatedAlignedShapesMean" + ".txt";
  718. fp.open(tempfn.c_str (), ios::out);
  719. fp << "m_CVMTruancatedAlignedShapesMean" << endl;
  720. for (unsigned int i = 0; i < this->m_CVMTruancatedAlignedShapesMean->cols; i++)
  721. {
  722. fp << CV_MAT_ELEM( *this->m_CVMTruancatedAlignedShapesMean, float, 0, i) << " " ;
  723. }
  724. fp << endl;
  725. fp.close();
  726. // m_CVMTruancatedAlignedShapesSD
  727. tempfn = fn + "/m_CVMTruancatedAlignedShapesSD" + ".txt";
  728. fp.open(tempfn.c_str (), ios::out);
  729. fp << "m_CVMTruancatedAlignedShapesSD" << endl;
  730. for (unsigned int i = 0; i < this->m_CVMTruancatedAlignedShapesSD->cols; i++)
  731. {
  732. fp << CV_MAT_ELEM( *this->m_CVMTruancatedAlignedShapesSD, float, 0, i) << " " ;
  733. }
  734. fp << endl;
  735. fp.close();
  736. // m_CVMAlignedShapesMean
  737. tempfn = fn + "/m_CVMAlignedShapesMean" + ".txt";
  738. fp.open(tempfn.c_str (), ios::out);
  739. fp << "m_CVMAlignedShapesMean" << endl;
  740. for (unsigned int i = 0; i < this->m_CVMAlignedShapesMean->cols; i++)
  741. {
  742. fp << CV_MAT_ELEM( *this->m_CVMAlignedShapesMean, float, 0, i) << " " ;
  743. }
  744. fp << endl;
  745. fp.close();
  746. // m_CVMAlignedShapesSD
  747. tempfn = fn + "/m_CVMAlignedShapesSD" + ".txt";
  748. fp.open(tempfn.c_str (), ios::out);
  749. fp << "m_CVMAlignedShapesSD" << endl;
  750. for (unsigned int i = 0; i < this->m_CVMAlignedShapesSD->cols; i++)
  751. {
  752. fp << CV_MAT_ELEM( *this->m_CVMAlignedShapesSD, float, 0, i) << " " ;
  753. }
  754. fp << endl;
  755. fp.close();
  756. // m_CVMAlignedShapesEigenVectors
  757. tempfn = fn + "/m_CVMAlignedShapesEigenVectors" + ".txt";
  758. fp.open(tempfn.c_str (), ios::out);
  759. fp << "m_CVMAlignedShapesEigenVectors" << endl;
  760. for (unsigned int i = 0; i < this->m_CVMAlignedShapesEigenVectors->rows; i++)
  761. {
  762. for (unsigned int j = 0; j < this->m_CVMAlignedShapesEigenVectors->cols; j++)
  763. {
  764. fp << CV_MAT_ELEM( *this->m_CVMAlignedShapesEigenVectors, float, i, j) << " " ;
  765. }
  766. fp << endl;
  767. }
  768. fp.close();
  769. // m_CVMAlignedShapesEigenValues
  770. tempfn = fn + "/m_CVMAlignedShapesEigenValues" + ".txt";
  771. fp.open(tempfn.c_str (), ios::out);
  772. fp << "m_CVMAlignedShapesEigenValues" << endl;
  773. for (unsigned int i = 0; i < this->m_CVMAlignedShapesEigenValues->cols; i++)
  774. {
  775. fp << CV_MAT_ELEM( *this->m_CVMAlignedShapesEigenValues, float, 0, i) << " " ;
  776. }
  777. fp << endl;
  778. fp.close();
  779. // m_CVMTruncatedAlignedShapesEigenVectors
  780. tempfn = fn + "/m_CVMTruncatedAlignedShapesEigenVectors" + ".txt";
  781. fp.open(tempfn.c_str (), ios::out);
  782. fp << "m_CVMTruncatedAlignedShapesEigenVectors" << endl;
  783. for (unsigned int i = 0; i < this->m_CVMTruncatedAlignedShapesEigenVectors->rows; i++)
  784. {
  785. for (unsigned int j = 0; j < this->m_CVMTruncatedAlignedShapesEigenVectors->cols; j++)
  786. {
  787. fp << CV_MAT_ELEM( *this->m_CVMTruncatedAlignedShapesEigenVectors, float, i, j) << " " ;
  788. }
  789. fp << endl;
  790. }
  791. fp.close();
  792. // m_CVMTruncatedAlignedShapesEigenValues
  793. tempfn = fn + "/m_CVMTruncatedAlignedShapesEigenValues" + ".txt";
  794. fp.open(tempfn.c_str (), ios::out);
  795. fp << "m_CVMTruncatedAlignedShapesEigenValues" << endl;
  796. for (unsigned int i = 0; i < this->m_CVMTruncatedAlignedShapesEigenValues->cols; i++)
  797. {
  798. fp << CV_MAT_ELEM( *this->m_CVMTruncatedAlignedShapesEigenValues, float, 0, i) << " " ;
  799. }
  800. fp << endl;
  801. fp.close();
  802. // m_CVMPoints
  803. tempfn = fn + "/m_CVMPoints" + ".txt";
  804. fp.open(tempfn.c_str (), ios::out);
  805. fp << "m_CVMPoints" << endl;
  806. for (unsigned int j = 0; j < this->m_CVMPoints->cols; j++)
  807. {
  808. fp << CV_MAT_ELEM( *this->m_CVMPoints, CvPoint2D32f, 0, j ).x << " "
  809. << CV_MAT_ELEM( *this->m_CVMPoints, CvPoint2D32f, 0, j ).y << " " << endl;
  810. }
  811. fp.close();
  812. // m_CVMConvexHull
  813. tempfn = fn + "/m_CVMConvexHull" + ".txt";
  814. fp.open(tempfn.c_str (), ios::out);
  815. fp << "m_CVMConvexHull" << endl;
  816. for (unsigned int j = 0; j < this->m_CVMConvexHull->cols; j++)
  817. {
  818. fp << CV_MAT_ELEM( *this->m_CVMConvexHull, CvPoint2D32f, 0, j).x << " "
  819. << CV_MAT_ELEM( *this->m_CVMConvexHull, CvPoint2D32f, 0, j).y << " " << endl;
  820. }
  821. fp.close();
  822. // m_VOAAMReferenceShape
  823. tempfn = fn + "/m_VOAAMReferenceShape" + ".txt";
  824. fp.open(tempfn.c_str (), ios::out);
  825. fp << "m_VOAAMReferenceShape" << endl;
  826. for (unsigned int i = 0; i < this->m_VOAAMReferenceShape.GetSize(); i++)
  827. {
  828. fp << this->m_VOAAMReferenceShape.GetPoint(i).GetXY().x << " ";
  829. fp << this->m_VOAAMReferenceShape.GetPoint(i).GetXY().y << " " << endl;
  830. }
  831. fp.close();
  832. // m_vAAMShapes
  833. tempfn = fn + "/m_vAAMShapes" + ".txt";
  834. fp.open(tempfn.c_str (), ios::out);
  835. fp << "m_vAAMShapes" << endl;
  836. for (unsigned int i = 0; i < this->m_vAAMShapes.size(); i++)
  837. {
  838. for (unsigned int j = 0; j < this->m_iNbOfPoints; j++)
  839. {
  840. fp << this->m_vAAMShapes[i].GetPoint(j).GetXY().x << " "
  841. << this->m_vAAMShapes[i].GetPoint(j).GetXY().y << " "
  842. << this->m_vAAMShapes[i].GetPoint(j).GetPath() << " "
  843. << this->m_vAAMShapes[i].GetPoint(j).GetType() << " "
  844. << this->m_vAAMShapes[i].GetPoint(j).GetIndex() << " "
  845. << this->m_vAAMShapes[i].GetPoint(j).GetFrom() << " "
  846. << this->m_vAAMShapes[i].GetPoint(j).GetTo() << " " << endl;
  847. }
  848. fp << endl;
  849. }
  850. fp.close();
  851. // m_vAAMAlignedShapes
  852. tempfn = fn + "/m_vAAMAlignedShapes" + ".txt";
  853. fp.open(tempfn.c_str (), ios::out);
  854. fp << "m_vAAMAlignedShapes" << endl;
  855. for (unsigned int i = 0; i < this->m_vAAMAlignedShapes.size(); i++)
  856. {
  857. for (unsigned int j = 0; j < this->m_iNbOfPoints; j++)
  858. {
  859. fp << this->m_vAAMAlignedShapes[i].GetPoint(j).GetXY().x << " ";
  860. fp << this->m_vAAMAlignedShapes[i].GetPoint(j).GetXY().y << " ";
  861. }
  862. fp << endl;
  863. }
  864. fp.close();
  865. // m_VOAAMMeanAlignedShapePrior
  866. tempfn = fn + "/m_VOAAMMeanAlignedShapePrior" + ".txt";
  867. fp.open(tempfn.c_str (), ios::out);
  868. fp << "m_VOAAMMeanAlignedShapePrior" << endl;
  869. for (unsigned int i = 0; i < this->m_iNbOfPoints; i++)
  870. {
  871. fp << this->m_VOAAMMeanAlignedShapePrior.GetPoint(i).GetXY().x << " ";
  872. fp << this->m_VOAAMMeanAlignedShapePrior.GetPoint(i).GetXY().y << " ";
  873. }
  874. fp << endl;
  875. fp.close();
  876. // m_VOAAMMeanAlignedShapePost
  877. tempfn = fn + "/m_VOAAMMeanAlignedShapePost" + ".txt";
  878. fp.open(tempfn.c_str (), ios::out);
  879. fp << "m_VOAAMMeanAlignedShapePost" << endl;
  880. for (unsigned int i = 0; i < this->m_iNbOfPoints; i++)
  881. {
  882. fp << this->m_VOAAMMeanAlignedShapePost.GetPoint(i).GetXY().x << " ";
  883. fp << this->m_VOAAMMeanAlignedShapePost.GetPoint(i).GetXY().y << " ";
  884. }
  885. fp << endl;
  886. fp.close();
  887. // m_VOAAMMeanShape
  888. tempfn = fn + "/m_VOAAMMeanShape" + ".txt";
  889. fp.open(tempfn.c_str (), ios::out);
  890. fp << "m_VOAAMMeanShape" << endl;
  891. for (unsigned int i = 0; i < this->m_iNbOfPoints; i++)
  892. {
  893. fp << this->m_VOAAMMeanShape.GetPoint(i).GetXY().x << " ";
  894. fp << this->m_VOAAMMeanShape.GetPoint(i).GetXY().y << " ";
  895. }
  896. fp << endl;
  897. fp.close();
  898. // m_vAAMEdge
  899. tempfn = fn + "/m_vAAMEdge" + ".txt";
  900. fp.open(tempfn.c_str (), ios::out);
  901. fp << "m_vAAMEdge" << endl;
  902. for (unsigned int i = 0; i < this->m_vAAMEdge.size(); i++)
  903. {
  904. fp << this->m_vAAMEdge[i].GetIndex1() << " ";
  905. fp << this->m_vAAMEdge[i].GetIndex2() << " " << endl;
  906. }
  907. fp.close();
  908. // m_vAAMTriangle2D
  909. tempfn = fn + "/m_vAAMTriangle2D" + ".txt";
  910. fp.open(tempfn.c_str (), ios::out);
  911. fp << "m_vAAMTriangle2D" << endl;
  912. for (unsigned int i = 0; i < this->m_vAAMTriangle2D.size (); i++)
  913. {
  914. fp << this->m_vAAMTriangle2D[i].GetVertexIndex(0) << " "
  915. << this->m_vAAMTriangle2D[i].GetVertex(0).x << " "
  916. << this->m_vAAMTriangle2D[i].GetVertex(0).y << " "
  917. << this->m_vAAMTriangle2D[i].GetVertexIndex(1) << " "
  918. << this->m_vAAMTriangle2D[i].GetVertex(1).x << " "
  919. << this->m_vAAMTriangle2D[i].GetVertex(1).y << " "
  920. << this->m_vAAMTriangle2D[i].GetVertexIndex(2) << " "
  921. << this->m_vAAMTriangle2D[i].GetVertex(2).x << " "
  922. << this->m_vAAMTriangle2D[i].GetVertex(2).y << " "
  923. << this->m_vAAMTriangle2D[i].GetdD() << " " << endl;
  924. }
  925. fp.close();
  926. // m_vAAMNormalizedTriangle2D
  927. tempfn = fn + "/m_vAAMNormalizedTriangle2D" + ".txt";
  928. fp.open(tempfn.c_str (), ios::out);
  929. fp << "m_vAAMNormalizedTriangle2D" << endl;
  930. for (unsigned int i = 0; i < this->m_vAAMNormalizedTriangle2D.size (); i++)
  931. {
  932. fp << this->m_vAAMNormalizedTriangle2D[i].GetVertexIndex(0) << " "
  933. << this->m_vAAMNormalizedTriangle2D[i].GetVertex(0).x << " "
  934. << this->m_vAAMNormalizedTriangle2D[i].GetVertex(0).y << " "
  935. << this->m_vAAMNormalizedTriangle2D[i].GetVertexIndex(1) << " "
  936. << this->m_vAAMNormalizedTriangle2D[i].GetVertex(1).x << " "
  937. << this->m_vAAMNormalizedTriangle2D[i].GetVertex(1).y << " "
  938. << this->m_vAAMNormalizedTriangle2D[i].GetVertexIndex(2) << " "
  939. << this->m_vAAMNormalizedTriangle2D[i].GetVertex(2).x << " "
  940. << this->m_vAAMNormalizedTriangle2D[i].GetVertex(2).y << " "
  941. << this->m_vAAMNormalizedTriangle2D[i].GetdD() << " " << endl;
  942. }
  943. fp.close();
  944. }
  945. /**
  946. @author DEENA Salil
  947. @version 2009-09-22
  948. @brief Load ASM from a specified folder
  949. @param fn Input - the folder that ASM is to be loaded from
  950. */
  951. void VO_ASM::VO_Load(const string& fd)
  952. {
  953. string tempfn;
  954. string line;
  955. ifstream fp;
  956. vector<string> tokens;
  957. vector<string> data;
  958. int num_rows, num_cols;
  959. CvPoint2D32f tempCvPoint2D32f;
  960. VO_AAMPoint2D tempAAMPoint2d;
  961. cout << "Loading ASM model data ..." << endl;
  962. string fn = fd+"/ASM";
  963. if (!boost::filesystem::is_directory(fn) )
  964. {
  965. cout << "ASM directory not present...aborting." << endl;
  966. exit(1);
  967. }
  968. // Read the variables first
  969. tempfn = fn + "/ASM" + ".txt";
  970. fp.open(tempfn.c_str (), ios::in);
  971. getline(fp, line);
  972. getline(fp, line);
  973. this->m_iNbOfSamples = atoi(line.c_str());
  974. getline(fp, line);
  975. getline(fp, line);
  976. this->m_iNbOfPoints = atoi(line.c_str());
  977. getline(fp, line);
  978. getline(fp, line);
  979. this->m_iNbOfShapes = atoi(line.c_str());
  980. getline(fp, line);
  981. getline(fp, line);
  982. this->m_iNbOfTruncatedShapes = atoi(line.c_str());
  983. getline(fp, line);
  984. getline(fp, line);
  985. this->m_iNbOfEigenShapesAtMost = atoi(line.c_str());
  986. getline(fp, line);
  987. getline(fp, line);
  988. this->m_fAverageShapeSize = atof(line.c_str());
  989. getline(fp, line);
  990. getline(fp, line);
  991. this->m_iNbOfPointsOnConvexHull = atoi(line.c_str());
  992. getline(fp, line);
  993. getline(fp, line);
  994. this->m_iNbOfEdges = atoi(line.c_str());
  995. getline(fp, line);
  996. getline(fp, line);
  997. this->m_iNbOfTriangles = atoi(line.c_str());
  998. getline(fp, line);
  999. getline(fp, line);
  1000. this->m_fTruncatedPercent_Shape = atof(line.c_str());
  1001. getline(fp, line);
  1002. getline(fp, line);
  1003. this->m_fAverageShapeScalingFactor = atof(line.c_str());
  1004. fp.close();
  1005. tempfn = fn + "/m_CVMShapes" + ".txt";
  1006. fp.open(tempfn.c_str (), ios::in);
  1007. getline(fp, line);
  1008. int i = 0;
  1009. while (getline(fp, line))
  1010. {
  1011. data.push_back(line);
  1012. i++;
  1013. }
  1014. // Obtain number of cols in data
  1015. line = data[0];
  1016. TokenizeIntoTokensOnly(data[0], tokens, " ");
  1017. this->m_CVMShapes = cvCreateMat(this->m_iNbOfSamples, this->m_iNbOfShapes, CV_32FC1);
  1018. for (unsigned int i = 0; i < this->m_CVMShapes->rows; i++)
  1019. {
  1020. tokens.clear();
  1021. TokenizeIntoTokensOnly(data[i], tokens, " ");
  1022. for (unsigned int j = 0; j < this->m_CVMShapes->cols; j++)
  1023. {
  1024. CV_MAT_ELEM( *this->m_CVMShapes, float, i, j) = atof(tokens[j].c_str());
  1025. }
  1026. }
  1027. data.clear();
  1028. fp.close();
  1029. tokens.clear();
  1030. // m_CVMAlignedShapes
  1031. tempfn = fn + "/m_CVMAlignedShapes" + ".txt";
  1032. fp.open(tempfn.c_str (), ios::in);
  1033. getline(fp, line);
  1034. i = 0;
  1035. while (getline(fp, line))
  1036. {
  1037. data.push_back(line);
  1038. i++;
  1039. }
  1040. // Obtain number of cols in data
  1041. line = data[0];
  1042. TokenizeIntoTokensOnly(data[0], tokens, " ");
  1043. num_rows = data.size();
  1044. num_cols = tokens.size();
  1045. this->m_CVMAlignedShapes = cvCreateMat(num_rows, num_cols, CV_32FC1);
  1046. for (unsigned int i = 0; i < num_rows; i++)
  1047. {
  1048. tokens.clear();
  1049. TokenizeIntoTokensOnly(data[i], tokens, " ");
  1050. for (unsigned int j = 0; j < num_cols; j++)
  1051. {
  1052. CV_MAT_ELEM( *this->m_CVMAlignedShapes, float, i, j) = atof(tokens[j].c_str());
  1053. }
  1054. }
  1055. data.clear();
  1056. fp.close();
  1057. tokens.clear();
  1058. // m_CVMAlignedShapesProject2Truncated
  1059. tempfn = fn + "/m_CVMAlignedShapesProject2Truncated" + ".txt";
  1060. fp.open(tempfn.c_str (), ios::in);
  1061. getline(fp, line);
  1062. i = 0;
  1063. while (getline(fp, line))
  1064. {
  1065. data.push_back(line);
  1066. i++;
  1067. }
  1068. // Obtain number of cols in data
  1069. line = data[0];
  1070. TokenizeIntoTokensOnly(data[0], tokens, " ");
  1071. num_rows = data.size();
  1072. num_cols = tokens.size();
  1073. this->m_CVMAlignedShapesProject2Truncated = cvCreateMat(num_rows, num_cols, CV_32FC1);
  1074. for (unsigned int i = 0; i < num_rows; i++)
  1075. {
  1076. tokens.clear();
  1077. TokenizeIntoTokensOnly(data[i], tokens, " ");
  1078. for (unsigned int j = 0; j < num_cols; j++)
  1079. {
  1080. CV_MAT_ELEM( *this->m_CVMAlignedShapesProject2Truncated, float, i, j) = atof(tokens[j].c_str());
  1081. }
  1082. }
  1083. data.clear();
  1084. tokens.clear();
  1085. fp.close();
  1086. // m_CVMAlignedShapesSD
  1087. tempfn = fn + "/m_CVMAlignedShapesSD" + ".txt";
  1088. fp.open(tempfn.c_str (), ios::in);
  1089. getline(fp, line);
  1090. i = 0;
  1091. while (getline(fp, line))
  1092. {
  1093. data.push_back(line);
  1094. i++;
  1095. }
  1096. // Obtain number of cols in data
  1097. line = data[0];
  1098. TokenizeIntoTokensOnly(data[0], tokens, " ");
  1099. num_rows = data.size();
  1100. num_cols = tokens.size();
  1101. this->m_CVMAlignedShapesSD = cvCreateMat(num_rows, num_cols, CV_32FC1);
  1102. for (unsigned int i = 0; i < num_rows; i++)
  1103. {
  1104. tokens.clear();
  1105. TokenizeIntoTokensOnly(data[i], tokens, " ");
  1106. for (unsigned int j = 0; j < num_cols; j++)
  1107. {
  1108. CV_MAT_ELEM( *this->m_CVMAlignedShapesSD, float, i, j) = atof(tokens[j].c_str());
  1109. }
  1110. }
  1111. data.clear();
  1112. tokens.clear();
  1113. fp.close();
  1114. // m_CVMTruancatedAlignedShapesMean
  1115. tempfn = fn + "/m_CVMTruancatedAlignedShapesMean" + ".txt";
  1116. fp.open(tempfn.c_str (), ios::in);
  1117. getline(fp, line);
  1118. i = 0;
  1119. while (getline(fp, line))
  1120. {
  1121. data.push_back(line);
  1122. i++;
  1123. }
  1124. // Obtain number of cols in data
  1125. line = data[0];
  1126. TokenizeIntoTokensOnly(line, tokens, " ");
  1127. num_rows = data.size();
  1128. num_cols = tokens.size();
  1129. this->m_CVMTruancatedAlignedShapesMean = cvCreateMat(num_rows, num_cols, CV_32FC1);
  1130. for (unsigned int i = 0; i < num_rows; i++)
  1131. {
  1132. tokens.clear();
  1133. TokenizeIntoTokensOnly(data[i], tokens, " ");
  1134. for (unsigned int j = 0; j < num_cols; j++)
  1135. {
  1136. CV_MAT_ELEM( *this->m_CVMTruancatedAlignedShapesMean, float, i, j) = atof(tokens[j].c_str());
  1137. }
  1138. }
  1139. data.clear();
  1140. fp.close();
  1141. tokens.clear();
  1142. // m_CVMTruancatedAlignedShapesSD
  1143. tempfn = fn + "/m_CVMTruancatedAlignedShapesSD" + ".txt";
  1144. fp.open(tempfn.c_str (), ios::in);
  1145. getline(fp, line);
  1146. i = 0;
  1147. while (getline(fp, line))
  1148. {
  1149. data.push_back(line);
  1150. i++;
  1151. }
  1152. // Obtain number of cols in data
  1153. line = data[0];
  1154. TokenizeIntoTokensOnly(line, tokens, " ");
  1155. num_rows = data.size();
  1156. num_cols = tokens.size();
  1157. this->m_CVMTruancatedAlignedShapesSD = cvCreateMat(num_rows, num_cols, CV_32FC1);
  1158. for (unsigned int i = 0; i < num_rows; i++)
  1159. {
  1160. tokens.clear();
  1161. TokenizeIntoTokensOnly(data[i], tokens, " ");
  1162. for (unsigned int j = 0; j < num_cols; j++)
  1163. {
  1164. CV_MAT_ELEM( *this->m_CVMTruancatedAlignedShapesSD, float, i, j) = atof(tokens[j].c_str());
  1165. }
  1166. }
  1167. data.clear();
  1168. fp.close();
  1169. tokens.clear();
  1170. // m_CVMAlignedShapesEigenVectors
  1171. tempfn = fn + "/m_CVMAlignedShapesEigenVectors" + ".txt";
  1172. fp.open(tempfn.c_str (), ios::in);
  1173. getline(fp, line);
  1174. i = 0;
  1175. while (getline(fp, line))
  1176. {
  1177. data.push_back(line);
  1178. i++;
  1179. }
  1180. // Obtain number of cols in data
  1181. line = data[0];
  1182. TokenizeIntoTokensOnly(line, tokens, " ");
  1183. num_rows = data.size();
  1184. num_cols = tokens.size();
  1185. this->m_CVMAlignedShapesEigenVectors = cvCreateMat(num_rows, num_cols, CV_32FC1);
  1186. for (unsigned int i = 0; i < num_rows; i++)
  1187. {
  1188. tokens.clear();
  1189. TokenizeIntoTokensOnly(data[i], tokens, " ");
  1190. for (unsigned int j = 0; j < num_cols; j++)
  1191. {
  1192. CV_MAT_ELEM( *this->m_CVMAlignedShapesEigenVectors, float, i, j) = atof(tokens[j].c_str());
  1193. }
  1194. }
  1195. data.clear();
  1196. fp.close();
  1197. tokens.clear();
  1198. // m_CVMAlignedShapesEigenValues
  1199. tempfn = fn + "/m_CVMAlignedShapesEigenValues" + ".txt";
  1200. fp.open(tempfn.c_str (), ios::in);
  1201. getline(fp, line);
  1202. i = 0;
  1203. while (getline(fp, line))
  1204. {
  1205. data.push_back(line);
  1206. i++;
  1207. }
  1208. // Obtain number of cols in data
  1209. line = data[0];
  1210. TokenizeIntoTokensOnly(line, tokens, " ");
  1211. num_rows = data.size();
  1212. num_cols = tokens.size();
  1213. this->m_CVMAlignedShapesEigenValues = cvCreateMat(num_rows, num_cols, CV_32FC1);
  1214. for (unsigned int i = 0; i < num_rows; i++)
  1215. {
  1216. tokens.clear();
  1217. TokenizeIntoTokensOnly(data[i], tokens, " ");
  1218. for (unsigned int j = 0; j < num_cols; j++)
  1219. {
  1220. CV_MAT_ELEM( *this->m_CVMAlignedShapesEigenValues, float, i, j) = atof(tokens[j].c_str());
  1221. }
  1222. }
  1223. data.clear();
  1224. fp.close();
  1225. tokens.clear();
  1226. //m_CVMTruncatedAlignedShapesEigenVectors
  1227. tempfn = fn + "//m_CVMTruncatedAlignedShapesEigenVectors" + ".txt";
  1228. fp.open(tempfn.c_str (), ios::in);
  1229. getline(fp, line);
  1230. i = 0;
  1231. while (getline(fp, line))
  1232. {
  1233. data.push_back(line);
  1234. i++;
  1235. }
  1236. // Obtain number of cols in data
  1237. line = data[0];
  1238. TokenizeIntoTokensOnly(line, tokens, " ");
  1239. num_rows = data.size();
  1240. num_cols = tokens.size();
  1241. this->m_CVMTruncatedAlignedShapesEigenVectors = cvCreateMat(num_rows, num_cols, CV_32FC1);
  1242. for (unsigned int i = 0; i < num_rows; i++)
  1243. {
  1244. tokens.clear();
  1245. TokenizeIntoTokensOnly(data[i], tokens, " ");
  1246. for (unsigned int j = 0; j < num_cols; j++)
  1247. {
  1248. CV_MAT_ELEM( *this->m_CVMTruncatedAlignedShapesEigenVectors, float, i, j) = atof(tokens[j].c_str());
  1249. }
  1250. }
  1251. data.clear();
  1252. fp.close();
  1253. tokens.clear();
  1254. //m_CVMTruncatedAlignedShapesEigenValues
  1255. tempfn = fn + "//m_CVMTruncatedAlignedShapesEigenValues" + ".txt";
  1256. fp.open(tempfn.c_str (), ios::in);
  1257. getline(fp, line);
  1258. i = 0;
  1259. while (getline(fp, line))
  1260. {
  1261. data.push_back(line);
  1262. i++;
  1263. }
  1264. // Obtain number of cols in data
  1265. line = data[0];
  1266. TokenizeIntoTokensOnly(line, tokens, " ");
  1267. num_rows = data.size();
  1268. num_cols = tokens.size();
  1269. this->m_CVMTruncatedAlignedShapesEigenValues = cvCreateMat(num_rows, num_cols, CV_32FC1);
  1270. for (unsigned int i = 0; i < num_rows; i++)
  1271. {
  1272. tokens.clear();
  1273. TokenizeIntoTokensOnly(data[i], tokens, " ");
  1274. for (unsigned int j = 0; j < num_cols; j++)
  1275. {
  1276. CV_MAT_ELEM( *this->m_CVMTruncatedAlignedShapesEigenValues, float, i, j) = atof(tokens[j].c_str());
  1277. }
  1278. }
  1279. data.clear();
  1280. fp.close();
  1281. tokens.clear();
  1282. // m_CVMPoints
  1283. tempfn = fn + "/m_CVMPoints" + ".txt";
  1284. fp.open(tempfn.c_str (), ios::in);
  1285. getline(fp, line);
  1286. i = 0;
  1287. while (getline(fp, line))
  1288. {
  1289. data.push_back(line);
  1290. i++;
  1291. }
  1292. // Obtain number of cols in data
  1293. line = data[0];
  1294. TokenizeIntoTokensOnly(line, tokens, " ");
  1295. num_cols = data.size();
  1296. num_rows = tokens.size();
  1297. this->m_CVMPoints = cvCreateMat (1, num_cols, CV_32FC2);
  1298. for (unsigned int j = 0; j < num_cols; j++)
  1299. {
  1300. tokens.clear();
  1301. TokenizeIntoTokensOnly(data[j], tokens, " ");
  1302. for (unsigned int i = 0; i < num_rows; i++)
  1303. {
  1304. if (i == 0)
  1305. CV_MAT_ELEM( *this->m_CVMPoints, CvPoint2D32f, 0, j ).x = atof(tokens[i].c_str());
  1306. if (i == 1)
  1307. CV_MAT_ELEM( *this->m_CVMPoints, CvPoint2D32f, 0, j ).y = atof(tokens[i].c_str());
  1308. }
  1309. }
  1310. data.clear();
  1311. fp.close();
  1312. tokens.clear();
  1313. // m_CVMConvexHull
  1314. tempfn = fn + "/m_CVMConvexHull" + ".txt";
  1315. fp.open(tempfn.c_str (), ios::in);
  1316. getline(fp, line);

Large files files are truncated, but you can click here to view the full file