OTSParticle.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. #include "stdafx.h"
  2. #include "OTSParticle.h"
  3. #include "Element.h"
  4. namespace OTSDATA {
  5. // COTSParticle
  6. // constructor
  7. COTSParticle::COTSParticle() // constructor
  8. {
  9. Init();
  10. }
  11. COTSParticle::COTSParticle(const COTSParticle& a_oSource) // copy constructor
  12. {
  13. // can't copy itself
  14. if (&a_oSource == this)
  15. {
  16. return;
  17. }
  18. // copy data over
  19. Duplicate(a_oSource);
  20. }
  21. COTSParticle::COTSParticle(COTSParticle* a_poSource) // copy constructor
  22. {
  23. // can't copy itself
  24. if (a_poSource == this)
  25. {
  26. return;
  27. }
  28. // copy data over
  29. Duplicate(*a_poSource);
  30. }
  31. COTSParticle& COTSParticle::operator=(const COTSParticle& a_oSource) // =operator
  32. {
  33. // cleanup
  34. Cleanup();
  35. // copy the class data over
  36. Duplicate(a_oSource);
  37. // return class
  38. return *this;
  39. }
  40. BOOL COTSParticle::operator==(const COTSParticle& a_oSource) // ==operator
  41. {
  42. // return FASLE, if the two segments list are in different size
  43. return ( m_nTagId == a_oSource.m_nTagId &&
  44. m_nSearchId == a_oSource.m_nSearchId &&
  45. m_nAnalysisId == a_oSource.m_nAnalysisId &&
  46. m_nFieldId == a_oSource.m_nFieldId &&
  47. m_dArea == a_oSource.m_dArea &&
  48. m_cAveGray == a_oSource.m_cAveGray &&
  49. m_nTypeId == a_oSource.m_nTypeId &&
  50. m_poiXRayPos == a_oSource.m_poiXRayPos &&
  51. *(m_pFeature.get()) == *(a_oSource.m_pFeature.get()));
  52. }
  53. COTSParticle::~COTSParticle() // destructor
  54. {
  55. Cleanup();
  56. }
  57. void COTSParticle::Serialize(bool isStoring, tinyxml2::XMLDocument * classDoc, tinyxml2::XMLElement * rootNode)
  58. {
  59. xmls::xInt xTagId;
  60. xmls::xInt xnSearchId;
  61. xmls::xInt xnAnalysisId;
  62. xmls::xInt xnFieldId;
  63. xmls::xDouble xdArea;
  64. xmls::xRect xrectParticle;
  65. xmls::xInt xcAveGray;
  66. xmls::xInt xType;
  67. xmls::xPoint xpoiXRayPos;
  68. xmls::Slo slo;
  69. slo.Register("TagId", &xTagId);
  70. slo.Register("SearchId", &xnSearchId);
  71. slo.Register("AnalysisId", &xnAnalysisId);
  72. slo.Register("FieldId", &xnFieldId);
  73. slo.Register("Area", &xdArea);
  74. slo.Register("rectParticle", &xrectParticle);
  75. slo.Register("AveGray", &xcAveGray);
  76. slo.Register("Type", &xType);
  77. slo.Register("poiXRayPos", &xpoiXRayPos);
  78. slo.Register("Feature", m_pFeature.get());
  79. if (isStoring)
  80. {
  81. xTagId = m_nTagId;
  82. xnSearchId = m_nSearchId;
  83. xnAnalysisId = m_nAnalysisId;
  84. xnFieldId = m_nFieldId;
  85. xdArea = m_dArea;
  86. xrectParticle = m_rectParticle;
  87. xcAveGray = m_cAveGray;
  88. xType = m_nTypeId;
  89. xpoiXRayPos = m_poiXRayPos;
  90. slo.Serialize(true, classDoc, rootNode);
  91. }
  92. else
  93. {
  94. slo.Serialize(false, classDoc, rootNode);
  95. m_nTagId = xTagId.value();
  96. m_nSearchId = xnSearchId.value();
  97. m_nAnalysisId = xnAnalysisId.value();
  98. m_nFieldId = xnFieldId.value();
  99. m_dArea = xdArea.value();
  100. m_rectParticle = xrectParticle.value();
  101. m_cAveGray = xcAveGray.value();
  102. m_nTypeId = xType.value();
  103. m_poiXRayPos = xpoiXRayPos.value();
  104. }
  105. }
  106. double COTSParticle::GetImgPropertyValueByName(CString propertyName)
  107. {
  108. //double pvalue;
  109. if (propertyName == "Dmax") return this->GetDMax();
  110. if (propertyName == "Dmin") return this->GetDMin();
  111. if (propertyName == "Area") return this->GetArea();
  112. if (propertyName == "Dferet") return this->GetFeretDiameter();
  113. if (propertyName == "With") return this->GetWidth();
  114. if (propertyName == "Height") return this->GetHeight();
  115. if (propertyName == "Perimeter") return this->GetPerimeter();
  116. if (propertyName == "Dperp") return this->GetDPerp();
  117. if (propertyName == "Dinscr") return this->GetDInscr();
  118. if (propertyName == "Dmean") return this->GetDMean();
  119. if (propertyName == "Orientation") return this->GetOrientation();
  120. if (propertyName == "Delong") return this->GetDElong();
  121. if (propertyName == "AspectElong") return this->GetAspectElong();
  122. if (propertyName == "Dequalcircle") return this->GetEqualCircleDiameter();
  123. if (propertyName == "Aspect") return this->GetAspectRatio();
  124. if (propertyName == "Vedio") return this->GetVideo();
  125. if (propertyName == "X") return this->GetXRayPos().x;
  126. if (propertyName == "Y") return this->GetXRayPos().y;
  127. //return pvalue;
  128. }
  129. BOOL COTSParticle::CalCoverRect()
  130. {
  131. ASSERT(m_pFeature);
  132. if (!m_pFeature)
  133. {
  134. return FALSE;
  135. }
  136. COTSSegmentsList a_listSegment = m_pFeature->GetSegmentsList();
  137. // height is most height - lowest + 1
  138. // width is the widest - thinnest + 1
  139. int nSize = (int)a_listSegment.size();
  140. // no segment, no need to compute
  141. if (nSize <= 0)
  142. {
  143. return FALSE;
  144. }
  145. // get the most highest, lowest, widest, thinness
  146. int nHmin = a_listSegment[0]->GetHeight();
  147. int nHmax = a_listSegment[0]->GetHeight();
  148. int nWmin = a_listSegment[0]->GetStart();
  149. int nWmax = a_listSegment[0]->GetStart() + a_listSegment[0]->GetLength() - 1;
  150. // loop segment list
  151. for (auto pSegement : a_listSegment)
  152. {
  153. int nHt = pSegement->GetHeight();
  154. if (nHt < nHmin)
  155. {
  156. nHmin = nHt;
  157. }
  158. if (nHt > nHmax)
  159. {
  160. nHmax = nHt;
  161. }
  162. int nSt = pSegement->GetStart();
  163. int nEd = pSegement->GetStart() + pSegement->GetLength() - 1;
  164. if (nSt < nWmin)
  165. {
  166. nWmin = nSt;
  167. }
  168. if (nEd > nWmax)
  169. {
  170. nWmax = nEd;
  171. }
  172. }
  173. if (nHmin > nHmax || nWmin > nWmax)
  174. {
  175. return FALSE;
  176. }
  177. // get the rect
  178. m_rectParticle.top = nHmin;
  179. m_rectParticle.left = nWmin;
  180. m_rectParticle.bottom = nHmax;
  181. m_rectParticle.right = nWmax;
  182. return TRUE;
  183. }
  184. BOOL COTSParticle::CalArea()
  185. {
  186. ASSERT(m_pFeature);
  187. if (!m_pFeature)
  188. {
  189. return FALSE;
  190. }
  191. COTSSegmentsList a_listSegment = m_pFeature->GetSegmentsList();
  192. // Area is all the segment's length add.
  193. int nSize = (int)a_listSegment.size();
  194. m_dArea = 0;
  195. // no segment, no need to compute
  196. if (nSize <= 0)
  197. {
  198. return FALSE;
  199. }
  200. // loop segment list
  201. for (auto pSegement : a_listSegment)
  202. {
  203. m_dArea += (double)pSegement->GetLength();
  204. }
  205. return TRUE;
  206. }
  207. BOOL COTSParticle::CalXRayPos()
  208. {
  209. ASSERT(m_pFeature);
  210. if (!m_pFeature)
  211. {
  212. return FALSE;
  213. }
  214. COTSSegmentsList a_listSegment = m_pFeature->GetSegmentsList();
  215. // all the pixels add
  216. int nSize = (int)a_listSegment.size();
  217. // no segment, no need to compute
  218. if (nSize <= 0)
  219. {
  220. return FALSE;
  221. }
  222. // get the 1/3 high part, the longest
  223. if(m_rectParticle.IsRectNull())
  224. {
  225. if (!CalCoverRect())
  226. return FALSE;
  227. }
  228. COTSSegmentsList listSegmentLength;
  229. listSegmentLength.clear();
  230. int nHMax = a_listSegment[0]->GetHeight();
  231. int nHMin = a_listSegment[0]->GetHeight();
  232. for (auto pSegment : a_listSegment)
  233. {
  234. int nH = pSegment->GetHeight();
  235. if (nH < nHMin)
  236. {
  237. nHMin = nH;
  238. }
  239. if (nH > nHMax)
  240. {
  241. nHMax = nH;
  242. }
  243. }
  244. int nHeight = m_rectParticle.Height();
  245. int nHStart = (int)(nHeight / 3 + nHMin + 0.5);
  246. int nHEnd = (int)(2 * nHeight / 3 + nHMax + 0.5);
  247. for (auto pSegment : a_listSegment)
  248. {
  249. int nH = pSegment->GetHeight();
  250. if (nH >= nHStart && nH <= nHEnd)
  251. {
  252. COTSSegmentPtr pSegmentNew = COTSSegmentPtr(new COTSSegment(*pSegment.get()));
  253. listSegmentLength.push_back(pSegmentNew);
  254. }
  255. }
  256. // get the longest length in the middle 1/3 part
  257. if ((int)listSegmentLength.size() < 0)
  258. {
  259. return FALSE;
  260. }
  261. int nLMax = listSegmentLength[0]->GetLength();
  262. for (auto pSegment : listSegmentLength)
  263. {
  264. int nL = pSegment->GetLength();
  265. if (nL > nLMax)
  266. {
  267. nLMax = nL;
  268. }
  269. }
  270. COTSSegmentsList listSegmentMaxLength;
  271. listSegmentMaxLength.clear();
  272. // find the segment has the longest length
  273. for (auto pSegment : listSegmentLength)
  274. {
  275. if (pSegment->GetLength() == nLMax)
  276. {
  277. COTSSegmentPtr pSegmentNew = COTSSegmentPtr(new COTSSegment(*pSegment.get()));
  278. listSegmentMaxLength.push_back(pSegmentNew);
  279. }
  280. }
  281. // get the middle longest length
  282. if ((int)listSegmentMaxLength.size() < 0)
  283. {
  284. return FALSE;
  285. }
  286. COTSSegmentPtr pSegCur = listSegmentMaxLength[0];
  287. int nSegStart = pSegCur->GetStart();
  288. int nSegHeight = pSegCur->GetHeight();
  289. int nSegLength = pSegCur->GetLength();
  290. CPoint ptSegCenter;
  291. ptSegCenter.x = (int)(nSegStart + nSegLength / 2 + 0.5);
  292. ptSegCenter.y = nSegHeight;
  293. CPoint ptPartCenter = m_rectParticle.CenterPoint();
  294. double nHToMMin = sqrt((ptSegCenter.x - ptPartCenter.x)*(ptSegCenter.x - ptPartCenter.x) + (ptSegCenter.y - ptPartCenter.y)*(ptSegCenter.y - ptPartCenter.y));
  295. for (auto pSegment : listSegmentMaxLength)
  296. {
  297. nSegStart = pSegment->GetStart();
  298. nSegHeight = pSegment->GetHeight();
  299. nSegLength = pSegment->GetLength();
  300. ptSegCenter.x = (int)(nSegStart + nSegLength / 2 + 0.5);
  301. ptSegCenter.y = nSegHeight;
  302. double nHToM = sqrt((ptSegCenter.x - ptPartCenter.x)*(ptSegCenter.x - ptPartCenter.x) + (ptSegCenter.y - ptPartCenter.y)*(ptSegCenter.y - ptPartCenter.y));
  303. if (nHToM < nHToMMin)
  304. {
  305. nHToMMin = nHToM;
  306. }
  307. }
  308. // get the middle longest segment
  309. for (auto pSegment : listSegmentMaxLength)
  310. {
  311. nSegStart = pSegment->GetStart();
  312. nSegHeight = pSegment->GetHeight();
  313. nSegLength = pSegment->GetLength();
  314. ptSegCenter.x = (int)(nSegStart + nSegLength / 2 + 0.5);
  315. ptSegCenter.y = nSegHeight;
  316. double nHToM = sqrt((ptSegCenter.x - ptPartCenter.x)*(ptSegCenter.x - ptPartCenter.x) + (ptSegCenter.y - ptPartCenter.y)*(ptSegCenter.y - ptPartCenter.y));
  317. if (nHToM == nHToMMin)
  318. {
  319. m_poiXRayPos = ptPartCenter;
  320. break;
  321. }
  322. }
  323. return TRUE;
  324. }
  325. void COTSParticle::SetFeature(COTSFeaturePtr a_pFeature)
  326. {
  327. ASSERT(a_pFeature);
  328. if (!a_pFeature)
  329. {
  330. return;
  331. }
  332. //m_pFeature = COTSFeaturePtr(new COTSFeature(*a_pFeature.get()));
  333. m_pFeature = a_pFeature;
  334. }
  335. // cleanup
  336. void COTSParticle::Cleanup()
  337. {
  338. }
  339. // initialization
  340. void COTSParticle::Init()
  341. {
  342. // initialization
  343. // id and tag id
  344. m_nTagId = -1;
  345. m_nSearchId = -1;
  346. m_nAnalysisId = -1;
  347. m_nFieldId = -1;
  348. // type
  349. m_nTypeId = (int)OTS_PARTCLE_TYPE::INVALID;
  350. // area
  351. m_dArea = 0;
  352. // gray
  353. m_cAveGray = 0;
  354. // feature
  355. m_pFeature = COTSFeaturePtr(new COTSFeature());
  356. m_dFeretDiameter=0;
  357. //最小外接矩形的宽度
  358. m_Width=0;
  359. //最小外接矩形的长度
  360. m_Height=0;
  361. // STD chemical type
  362. m_Perimeter=0;
  363. m_DMax=0;
  364. m_DMin=0;
  365. m_Dp=0;
  366. m_Di=0;
  367. m_Dm=0;
  368. m_De=0;
  369. m_Orientation=0;
  370. GB_CHEMICAL_TYPE m_nChemical= GB_CHEMICAL_TYPE::INVALID;
  371. }
  372. // duplication
  373. void COTSParticle::Duplicate(const COTSParticle& a_oSource)
  374. {
  375. // initialization
  376. Init();
  377. // copy data over
  378. // id and tag id
  379. m_nTagId = a_oSource.m_nTagId;
  380. m_nSearchId = a_oSource.m_nSearchId;
  381. m_nAnalysisId = a_oSource.m_nAnalysisId;
  382. m_nFieldId = a_oSource.m_nFieldId;
  383. // type
  384. m_nTypeId = a_oSource.m_nTypeId;
  385. // area
  386. m_dArea = a_oSource.m_dArea;
  387. // rectangle
  388. m_rectParticle = a_oSource.m_rectParticle;
  389. // gray
  390. m_cAveGray = a_oSource.m_cAveGray;
  391. // x-ray position
  392. m_poiXRayPos = a_oSource.m_poiXRayPos;
  393. m_Width = a_oSource.m_Width;
  394. m_Height = a_oSource.m_Height;
  395. m_TypeName = a_oSource.m_TypeName;
  396. m_TypeColor = a_oSource.m_TypeColor;
  397. // feature
  398. m_pFeature = COTSFeaturePtr(new COTSFeature(*a_oSource.m_pFeature.get()));
  399. }
  400. }