OTSParticle.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. #include "stdafx.h"
  2. #include "OTSParticle.h"
  3. #include "Element.h"
  4. #include "Convert.h"
  5. namespace OTSDATA {
  6. // COTSParticle
  7. // constructor
  8. COTSParticle::COTSParticle() // constructor
  9. {
  10. Init();
  11. //headerParticle = NULL;
  12. }
  13. COTSParticle::COTSParticle(const COTSParticle& a_oSource) // copy constructor
  14. {
  15. // can't copy itself
  16. if (&a_oSource == this)
  17. {
  18. return;
  19. }
  20. // copy data over
  21. Duplicate(a_oSource);
  22. }
  23. COTSParticle::COTSParticle(COTSParticle* a_poSource) // copy constructor
  24. {
  25. // can't copy itself
  26. if (a_poSource == this)
  27. {
  28. return;
  29. }
  30. // copy data over
  31. Duplicate(*a_poSource);
  32. }
  33. COTSParticle& COTSParticle::operator=(const COTSParticle& a_oSource) // =operator
  34. {
  35. // cleanup
  36. Cleanup();
  37. // copy the class data over
  38. Duplicate(a_oSource);
  39. // return class
  40. return *this;
  41. }
  42. BOOL COTSParticle::operator==(const COTSParticle& a_oSource) // ==operator
  43. {
  44. // return FASLE, if the two segments list are in different size
  45. return ( m_nTagId == a_oSource.m_nTagId &&
  46. //m_nSearchId == a_oSource.m_nSearchId &&
  47. m_nAnalysisId == a_oSource.m_nAnalysisId &&
  48. m_nFieldId == a_oSource.m_nFieldId &&
  49. m_dArea == a_oSource.m_dArea &&
  50. m_cAveGray == a_oSource.m_cAveGray &&
  51. m_classifyId == a_oSource.m_classifyId &&
  52. m_poiXRayPos == a_oSource.m_poiXRayPos &&
  53. *(m_pFeature.get()) == *(a_oSource.m_pFeature.get()));
  54. }
  55. COTSParticle::~COTSParticle() // destructor
  56. {
  57. Cleanup();
  58. }
  59. void COTSParticle::Serialize(bool isStoring, tinyxml2::XMLDocument * classDoc, tinyxml2::XMLElement * rootNode)
  60. {
  61. xmls::xInt xTagId;
  62. xmls::xInt xnSearchId;
  63. xmls::xInt xnAnalysisId;
  64. xmls::xInt xnFieldId;
  65. xmls::xDouble xdArea;
  66. xmls::xRect xrectParticle;
  67. xmls::xInt xcAveGray;
  68. xmls::xInt xType;
  69. xmls::xPoint xpoiXRayPos;
  70. xmls::Slo slo;
  71. slo.Register("TagId", &xTagId);
  72. slo.Register("SearchId", &xnSearchId);
  73. slo.Register("AnalysisId", &xnAnalysisId);
  74. slo.Register("FieldId", &xnFieldId);
  75. slo.Register("Area", &xdArea);
  76. slo.Register("rectParticle", &xrectParticle);
  77. slo.Register("AveGray", &xcAveGray);
  78. slo.Register("Type", &xType);
  79. slo.Register("poiXRayPos", &xpoiXRayPos);
  80. slo.Register("Feature", m_pFeature.get());
  81. if (isStoring)
  82. {
  83. xTagId = m_nTagId;
  84. //xnSearchId = m_nSearchId;
  85. xnAnalysisId = m_nAnalysisId;
  86. xnFieldId = m_nFieldId;
  87. xdArea = m_dArea;
  88. xrectParticle = m_rectParticle;
  89. xcAveGray = m_cAveGray;
  90. xType = m_classifyId;
  91. xpoiXRayPos = m_poiXRayPos;
  92. slo.Serialize(true, classDoc, rootNode);
  93. }
  94. else
  95. {
  96. slo.Serialize(false, classDoc, rootNode);
  97. m_nTagId = xTagId.value();
  98. //m_nSearchId = xnSearchId.value();
  99. m_nAnalysisId = xnAnalysisId.value();
  100. m_nFieldId = xnFieldId.value();
  101. m_dArea = xdArea.value();
  102. m_rectParticle = xrectParticle.value();
  103. m_cAveGray = xcAveGray.value();
  104. m_classifyId = xType.value();
  105. m_poiXRayPos = xpoiXRayPos.value();
  106. }
  107. }
  108. double COTSParticle::GetImgPropertyValueByName(CString propertyName)
  109. {
  110. //double pvalue;
  111. if (propertyName == "Dmax") return this->GetDMax();
  112. if (propertyName == "Dmin") return this->GetDMin();
  113. if (propertyName == "Area") return this->GetActualArea();
  114. if (propertyName == "Dferet") return this->GetFeretDiameter();
  115. if (propertyName == "Width") return this->GetMinWidth();
  116. if (propertyName == "Height") return this->GetMinHeight();
  117. if (propertyName == "Perimeter") return this->GetPerimeter();
  118. if (propertyName == "Dperp") return this->GetDPerp();
  119. if (propertyName == "Dinscr") return this->GetDInscr();
  120. if (propertyName == "Dmean") return this->GetDMean();
  121. if (propertyName == "Orientation") return this->GetOrientation();
  122. if (propertyName == "Delong") return this->GetDElong();
  123. if (propertyName == "AspectElong") return this->GetAspectElong();
  124. if (propertyName == "Dequalcircle") return this->GetEqualCircleDiameter();
  125. if (propertyName == "Aspect") return this->GetAspectRatio();
  126. if (propertyName == "Vedio") return this->GetVideo();
  127. if (propertyName == "X") return this->GetXRayPos().x;
  128. if (propertyName == "Y") return this->GetXRayPos().y;
  129. //return pvalue;
  130. }
  131. std::string COTSParticle::GetImgPortraitString()
  132. {
  133. CString str;
  134. CString dmax = Convert::MFC::ToString(this->GetDMax());
  135. CString dmin = Convert::MFC::ToString(this->GetDMin());
  136. CString dmean = Convert::MFC::ToString(this->GetDMean());
  137. CString dinsc = Convert::MFC::ToString(this->GetDInscr());
  138. CString dferet = Convert::MFC::ToString(this->GetFeretDiameter());
  139. CString dperp = Convert::MFC::ToString(this->GetDPerp());
  140. CString delong = Convert::MFC::ToString(this->GetDElong());
  141. CString aspect = Convert::MFC::ToString(this->GetAspectRatio());
  142. CString area = Convert::MFC::ToString(this->GetActualArea());
  143. CString video = Convert::MFC::ToString(this->GetVideo());
  144. CString width = Convert::MFC::ToString(this->GetOTSRect().GetWidth());
  145. CString height = Convert::MFC::ToString(this->GetOTSRect().GetHeight());
  146. CString orientation = Convert::MFC::ToString(this->GetOrientation());
  147. str = _T("Area:")+ area + _T(" ") + _T("Gray:")+video + _T(" ") +_T("Dmax:")+ dmax + _T(" ") + _T("Dmin:")+ dmin + _T(" ") + dmean + _T(" ") + dinsc + _T(" ") +_T("Dfere:")+ dferet + _T(" ") + dperp + _T(" ") +
  148. delong + _T(" ") + _T("Aspect:")+aspect + _T(" ") + width + _T(" ") + height + _T(" ") +_T("orientation:")+ orientation;
  149. return Convert::MFC::CStringToString(str);
  150. }
  151. double COTSParticle::CalculateSimilarity(COTSParticlePtr part)
  152. {
  153. //estimate the area first----------
  154. double arearatio = 0;
  155. if (this->GetActualArea() <= part->GetActualArea())
  156. {
  157. arearatio = this->GetActualArea() / part->GetActualArea();
  158. }
  159. else
  160. {
  161. arearatio = part->GetActualArea() / this->GetActualArea();
  162. }
  163. if (arearatio < 0.85)
  164. {
  165. return 0;
  166. }
  167. //-------------------------
  168. auto data1 = this->GetMorphData();
  169. auto data2 = part->GetMorphData();
  170. // 公式: (x1y1+x2y2+x3y3+...x2000y2000) / (sqrt(x1^2 + x2^2 + ...x2000^2) * sqrt(y1^2 + y2^2 + ...y2000^2))
  171. double dotProduct = 0;
  172. double d1 = 0;
  173. double d2 = 0;
  174. for (int i = 0; i < data1.size(); i++)
  175. {
  176. double r1 = data1[i];
  177. double r2 = data2[i];
  178. r1 *= r2;
  179. dotProduct = dotProduct + r1;
  180. }
  181. d1 =this->GetMorphologyVectorNorm();
  182. d2 = part->GetMorphologyVectorNorm();
  183. return (0 == d1 || 0 == d2) ? 0 : dotProduct / (d1 * d2);
  184. }
  185. BOOL COTSParticle::CalCoverRectFromSegment()
  186. {
  187. ASSERT(m_pFeature);
  188. if (!m_pFeature)
  189. {
  190. return FALSE;
  191. }
  192. COTSSegmentsList a_listSegment = m_pFeature->GetSegmentsList();
  193. // height is most height - lowest + 1
  194. // width is the widest - thinnest + 1
  195. int nSize = (int)a_listSegment.size();
  196. // no segment, no need to compute
  197. if (nSize <= 0)
  198. {
  199. return FALSE;
  200. }
  201. // get the most highest, lowest, widest, thinness
  202. int nHmin = a_listSegment[0]->GetHeight();
  203. int nHmax = a_listSegment[0]->GetHeight();
  204. int nWmin = a_listSegment[0]->GetStart();
  205. int nWmax = a_listSegment[0]->GetStart() + a_listSegment[0]->GetLength() - 1;
  206. // loop segment list
  207. for (auto pSegement : a_listSegment)
  208. {
  209. int nHt = pSegement->GetHeight();
  210. if (nHt < nHmin)
  211. {
  212. nHmin = nHt;
  213. }
  214. if (nHt > nHmax)
  215. {
  216. nHmax = nHt;
  217. }
  218. int nSt = pSegement->GetStart();
  219. int nEd = pSegement->GetStart() + pSegement->GetLength() - 1;
  220. if (nSt < nWmin)
  221. {
  222. nWmin = nSt;
  223. }
  224. if (nEd > nWmax)
  225. {
  226. nWmax = nEd;
  227. }
  228. }
  229. if (nHmin > nHmax || nWmin > nWmax)
  230. {
  231. return FALSE;
  232. }
  233. // get the rect
  234. m_rectParticle.top = nHmin;
  235. m_rectParticle.left = nWmin;
  236. m_rectParticle.bottom = nHmax;
  237. m_rectParticle.right = nWmax;
  238. return TRUE;
  239. }
  240. BOOL COTSParticle::CalPixelArea()
  241. {
  242. ASSERT(m_pFeature);
  243. if (!m_pFeature)
  244. {
  245. return FALSE;
  246. }
  247. COTSSegmentsList a_listSegment = m_pFeature->GetSegmentsList();
  248. // Area is all the segment's length add.
  249. int nSize = (int)a_listSegment.size();
  250. m_dPixelArea = 0;
  251. // no segment, no need to compute
  252. if (nSize <= 0)
  253. {
  254. return FALSE;
  255. }
  256. // loop segment list
  257. for (auto pSegement : a_listSegment)
  258. {
  259. m_dPixelArea += (double)pSegement->GetLength();
  260. }
  261. return TRUE;
  262. }
  263. BOOL COTSParticle::CalXRayPos()
  264. {
  265. ASSERT(m_pFeature);
  266. if (!m_pFeature)
  267. {
  268. return FALSE;
  269. }
  270. COTSSegmentsList a_listSegment = m_pFeature->GetSegmentsList();
  271. // all the pixels add
  272. int nSize = (int)a_listSegment.size();
  273. // no segment, no need to compute
  274. if (nSize <= 0)
  275. {
  276. return FALSE;
  277. }
  278. // get the 1/3 high part, the longest
  279. if(m_rectParticle.IsRectNull())
  280. {
  281. if (!CalCoverRectFromSegment())
  282. return FALSE;
  283. }
  284. COTSSegmentsList listSegmentLength;
  285. listSegmentLength.clear();
  286. int nHMax = a_listSegment[0]->GetHeight();
  287. int nHMin = a_listSegment[0]->GetHeight();
  288. for (auto pSegment : a_listSegment)
  289. {
  290. int nH = pSegment->GetHeight();
  291. if (nH < nHMin)
  292. {
  293. nHMin = nH;
  294. }
  295. if (nH > nHMax)
  296. {
  297. nHMax = nH;
  298. }
  299. }
  300. int nHeight = m_rectParticle.Height();
  301. int nHStart = (int)(nHeight / 3 + nHMin + 0.5);
  302. int nHEnd = (int)(2 * nHeight / 3 + nHMax + 0.5);
  303. for (auto pSegment : a_listSegment)
  304. {
  305. int nH = pSegment->GetHeight();
  306. if (nH >= nHStart && nH <= nHEnd)
  307. {
  308. COTSSegmentPtr pSegmentNew = COTSSegmentPtr(new COTSSegment(*pSegment.get()));
  309. listSegmentLength.push_back(pSegmentNew);
  310. }
  311. }
  312. // get the longest length in the middle 1/3 part
  313. if ((int)listSegmentLength.size() < 0)
  314. {
  315. return FALSE;
  316. }
  317. int nLMax = listSegmentLength[0]->GetLength();
  318. for (auto pSegment : listSegmentLength)
  319. {
  320. int nL = pSegment->GetLength();
  321. if (nL > nLMax)
  322. {
  323. nLMax = nL;
  324. }
  325. }
  326. COTSSegmentsList listSegmentMaxLength;
  327. listSegmentMaxLength.clear();
  328. // find the segment has the longest length
  329. for (auto pSegment : listSegmentLength)
  330. {
  331. if (pSegment->GetLength() == nLMax)
  332. {
  333. COTSSegmentPtr pSegmentNew = COTSSegmentPtr(new COTSSegment(*pSegment.get()));
  334. listSegmentMaxLength.push_back(pSegmentNew);
  335. }
  336. }
  337. // get the middle longest length
  338. if ((int)listSegmentMaxLength.size() < 0)
  339. {
  340. return FALSE;
  341. }
  342. COTSSegmentPtr pSegCur = listSegmentMaxLength[0];
  343. int nSegStart = pSegCur->GetStart();
  344. int nSegHeight = pSegCur->GetHeight();
  345. int nSegLength = pSegCur->GetLength();
  346. CPoint ptSegCenter;
  347. ptSegCenter.x = (int)(nSegStart + nSegLength / 2 + 0.5);
  348. ptSegCenter.y = nSegHeight;
  349. CPoint ptPartCenter = m_rectParticle.CenterPoint();
  350. double nHToMMin = sqrt((ptSegCenter.x - ptPartCenter.x)*(ptSegCenter.x - ptPartCenter.x) + (ptSegCenter.y - ptPartCenter.y)*(ptSegCenter.y - ptPartCenter.y));
  351. for (auto pSegment : listSegmentMaxLength)
  352. {
  353. nSegStart = pSegment->GetStart();
  354. nSegHeight = pSegment->GetHeight();
  355. nSegLength = pSegment->GetLength();
  356. ptSegCenter.x = (int)(nSegStart + nSegLength / 2 + 0.5);
  357. ptSegCenter.y = nSegHeight;
  358. double nHToM = sqrt((ptSegCenter.x - ptPartCenter.x)*(ptSegCenter.x - ptPartCenter.x) + (ptSegCenter.y - ptPartCenter.y)*(ptSegCenter.y - ptPartCenter.y));
  359. if (nHToM < nHToMMin)
  360. {
  361. nHToMMin = nHToM;
  362. }
  363. }
  364. // get the middle longest segment
  365. for (auto pSegment : listSegmentMaxLength)
  366. {
  367. nSegStart = pSegment->GetStart();
  368. nSegHeight = pSegment->GetHeight();
  369. nSegLength = pSegment->GetLength();
  370. ptSegCenter.x = (int)(nSegStart + nSegLength / 2 + 0.5);
  371. ptSegCenter.y = nSegHeight;
  372. double nHToM = sqrt((ptSegCenter.x - ptPartCenter.x)*(ptSegCenter.x - ptPartCenter.x) + (ptSegCenter.y - ptPartCenter.y)*(ptSegCenter.y - ptPartCenter.y));
  373. if (nHToM == nHToMMin)
  374. {
  375. m_poiXRayPos = ptPartCenter;
  376. break;
  377. }
  378. }
  379. return TRUE;
  380. }
  381. BOOL COTSParticle::CalActualArea(double pixelsize)
  382. {
  383. auto pixelarea = GetPixelArea();
  384. m_dArea = pixelarea * pixelsize * pixelsize;
  385. return true;
  386. }
  387. void COTSParticle::SetFeature(COTSFeaturePtr a_pFeature)
  388. {
  389. ASSERT(a_pFeature);
  390. if (!a_pFeature)
  391. {
  392. return;
  393. }
  394. //m_pFeature = COTSFeaturePtr(new COTSFeature(*a_pFeature.get()));
  395. m_pFeature = a_pFeature;
  396. }
  397. BOOL COTSParticle::IsConnected(COTSParticle* a_p, int fldwidth, int fldheight, int direction)
  398. {
  399. //decide if two on boundary particles are connected.
  400. typedef enum class SORTING_DIRECTION
  401. {
  402. LEFT = 1,
  403. DOWN = 2,
  404. RIGHT = 3,
  405. UP = 4
  406. }SORTING_DIRECTION;
  407. SORTING_DIRECTION di = (SORTING_DIRECTION)direction;
  408. for (auto s : m_pFeature->GetSegmentsList())
  409. {
  410. for (auto a_seg : a_p->GetFeature()->GetSegmentsList())
  411. {
  412. if (di == SORTING_DIRECTION::LEFT || di == SORTING_DIRECTION::RIGHT)
  413. {
  414. if (s->GetHeight() == a_seg->GetHeight())
  415. {
  416. if ((s->GetStart() + s->GetLength()) == fldwidth && a_seg->GetStart() == 0)
  417. {
  418. return true;//left connected to neighbor's right.
  419. }
  420. if ((a_seg->GetStart() + a_seg->GetLength()) == fldwidth && s->GetStart() == 0)
  421. {
  422. return true;//
  423. }
  424. }
  425. }
  426. if (di == SORTING_DIRECTION::UP || di == SORTING_DIRECTION::DOWN)
  427. {
  428. if (s->GetHeight() == 0 && a_seg->GetHeight() == fldheight - 1)//the lowest height of the segment is the height of the field minus 1.
  429. {
  430. if (s->GetStart() >= a_seg->GetStart() && s->GetStart() <= a_seg->GetStart() + a_seg->GetLength())
  431. {
  432. return true;
  433. }
  434. if (a_seg->GetStart() >= s->GetStart() && a_seg->GetStart() <= s->GetStart() + s->GetLength())
  435. {
  436. return true;
  437. }
  438. }
  439. if (a_seg->GetHeight() == 0 && s->GetHeight() == fldheight - 1)
  440. {
  441. if (s->GetStart() >= a_seg->GetStart() && s->GetStart() <= a_seg->GetStart() + a_seg->GetLength())
  442. {
  443. return true;
  444. }
  445. if (a_seg->GetStart() >= s->GetStart() && a_seg->GetStart() <= s->GetStart() + s->GetLength())
  446. {
  447. return true;
  448. }
  449. }
  450. }
  451. }
  452. }
  453. return false;
  454. }
  455. BOOL COTSParticle::IfContain(CPoint pos)
  456. {
  457. CRect rec = m_rectParticle;
  458. if (pos.x<rec.left || pos.x>rec.right) return false;
  459. if (pos.y<rec.top || pos.y>rec.bottom) return false;
  460. auto segs = m_pFeature->GetSegmentsList();
  461. for (auto seg : segs)
  462. {
  463. if (pos.x >= seg->GetStart() && pos.x <= seg->GetEnd() && pos.y == seg->GetHeight())
  464. {
  465. return true;
  466. }
  467. }
  468. return false;
  469. }
  470. // cleanup
  471. void COTSParticle::Cleanup()
  472. {
  473. }
  474. // initialization
  475. void COTSParticle::Init()
  476. {
  477. // id and tag id
  478. m_nTagId = -1;
  479. //m_nSearchId = -1;
  480. m_nAnalysisId = -1;
  481. m_nFieldId = -1;
  482. m_nType = OTS_PARTICLE_TYPE::UNCLASSIFY;
  483. // type
  484. m_classifyId = 0;
  485. // area
  486. m_dArea = 0;
  487. // gray
  488. m_cAveGray = 0;
  489. // feature
  490. m_pFeature = COTSFeaturePtr(new COTSFeature());
  491. m_dFeretDiameter=0;
  492. //最小外接矩形的宽度
  493. m_Width=0;
  494. //最小外接矩形的长度
  495. m_Height=0;
  496. // STD chemical type
  497. m_Perimeter=0;
  498. m_DMax=0;
  499. m_DMin=0;
  500. m_Dp=0;
  501. m_Di=0;
  502. m_Dm=0;
  503. m_De=0;
  504. m_Orientation=0;
  505. GB_CHEMICAL_TYPE m_nChemical= GB_CHEMICAL_TYPE::INVALID;
  506. m_pXRayInfo = nullptr;
  507. }
  508. // duplication
  509. void COTSParticle::Duplicate(const COTSParticle& a_oSource)
  510. {
  511. // initialization
  512. Init();
  513. // copy data over
  514. // id and tag id
  515. m_nTagId = a_oSource.m_nTagId;
  516. //m_nSearchId = a_oSource.m_nSearchId;
  517. m_nAnalysisId = a_oSource.m_nAnalysisId;
  518. m_nFieldId = a_oSource.m_nFieldId;
  519. // type
  520. m_classifyId = a_oSource.m_classifyId;
  521. // area
  522. m_dArea = a_oSource.m_dArea;
  523. // rectangle
  524. m_rectParticle = a_oSource.m_rectParticle;
  525. // gray
  526. m_cAveGray = a_oSource.m_cAveGray;
  527. // x-ray position
  528. m_poiXRayPos = a_oSource.m_poiXRayPos;
  529. m_Width = a_oSource.m_Width;
  530. m_Height = a_oSource.m_Height;
  531. m_classifyName = a_oSource.m_classifyName;
  532. m_TypeColor = a_oSource.m_TypeColor;
  533. // feature
  534. m_pFeature = COTSFeaturePtr(new COTSFeature(*a_oSource.m_pFeature.get()));
  535. }
  536. double COTSParticle::GetMorphologyVectorNorm()
  537. {
  538. if (m_vectorNorm == 0)
  539. {
  540. auto data = GetMorphData();
  541. double d1 = 0;
  542. double sumOfchannelPower = 0;
  543. for (int i = 0; i < data.size(); i++)
  544. {
  545. double r1 = data[i];
  546. r1 *= r1;
  547. sumOfchannelPower = sumOfchannelPower + r1;
  548. }
  549. d1 = sqrt(sumOfchannelPower);
  550. m_vectorNorm = d1;
  551. return m_vectorNorm;
  552. }
  553. else
  554. {
  555. return m_vectorNorm;
  556. }
  557. }
  558. std::vector<double> COTSParticle::GetMorphData()
  559. {
  560. std::vector<double> morphData;
  561. morphData.push_back(m_OTSRect.GetWidth());
  562. morphData.push_back(m_OTSRect.GetHeight());
  563. morphData.push_back(m_cAveGray);
  564. morphData.push_back(this->GetActualArea());
  565. morphData.push_back(m_DMax);
  566. morphData.push_back(m_DMin);
  567. morphData.push_back(this->GetDMean());
  568. morphData.push_back(this->GetDElong());
  569. morphData.push_back(this->GetDPerp());
  570. morphData.push_back(this->GetFeretDiameter());
  571. morphData.push_back(this->GetOrientation());
  572. morphData.push_back(this->GetPerimeter());
  573. morphData.push_back(this->GetDInscr());
  574. morphData.push_back(this->GetAspectRatio());
  575. return morphData;
  576. }
  577. }