123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683 |
- #include "stdafx.h"
- #include "OTSParticle.h"
- #include "Element.h"
- #include "Convert.h"
- namespace OTSDATA {
- // COTSParticle
- // constructor
- COTSParticle::COTSParticle() // constructor
- {
- Init();
- //headerParticle = NULL;
- }
- COTSParticle::COTSParticle(const COTSParticle& a_oSource) // copy constructor
- {
- // can't copy itself
- if (&a_oSource == this)
- {
- return;
- }
- // copy data over
- Duplicate(a_oSource);
- }
- COTSParticle::COTSParticle(COTSParticle* a_poSource) // copy constructor
- {
- // can't copy itself
- if (a_poSource == this)
- {
- return;
- }
- // copy data over
- Duplicate(*a_poSource);
- }
- COTSParticle& COTSParticle::operator=(const COTSParticle& a_oSource) // =operator
- {
- // cleanup
- Cleanup();
- // copy the class data over
- Duplicate(a_oSource);
- // return class
- return *this;
- }
- BOOL COTSParticle::operator==(const COTSParticle& a_oSource) // ==operator
- {
- // return FASLE, if the two segments list are in different size
- return ( m_nTagId == a_oSource.m_nTagId &&
- //m_nSearchId == a_oSource.m_nSearchId &&
- m_nAnalysisId == a_oSource.m_nAnalysisId &&
- m_nFieldId == a_oSource.m_nFieldId &&
- m_dArea == a_oSource.m_dArea &&
- m_cAveGray == a_oSource.m_cAveGray &&
- m_classifyId == a_oSource.m_classifyId &&
- m_poiXRayPos == a_oSource.m_poiXRayPos &&
- *(m_pFeature.get()) == *(a_oSource.m_pFeature.get()));
-
- }
- COTSParticle::~COTSParticle() // destructor
- {
- Cleanup();
- }
- void COTSParticle::Serialize(bool isStoring, tinyxml2::XMLDocument * classDoc, tinyxml2::XMLElement * rootNode)
- {
- xmls::xInt xTagId;
- xmls::xInt xnSearchId;
- xmls::xInt xnAnalysisId;
- xmls::xInt xnFieldId;
- xmls::xDouble xdArea;
- xmls::xRect xrectParticle;
- xmls::xInt xcAveGray;
- xmls::xInt xType;
- xmls::xPoint xpoiXRayPos;
- xmls::Slo slo;
- slo.Register("TagId", &xTagId);
- slo.Register("SearchId", &xnSearchId);
- slo.Register("AnalysisId", &xnAnalysisId);
- slo.Register("FieldId", &xnFieldId);
- slo.Register("Area", &xdArea);
- slo.Register("rectParticle", &xrectParticle);
- slo.Register("AveGray", &xcAveGray);
- slo.Register("Type", &xType);
- slo.Register("poiXRayPos", &xpoiXRayPos);
- slo.Register("Feature", m_pFeature.get());
- if (isStoring)
- {
- xTagId = m_nTagId;
- //xnSearchId = m_nSearchId;
- xnAnalysisId = m_nAnalysisId;
- xnFieldId = m_nFieldId;
- xdArea = m_dArea;
- xrectParticle = m_rectParticle;
- xcAveGray = m_cAveGray;
- xType = m_classifyId;
- xpoiXRayPos = m_poiXRayPos;
- slo.Serialize(true, classDoc, rootNode);
- }
- else
- {
- slo.Serialize(false, classDoc, rootNode);
- m_nTagId = xTagId.value();
- //m_nSearchId = xnSearchId.value();
- m_nAnalysisId = xnAnalysisId.value();
- m_nFieldId = xnFieldId.value();
- m_dArea = xdArea.value();
- m_rectParticle = xrectParticle.value();
- m_cAveGray = xcAveGray.value();
- m_classifyId = xType.value();
- m_poiXRayPos = xpoiXRayPos.value();
-
- }
- }
- double COTSParticle::GetImgPropertyValueByName(CString propertyName)
- {
- //double pvalue;
- if (propertyName == "Dmax") return this->GetDMax();
- if (propertyName == "Dmin") return this->GetDMin();
- if (propertyName == "Area") return this->GetActualArea();
- if (propertyName == "Dferet") return this->GetFeretDiameter();
- if (propertyName == "Width") return this->GetMinWidth();
- if (propertyName == "Height") return this->GetMinHeight();
- if (propertyName == "Perimeter") return this->GetPerimeter();
- if (propertyName == "Dperp") return this->GetDPerp();
- if (propertyName == "Dinscr") return this->GetDInscr();
- if (propertyName == "Dmean") return this->GetDMean();
- if (propertyName == "Orientation") return this->GetOrientation();
- if (propertyName == "Delong") return this->GetDElong();
- if (propertyName == "AspectElong") return this->GetAspectElong();
- if (propertyName == "Dequalcircle") return this->GetEqualCircleDiameter();
- if (propertyName == "Aspect") return this->GetAspectRatio();
- if (propertyName == "Vedio") return this->GetVideo();
- if (propertyName == "X") return this->GetXRayPos().x;
- if (propertyName == "Y") return this->GetXRayPos().y;
- //return pvalue;
- }
- std::string COTSParticle::GetImgPortraitString()
- {
- CString str;
- CString dmax = Convert::MFC::ToString(this->GetDMax());
- CString dmin = Convert::MFC::ToString(this->GetDMin());
- CString dmean = Convert::MFC::ToString(this->GetDMean());
- CString dinsc = Convert::MFC::ToString(this->GetDInscr());
- CString dferet = Convert::MFC::ToString(this->GetFeretDiameter());
- CString dperp = Convert::MFC::ToString(this->GetDPerp());
- CString delong = Convert::MFC::ToString(this->GetDElong());
- CString aspect = Convert::MFC::ToString(this->GetAspectRatio());
- CString area = Convert::MFC::ToString(this->GetActualArea());
- CString video = Convert::MFC::ToString(this->GetVideo());
- CString width = Convert::MFC::ToString(this->GetOTSRect().GetWidth());
- CString height = Convert::MFC::ToString(this->GetOTSRect().GetHeight());
- CString orientation = Convert::MFC::ToString(this->GetOrientation());
- 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(" ") +
- delong + _T(" ") + _T("Aspect:")+aspect + _T(" ") + width + _T(" ") + height + _T(" ") +_T("orientation:")+ orientation;
- return Convert::MFC::CStringToString(str);
-
- }
- double COTSParticle::CalculateSimilarity(COTSParticlePtr part)
- {
- //estimate the area first----------
- double arearatio = 0;
- if (this->GetActualArea() <= part->GetActualArea())
- {
- arearatio = this->GetActualArea() / part->GetActualArea();
- }
- else
- {
- arearatio = part->GetActualArea() / this->GetActualArea();
- }
- if (arearatio < 0.85)
- {
- return 0;
- }
- //-------------------------
- auto data1 = this->GetMorphData();
- auto data2 = part->GetMorphData();
- // 公式: (x1y1+x2y2+x3y3+...x2000y2000) / (sqrt(x1^2 + x2^2 + ...x2000^2) * sqrt(y1^2 + y2^2 + ...y2000^2))
- double dotProduct = 0;
- double d1 = 0;
- double d2 = 0;
- for (int i = 0; i < data1.size(); i++)
- {
- double r1 = data1[i];
- double r2 = data2[i];
- r1 *= r2;
- dotProduct = dotProduct + r1;
- }
- d1 =this->GetMorphologyVectorNorm();
- d2 = part->GetMorphologyVectorNorm();
- return (0 == d1 || 0 == d2) ? 0 : dotProduct / (d1 * d2);
- }
- BOOL COTSParticle::CalCoverRectFromSegment()
- {
- ASSERT(m_pFeature);
- if (!m_pFeature)
- {
- return FALSE;
- }
- COTSSegmentsList a_listSegment = m_pFeature->GetSegmentsList();
- // height is most height - lowest + 1
- // width is the widest - thinnest + 1
- int nSize = (int)a_listSegment.size();
- // no segment, no need to compute
- if (nSize <= 0)
- {
- return FALSE;
- }
- // get the most highest, lowest, widest, thinness
- int nHmin = a_listSegment[0]->GetHeight();
- int nHmax = a_listSegment[0]->GetHeight();
- int nWmin = a_listSegment[0]->GetStart();
- int nWmax = a_listSegment[0]->GetStart() + a_listSegment[0]->GetLength() - 1;
- // loop segment list
- for (auto pSegement : a_listSegment)
- {
- int nHt = pSegement->GetHeight();
- if (nHt < nHmin)
- {
- nHmin = nHt;
- }
- if (nHt > nHmax)
- {
- nHmax = nHt;
- }
- int nSt = pSegement->GetStart();
- int nEd = pSegement->GetStart() + pSegement->GetLength() - 1;
- if (nSt < nWmin)
- {
- nWmin = nSt;
- }
- if (nEd > nWmax)
- {
- nWmax = nEd;
- }
- }
- if (nHmin > nHmax || nWmin > nWmax)
- {
- return FALSE;
- }
- // get the rect
- m_rectParticle.top = nHmin;
- m_rectParticle.left = nWmin;
- m_rectParticle.bottom = nHmax;
- m_rectParticle.right = nWmax;
-
- return TRUE;
- }
-
- BOOL COTSParticle::CalPixelArea()
- {
- ASSERT(m_pFeature);
- if (!m_pFeature)
- {
- return FALSE;
- }
- COTSSegmentsList a_listSegment = m_pFeature->GetSegmentsList();
- // Area is all the segment's length add.
- int nSize = (int)a_listSegment.size();
- m_dPixelArea = 0;
- // no segment, no need to compute
- if (nSize <= 0)
- {
- return FALSE;
- }
- // loop segment list
- for (auto pSegement : a_listSegment)
- {
- m_dPixelArea += (double)pSegement->GetLength();
- }
- return TRUE;
- }
- BOOL COTSParticle::CalXRayPos()
- {
- ASSERT(m_pFeature);
- if (!m_pFeature)
- {
- return FALSE;
- }
- COTSSegmentsList a_listSegment = m_pFeature->GetSegmentsList();
- // all the pixels add
- int nSize = (int)a_listSegment.size();
- // no segment, no need to compute
- if (nSize <= 0)
- {
- return FALSE;
- }
- // get the 1/3 high part, the longest
- if(m_rectParticle.IsRectNull())
- {
- if (!CalCoverRectFromSegment())
- return FALSE;
- }
-
- COTSSegmentsList listSegmentLength;
- listSegmentLength.clear();
- int nHMax = a_listSegment[0]->GetHeight();
- int nHMin = a_listSegment[0]->GetHeight();
- for (auto pSegment : a_listSegment)
- {
- int nH = pSegment->GetHeight();
- if (nH < nHMin)
- {
- nHMin = nH;
- }
- if (nH > nHMax)
- {
- nHMax = nH;
- }
- }
- int nHeight = m_rectParticle.Height();
- int nHStart = (int)(nHeight / 3 + nHMin + 0.5);
- int nHEnd = (int)(2 * nHeight / 3 + nHMax + 0.5);
- for (auto pSegment : a_listSegment)
- {
- int nH = pSegment->GetHeight();
- if (nH >= nHStart && nH <= nHEnd)
- {
- COTSSegmentPtr pSegmentNew = COTSSegmentPtr(new COTSSegment(*pSegment.get()));
- listSegmentLength.push_back(pSegmentNew);
- }
- }
- // get the longest length in the middle 1/3 part
- if ((int)listSegmentLength.size() < 0)
- {
- return FALSE;
- }
-
- int nLMax = listSegmentLength[0]->GetLength();
- for (auto pSegment : listSegmentLength)
- {
- int nL = pSegment->GetLength();
- if (nL > nLMax)
- {
- nLMax = nL;
- }
- }
- COTSSegmentsList listSegmentMaxLength;
- listSegmentMaxLength.clear();
- // find the segment has the longest length
- for (auto pSegment : listSegmentLength)
- {
- if (pSegment->GetLength() == nLMax)
- {
- COTSSegmentPtr pSegmentNew = COTSSegmentPtr(new COTSSegment(*pSegment.get()));
- listSegmentMaxLength.push_back(pSegmentNew);
- }
- }
- // get the middle longest length
- if ((int)listSegmentMaxLength.size() < 0)
- {
- return FALSE;
- }
-
- COTSSegmentPtr pSegCur = listSegmentMaxLength[0];
- int nSegStart = pSegCur->GetStart();
- int nSegHeight = pSegCur->GetHeight();
- int nSegLength = pSegCur->GetLength();
- CPoint ptSegCenter;
- ptSegCenter.x = (int)(nSegStart + nSegLength / 2 + 0.5);
- ptSegCenter.y = nSegHeight;
- CPoint ptPartCenter = m_rectParticle.CenterPoint();
-
- double nHToMMin = sqrt((ptSegCenter.x - ptPartCenter.x)*(ptSegCenter.x - ptPartCenter.x) + (ptSegCenter.y - ptPartCenter.y)*(ptSegCenter.y - ptPartCenter.y));
-
- for (auto pSegment : listSegmentMaxLength)
- {
- nSegStart = pSegment->GetStart();
- nSegHeight = pSegment->GetHeight();
- nSegLength = pSegment->GetLength();
- ptSegCenter.x = (int)(nSegStart + nSegLength / 2 + 0.5);
- ptSegCenter.y = nSegHeight;
- double nHToM = sqrt((ptSegCenter.x - ptPartCenter.x)*(ptSegCenter.x - ptPartCenter.x) + (ptSegCenter.y - ptPartCenter.y)*(ptSegCenter.y - ptPartCenter.y));
- if (nHToM < nHToMMin)
- {
- nHToMMin = nHToM;
- }
- }
- // get the middle longest segment
- for (auto pSegment : listSegmentMaxLength)
- {
- nSegStart = pSegment->GetStart();
- nSegHeight = pSegment->GetHeight();
- nSegLength = pSegment->GetLength();
- ptSegCenter.x = (int)(nSegStart + nSegLength / 2 + 0.5);
- ptSegCenter.y = nSegHeight;
- double nHToM = sqrt((ptSegCenter.x - ptPartCenter.x)*(ptSegCenter.x - ptPartCenter.x) + (ptSegCenter.y - ptPartCenter.y)*(ptSegCenter.y - ptPartCenter.y));
-
- if (nHToM == nHToMMin)
- {
- m_poiXRayPos = ptPartCenter;
- break;
- }
- }
-
- return TRUE;
- }
- BOOL COTSParticle::CalActualArea(double pixelsize)
- {
- auto pixelarea = GetPixelArea();
- m_dArea = pixelarea * pixelsize * pixelsize;
- return true;
- }
- void COTSParticle::SetFeature(COTSFeaturePtr a_pFeature)
- {
- ASSERT(a_pFeature);
- if (!a_pFeature)
- {
- return;
- }
- //m_pFeature = COTSFeaturePtr(new COTSFeature(*a_pFeature.get()));
- m_pFeature = a_pFeature;
- }
- BOOL COTSParticle::IsConnected(COTSParticle* a_p, int fldwidth, int fldheight, int direction)
- {
- //decide if two on boundary particles are connected.
- typedef enum class SORTING_DIRECTION
- {
- LEFT = 1,
- DOWN = 2,
- RIGHT = 3,
- UP = 4
- }SORTING_DIRECTION;
- SORTING_DIRECTION di = (SORTING_DIRECTION)direction;
- for (auto s : m_pFeature->GetSegmentsList())
- {
- for (auto a_seg : a_p->GetFeature()->GetSegmentsList())
- {
- if (di == SORTING_DIRECTION::LEFT || di == SORTING_DIRECTION::RIGHT)
- {
- if (s->GetHeight() == a_seg->GetHeight())
- {
- if ((s->GetStart() + s->GetLength()) == fldwidth && a_seg->GetStart() == 0)
- {
- return true;//left connected to neighbor's right.
- }
- if ((a_seg->GetStart() + a_seg->GetLength()) == fldwidth && s->GetStart() == 0)
- {
- return true;//
- }
- }
- }
- if (di == SORTING_DIRECTION::UP || di == SORTING_DIRECTION::DOWN)
- {
- if (s->GetHeight() == 0 && a_seg->GetHeight() == fldheight - 1)//the lowest height of the segment is the height of the field minus 1.
- {
- if (s->GetStart() >= a_seg->GetStart() && s->GetStart() <= a_seg->GetStart() + a_seg->GetLength())
- {
- return true;
- }
- if (a_seg->GetStart() >= s->GetStart() && a_seg->GetStart() <= s->GetStart() + s->GetLength())
- {
- return true;
- }
- }
- if (a_seg->GetHeight() == 0 && s->GetHeight() == fldheight - 1)
- {
- if (s->GetStart() >= a_seg->GetStart() && s->GetStart() <= a_seg->GetStart() + a_seg->GetLength())
- {
- return true;
- }
- if (a_seg->GetStart() >= s->GetStart() && a_seg->GetStart() <= s->GetStart() + s->GetLength())
- {
- return true;
- }
- }
- }
- }
- }
- return false;
- }
- BOOL COTSParticle::IfContain(CPoint pos)
- {
- CRect rec = m_rectParticle;
- if (pos.x<rec.left || pos.x>rec.right) return false;
- if (pos.y<rec.top || pos.y>rec.bottom) return false;
- auto segs = m_pFeature->GetSegmentsList();
- for (auto seg : segs)
- {
- if (pos.x >= seg->GetStart() && pos.x <= seg->GetEnd() && pos.y == seg->GetHeight())
- {
- return true;
- }
- }
- return false;
- }
- // cleanup
- void COTSParticle::Cleanup()
- {
- }
- // initialization
- void COTSParticle::Init()
- {
- // id and tag id
- m_nTagId = -1;
- //m_nSearchId = -1;
- m_nAnalysisId = -1;
- m_nFieldId = -1;
- m_nType = OTS_PARTICLE_TYPE::UNCLASSIFY;
- // type
- m_classifyId = 0;
- // area
- m_dArea = 0;
- // gray
- m_cAveGray = 0;
- // feature
- m_pFeature = COTSFeaturePtr(new COTSFeature());
- m_dFeretDiameter=0;
- //最小外接矩形的宽度
- m_Width=0;
- //最小外接矩形的长度
- m_Height=0;
- // STD chemical type
- m_Perimeter=0;
- m_DMax=0;
- m_DMin=0;
- m_Dp=0;
- m_Di=0;
- m_Dm=0;
- m_De=0;
- m_Orientation=0;
- GB_CHEMICAL_TYPE m_nChemical= GB_CHEMICAL_TYPE::INVALID;
- m_pXRayInfo = nullptr;
-
- }
- // duplication
- void COTSParticle::Duplicate(const COTSParticle& a_oSource)
- {
- // initialization
- Init();
- // copy data over
- // id and tag id
- m_nTagId = a_oSource.m_nTagId;
- //m_nSearchId = a_oSource.m_nSearchId;
- m_nAnalysisId = a_oSource.m_nAnalysisId;
- m_nFieldId = a_oSource.m_nFieldId;
- // type
- m_classifyId = a_oSource.m_classifyId;
-
- // area
- m_dArea = a_oSource.m_dArea;
- // rectangle
- m_rectParticle = a_oSource.m_rectParticle;
- // gray
- m_cAveGray = a_oSource.m_cAveGray;
- // x-ray position
- m_poiXRayPos = a_oSource.m_poiXRayPos;
- m_Width = a_oSource.m_Width;
- m_Height = a_oSource.m_Height;
- m_classifyName = a_oSource.m_classifyName;
- m_TypeColor = a_oSource.m_TypeColor;
-
- // feature
- m_pFeature = COTSFeaturePtr(new COTSFeature(*a_oSource.m_pFeature.get()));
- }
- double COTSParticle::GetMorphologyVectorNorm()
- {
- if (m_vectorNorm == 0)
- {
- auto data = GetMorphData();
- double d1 = 0;
- double sumOfchannelPower = 0;
- for (int i = 0; i < data.size(); i++)
- {
- double r1 = data[i];
- r1 *= r1;
- sumOfchannelPower = sumOfchannelPower + r1;
- }
- d1 = sqrt(sumOfchannelPower);
- m_vectorNorm = d1;
- return m_vectorNorm;
- }
- else
- {
- return m_vectorNorm;
- }
- }
- std::vector<double> COTSParticle::GetMorphData()
- {
- std::vector<double> morphData;
- morphData.push_back(m_OTSRect.GetWidth());
- morphData.push_back(m_OTSRect.GetHeight());
- morphData.push_back(m_cAveGray);
- morphData.push_back(this->GetActualArea());
- morphData.push_back(m_DMax);
- morphData.push_back(m_DMin);
- morphData.push_back(this->GetDMean());
- morphData.push_back(this->GetDElong());
- morphData.push_back(this->GetDPerp());
- morphData.push_back(this->GetFeretDiameter());
- morphData.push_back(this->GetOrientation());
- morphData.push_back(this->GetPerimeter());
- morphData.push_back(this->GetDInscr());
- morphData.push_back(this->GetAspectRatio());
- return morphData;
- }
- }
|