#include "stdafx.h" #include "OTSFieldMgr.h" #include "OTSImageProcess.h" #include "otsdataconst.h" #include "BSEImgFileMgr.h" #include "SmplMsrResultFile.h" #include "PosXrayFileMgr.h" #include "IncAFileMgr.h" namespace OTSMODEL { using namespace OTSIMGPROC; COTSFieldMgr::COTSFieldMgr() : m_pFieldData(nullptr) { } COTSFieldMgr::~COTSFieldMgr() { } // init BOOL COTSFieldMgr::Init(COTSFieldDataPtr a_pFieldData, CBSEImgPtr a_pBSEImg) { ASSERT(a_pFieldData); if (!a_pFieldData) { // invalid field data. LogErrorTrace(__FILE__, __LINE__, _T("Init: invalid field data.")); return FALSE; } ASSERT(a_pBSEImg); if (!a_pBSEImg) { // invalid BSE image. LogErrorTrace(__FILE__, __LINE__, _T("SetBSEImage: invalid BSE image.")); return FALSE; } // keep the original field data pointer m_pFieldData = a_pFieldData; // make a copy of the BSE image //m_pBSEImg = CBSEImgPtr(new CBSEImg(a_pBSEImg.get())); m_pBSEImg = a_pBSEImg; // create measure result m_pMsrResults = CMsrResultsPtr(new CMsrResults()); // ok, return TRUE return TRUE; } // field data void COTSFieldMgr::SetOTSFieldData(COTSFieldDataPtr a_pOTSFieldData) { ASSERT(a_pOTSFieldData); if (!a_pOTSFieldData) { // invalid field data. LogErrorTrace(__FILE__, __LINE__, _T("SetOTSFieldData: invalid field data.")); return; } m_pFieldData = a_pOTSFieldData; } // BSE image void COTSFieldMgr::SetBSEImage(CBSEImgPtr a_pBSEImg) { ASSERT(a_pBSEImg); if (!a_pBSEImg) { // invalid BSE image. LogErrorTrace(__FILE__, __LINE__, _T("SetBSEImage: invalid BSE image.")); return; } m_pBSEImg = a_pBSEImg; } void COTSFieldMgr::SetSearchPosXayList(CPosXraysList& a_listPosXray, BOOL a_bClear) { if (a_bClear) { m_listSearchPosXray.clear(); } for (auto pPosXray : a_listPosXray) { m_listSearchPosXray.push_back(pPosXray); } } void COTSFieldMgr::SetAnalysisPosXayList(CPosXraysList& a_listPosXray, BOOL a_bClear) { if (a_bClear) { m_listAnalysisPosXray.clear(); } for (auto pPosXray : a_listPosXray) { m_listAnalysisPosXray.push_back(pPosXray); } } // remove BSE image BackGround BOOL COTSFieldMgr::RemoveBSEImageBG(COTSImageProcessParamPtr a_pImageProcessParam) { ASSERT(m_pFieldData); if (!m_pFieldData) { LogErrorTrace(__FILE__, __LINE__, _T("RemoveBSEImageBG: there is no field data")); return FALSE; } ASSERT(m_pBSEImg); if (!m_pBSEImg) { LogErrorTrace(__FILE__, __LINE__, _T("RemoveBSEImageBG: there is no image data")); return FALSE; } ASSERT(a_pImageProcessParam); if (!a_pImageProcessParam) { LogErrorTrace(__FILE__, __LINE__, _T("RemoveBSEImageBG: there is no image process data")); return FALSE; } int nWidthImg = m_pBSEImg->GetWidth(); int nHeightImg = m_pBSEImg->GetHeight(); long nImgSize = nWidthImg * nHeightImg; BYTE* pPixel = new BYTE[nImgSize]; BYTE* pSrcImg = m_pBSEImg->GetImageDataPointer(); BYTE* pTargetImg = new BYTE[nImgSize]; BYTE* pTempImg = new BYTE[nImgSize]; memset(pPixel, 0, sizeof(BYTE)*nImgSize); memset(pTargetImg, 0, sizeof(BYTE)*nImgSize); memset(pTempImg, 0, sizeof(BYTE)*nImgSize); long nBGStart = a_pImageProcessParam->GetBGGray().GetStart(); long nBGEnd = a_pImageProcessParam->GetBGGray().GetEnd(); long nPtStart = a_pImageProcessParam->GetParticleGray().GetStart(); long nPtEnd = a_pImageProcessParam->GetParticleGray().GetEnd(); // delete background and not not particle ones long nNumParticle = 0; for (int i = 0; i < nImgSize; i++) { if (pSrcImg[i] >= nBGStart && pSrcImg[i] <= nBGEnd) { pPixel[i] = 0; } else { pPixel[i] = 255; nNumParticle++; } } if (nNumParticle == 0) { COTSParticleList listParticleEmpty; listParticleEmpty.clear(); m_pFieldData->SetParticleList(listParticleEmpty); memset(pPixel, 0, nImgSize); LogInfoTrace(__FILE__, __LINE__, _T("RemoveBSEImageBG: no particle is found.")); } else { memcpy(pTempImg, pPixel, nImgSize); // get the area image memcpy(pPixel, pTempImg, nImgSize); COTSImageProcess::BErode3(pPixel, pTargetImg, 5, nHeightImg, nWidthImg); COTSImageProcess::BDilate3(pTargetImg, pPixel, 5, nHeightImg, nWidthImg); memcpy(pPixel, pTargetImg, nImgSize); COTSParticleList listParticleOut; if (!GetParticles(nWidthImg, nHeightImg, pPixel, listParticleOut)) { COTSParticleList listParticleEmpty; listParticleEmpty.clear(); m_pFieldData->SetParticleList(listParticleEmpty); memset(pPixel, 0, nImgSize); } else { // form a image only have particles on COTSSegmentsList listImage; for (auto pParticle : listParticleOut) { COTSFeaturePtr pFeature = pParticle->GetFeature(); COTSSegmentsList listSegment = pFeature->GetSegmentsList(); long nPixelNum = 0; long nPixelAll = 0; int nStartS = 0; int nHeightS = 0; int nLengthS = 0; for (auto pSegment : listSegment) { // update image list COTSSegmentPtr pSegNew = COTSSegmentPtr(new COTSSegment(*pSegment.get())); listImage.push_back(pSegNew); // get particle average gray nStartS = pSegment->GetStart(); nHeightS = pSegment->GetHeight(); nLengthS = pSegment->GetLength(); nPixelNum += (long)nLengthS; if (nHeightS > nHeightImg) { LogErrorTrace(__FILE__, __LINE__, _T("seg height is wrong.")); return FALSE; } if ((nStartS + nLengthS - 1) > nWidthImg) { LogErrorTrace(__FILE__, __LINE__, _T("seg starst and length is wrong.")); return FALSE; } for (int i = 0; i < nLengthS; i++) { if ((nStartS + i) > nWidthImg) { LogErrorTrace(__FILE__, __LINE__, _T("seg start is wrong.")); return FALSE; } else if (nHeightS > nHeightImg) { LogErrorTrace(__FILE__, __LINE__, _T("seg height is wrong.")); return FALSE; } long nValueTemp = (long)*(pSrcImg + nHeightS * nWidthImg + nStartS + i); nPixelAll += nValueTemp; } } BYTE nAveGray = (BYTE)(nPixelAll / nPixelNum); pParticle->SetAveGray(nAveGray); pParticle->SetArea(nPixelNum); } m_pFieldData->SetParticleList(listParticleOut); memset(pPixel, 0, nImgSize); int nS, nH, nL; for (auto pSegment : listImage) { nS = pSegment->GetStart(); nH = pSegment->GetHeight(); nL = pSegment->GetLength(); memcpy((pPixel + nH * nWidthImg + nS), (pSrcImg + nH * nWidthImg + nS), nL); } // only used to show clearly. for (int i = 0; i < nImgSize; i++) { if (*(pPixel + i) == 0) { *(pPixel + i) = 255; } else { continue; } } } } delete[]pPixel; delete[]pTargetImg; delete[]pTempImg; return TRUE; } // remove oversize particles and small particles and get analysis particles list BOOL COTSFieldMgr::ProcessParticles(COTSImageProcessParamPtr a_pImageProcessParam, double a_dPixelSize, COTSParticleList& a_listParticlesOut) { // safety check ASSERT(a_pImageProcessParam); if (!a_pImageProcessParam) { // invalid image process parameter pointer LogErrorTrace(__FILE__, __LINE__, _T("ProcessParticles: invalid image process parameter pointer.")); return FALSE; } if (a_dPixelSize <= 0) { LogErrorTrace(__FILE__, __LINE__, _T("ProcessParticles: invalid pixel size data.")); return FALSE; } // get area range CDoubleRange oAreaRange = a_pImageProcessParam->GetIncArea(); double nAreaLow = (oAreaRange.GetStart()/2) * (oAreaRange.GetStart()/2) * 3.14159; double nAreaHigh = (oAreaRange.GetEnd()/2) * (oAreaRange.GetEnd()/2) * 3.14159; // gray level range CIntRange oParticleGrayRange = a_pImageProcessParam->GetParticleGray(); int nGrayLow = oParticleGrayRange.GetStart(); int nGrayHigh = oParticleGrayRange.GetEnd(); // get particles list COTSParticleList listParticles = m_pFieldData->GetParticleList(); // go through each particles a_listParticlesOut.clear(); int nTagId = 0; //int nSearchPartId = 0; int nAnalysisPartId = 0; for (auto pParticle : listParticles) { // get particle area double dPartArea = pParticle->GetArea(); dPartArea = dPartArea * a_dPixelSize * a_dPixelSize; pParticle->SetArea(dPartArea); // get average gray level int nAveGrayLevel = pParticle->GetAveGray(); // set particle tag id pParticle->SetTagId(nTagId++); // set field id pParticle->SetFieldId(m_pFieldData->GetId()); // oversize particles if (dPartArea > (double)nAreaHigh) { pParticle->SetType((int)OTS_PARTCLE_TYPE::OVERSIZE); LogInfoTrace(__FILE__, __LINE__, _T("ProcessParticles: oversize particle, particle size is %f"), dPartArea); continue; } // too small to measure else if (dPartArea < (double)nAreaLow) { pParticle->SetType((int)OTS_PARTCLE_TYPE::SMALL); LogInfoTrace(__FILE__, __LINE__, _T("ProcessParticles: samll particle, particle size is %f"), dPartArea); continue; } // gray level is not in the measurement range else if (nGrayLow > nAveGrayLevel || nAveGrayLevel > nGrayHigh) { pParticle->SetType((int)OTS_PARTCLE_TYPE::AVE_GRAY_NOT_INRANRE); LogInfoTrace(__FILE__, __LINE__, _T("ProcessParticles: gray not interested particle, particle gray is %d, gray range(%d, %d)"), nAveGrayLevel, nGrayLow, nGrayHigh); continue; } // add the particle into the output particles list pParticle->SetType((int)OTS_PARTCLE_TYPE::NOT_IDENTIFIED); pParticle->SetAnalysisId(nAnalysisPartId); a_listParticlesOut.push_back(pParticle); ++nAnalysisPartId; } // ok, return TRUE return TRUE; } BOOL COTSFieldMgr::IdentifyParticle(COTSImageProcessParamPtr a_pImageProcessParam, CPosXraysList& a_listXRay) { ASSERT(a_pImageProcessParam); if (!a_pImageProcessParam) { LogErrorTrace(__FILE__, __LINE__, _T("IdentifyParticle: there is no image process data")); return FALSE; } CDoubleRange oAreaRange = a_pImageProcessParam->GetIncArea(); double nAreaLow = oAreaRange.GetStart(); double nAreaHigh = oAreaRange.GetEnd(); CIntRange oParticleGrayRange = a_pImageProcessParam->GetParticleGray(); int nGrayLow = oParticleGrayRange.GetStart(); int nGrayHigh = oParticleGrayRange.GetEnd(); COTSParticleList listParticle = m_pFieldData->GetParticleList(); a_listXRay.clear(); int nSearchPartId = 0; int nXrayIndex = 0; for (auto pParticle : listParticle) { if (!pParticle->CalArea()) { LogErrorTrace(__FILE__, __LINE__, _T("IdentifyParticle: failed to calculate particle area.")); return FALSE; } double dArea = pParticle->GetArea(); BYTE nAveGray = pParticle->GetAveGray(); if (dArea > (double)nAreaHigh) { pParticle->SetType((int)OTS_PARTCLE_TYPE::OVERSIZE); } else if (dArea < (double)nAreaLow) { pParticle->SetType((int)OTS_PARTCLE_TYPE::SMALL); } else { if (nAveGray <= nGrayHigh && nAveGray >= nGrayLow) { pParticle->SetType((int)OTS_PARTCLE_TYPE::SEARCH_X_RAY); if (!pParticle->CalXRayPos()) { LogErrorTrace(__FILE__, __LINE__, _T("IdentifyParticle: failed to calculate x-ray position.")); return FALSE; } CPoint pt = pParticle->GetXRayPos(); CPosXrayPtr pPosXray = CPosXrayPtr(new CPosXray()); nXrayIndex++; pPosXray->SetIndex(nXrayIndex); pPosXray->SetPartTagId(nSearchPartId); pPosXray->SetPosition(pt); pPosXray->SetScanFieldId(m_pFieldData->GetId()); pPosXray->SetFeatureId(nSearchPartId); a_listXRay.push_back(pPosXray); } } nSearchPartId++; } return TRUE; } // create x-ray list for a set of particles BOOL COTSFieldMgr::CreateXrayList(COTSParticleList& a_listParticles, CPosXraysList& a_listPosXRay) { // go through particles list a_listPosXRay.clear(); int nXrayIndex = 0; for (auto pPart : a_listParticles) { if (!pPart->CalXRayPos()) { LogErrorTrace(__FILE__, __LINE__, _T("CreateXrayList: failed to calculate x-ray position.")); return FALSE; } // get xray position CPoint poi = pPart->GetXRayPos(); // create a x-ray CPosXrayPtr pPosXray = CPosXrayPtr(new CPosXray()); // set x-ray position pPosXray->SetPosition(poi); // set particle tag id pPosXray->SetPartTagId(pPart->GetTagId()); pPosXray->SetIndex(nXrayIndex++); // set field id pPosXray->SetScanFieldId(pPart->GetFieldId()); // add the x-ray into the list a_listPosXRay.push_back(pPosXray); } return TRUE; } // field on-line classification BOOL COTSFieldMgr::OnLineClassification() { // safety check ASSERT(m_pFieldData); if (!m_pFieldData) { // invalid field data pointer LogErrorTrace(__FILE__, __LINE__, _T("OnLineClassification: invalid field data pointer.")); return FALSE; } ASSERT(m_pMsrResults); if (!m_pMsrResults) { // invalid measure results pointer LogErrorTrace(__FILE__, __LINE__, _T("OnLineClassification: invalid measure results pointer.")); return FALSE; } // get particles list of the field data COTSParticleList& listParticles = m_pFieldData->GetParticleList(); // go through the particles list for (auto pParticle : listParticles) { // create a measure result item CMsrResultItemPtr pMsrResultItem = CMsrResultItemPtr(new CMsrResultItem()); pMsrResultItem->SetTypeId(pParticle->GetType()); pMsrResultItem->SetArea((int)(pParticle->GetArea() + 0.5)); pMsrResultItem->SetNumber(1); pMsrResultItem->SetName(pParticle->TypeName()); m_pMsrResults->CumulateMeasureResults(pMsrResultItem); } return TRUE; } void COTSFieldMgr::SetMsrResult(CMsrResultsPtr a_pMsrResults) { ASSERT(a_pMsrResults); if (!a_pMsrResults) { LogErrorTrace(__FILE__, __LINE__, _T("SetMsrResult: invalid pointer.")); return; } m_pMsrResults = a_pMsrResults; } // save field files BOOL COTSFieldMgr::SaveFieldFiles() { ASSERT(m_pFieldData); if (!m_pFieldData) { LogErrorTrace(__FILE__, __LINE__, _T("SaveFieldFiles: invalid field data pointer.")); return FALSE; } CString strFieldFileFolder = m_pFieldData->GetFieldFileFolder(); ASSERT(m_pBSEImg); if (!m_pBSEImg) { LogErrorTrace(__FILE__, __LINE__, _T("SaveFieldFiles: invalid BSE data pointer.")); return FALSE; } CBSEImgFileMgrPtr pBSEImgFileMgr = CBSEImgFileMgrPtr(new CBSEImgFileMgr()); pBSEImgFileMgr->SetBSEImg(m_pBSEImg); int nId = m_pFieldData->GetId(); CString sFieldId; sFieldId.Format(_T("%d"), nId); // get field BSE file pathname CString strBSEFilePathname = strFieldFileFolder + SMPL_MSR_RESULT_FIELDS_BSE + sFieldId + BMP_IMG_FILE_EXT; if (!pBSEImgFileMgr->SaveIntoBitmap(strBSEFilePathname)) { LogErrorTrace(__FILE__, __LINE__, _T("SaveFieldFiles: save BSE file failed.")); return FALSE; } // analysis x ray list CString strXRayAnalysisFilename = strFieldFileFolder + _T("\\") + SMPL_MSR_RESULT_ANALYSIS_X_RAY_FILE; CPosXrayFileMgrPtr pPosAnalysisXrayFileMgr = CPosXrayFileMgrPtr(new CPosXrayFileMgr(strXRayAnalysisFilename)); pPosAnalysisXrayFileMgr->SetPosXrayList(m_listAnalysisPosXray, TRUE); pPosAnalysisXrayFileMgr->SetHasElement(TRUE); if (!pPosAnalysisXrayFileMgr->Save(strXRayAnalysisFilename)) { LogErrorTrace(__FILE__, __LINE__, _T("SaveFieldFiles: save analysis x-ray failed.")); return FALSE; } // IncA Data list CString strIncAFilename = strFieldFileFolder + _T("\\") + SMPL_MSR_RESULT_INCLUSION_FILE; CIncAFileMgrPtr pIncAFileMgr = CIncAFileMgrPtr(new CIncAFileMgr(strIncAFilename)); pIncAFileMgr->SetPosXrayList(m_listAnalysisPosXray, TRUE); COTSParticleList listIncAParticle=m_pFieldData->GetParticleList(); pIncAFileMgr->SetParticleList(listIncAParticle, TRUE); pIncAFileMgr->SetFieldPos(m_pFieldData->GetPosition()); pIncAFileMgr->SetMsrStatus(this->GetMsrStatus()); if (!pIncAFileMgr->Save(strIncAFilename)) { LogErrorTrace(__FILE__, __LINE__, _T("SaveFieldFiles: save inclusion file failed.")); return FALSE; } // ok, return TRUE return TRUE; } BOOL COTSFieldMgr::DoSearchXRayAnalysis(COTSXRayParamPtr a_pXrayParam, std::vector>& a_listFeatures, CPosXraysList& a_listXRay) { ASSERT(a_pXrayParam); if (!a_pXrayParam) { LogErrorTrace(__FILE__, __LINE__, _T("DoSearchXRayAnalysis: there is no image process data")); return FALSE; } long nSearchCount = a_pXrayParam->GetXRaySearchCount(); ASSERT(m_pFieldData); if (!m_pFieldData) { LogErrorTrace(__FILE__, __LINE__, _T("DoSearchXRayAnalysis: there is no field data")); return FALSE; } COTSParticleList listParticle = m_pFieldData->GetParticleList(); if (listParticle.empty()) { LogErrorTrace(__FILE__, __LINE__, _T("DoSearchXRayAnalysis: there is no particles")); return FALSE; } if (listParticle.size() < m_listSearchPosXray.size()) { LogErrorTrace(__FILE__, __LINE__, _T("DoSearchXRayAnalysis: there is no enough particles")); return FALSE; } // x-ray data //DWORD* pXrayData = new DWORD[GENERALXRAYCHANNELS]; DWORD* pXrayData; for (auto pPosXray : m_listSearchPosXray) { pXrayData = pPosXray->GetXrayData(); //compute count long nPosCurCount = 0; for (int i = 0; i < GENERALXRAYCHANNELS; i++) { nPosCurCount += pXrayData[i]; } //if this particle should do x-ray analysis if (nPosCurCount >= nSearchCount) { long nPartTagId = pPosXray->GetPartTagId(); COTSParticlePtr pParticle = listParticle[nPartTagId]; pParticle->SetType((int)OTS_PARTCLE_TYPE::NO_ANALYSIS_X_RAY); COTSFeaturePtr pFeature = pParticle->GetFeature(); COTSSegmentsList listSegment = pFeature->GetSegmentsList(); std::vector listBrukSegment; for (auto Segment : listSegment) { BrukerSegment BrukSeg; BrukSeg.XCount = Segment->GetLength(); BrukSeg.Y = Segment->GetHeight(); BrukSeg.XStart = Segment->GetStart(); listBrukSegment.push_back(BrukSeg); } a_listFeatures.push_back(listBrukSegment); CPosXrayPtr pPosXrayNewPtr = CPosXrayPtr(new CPosXray(*pPosXray.get())); a_listXRay.push_back(pPosXrayNewPtr); } } return TRUE; } // Check if is there any particles BOOL COTSFieldMgr::NoParticle() { ASSERT(m_pFieldData); if (!m_pFieldData) { // invalid field data. LogErrorTrace(__FILE__, __LINE__, _T("Init: invalid field data.")); // return TRUE means NO particles return TRUE; } return m_pFieldData->GetParticleList().empty(); } BOOL COTSFieldMgr::GetSegmentList(long a_nWidth, long a_nHeight, const BYTE* a_pPixel, COTSSegmentsList& a_listSegments) { ASSERT(a_pPixel); if (!a_pPixel) { LogErrorTrace(__FILE__, __LINE__, _T("GetSegments: there is no image data")); return FALSE; } long nImgSize = a_nWidth * a_nHeight; a_listSegments.clear(); //1. get segment line by line long nLine, nm, nn; long nStart, nLength; for (nLine = 0; nLine < a_nHeight; nLine++) { for (nm = 0; nm < a_nWidth; nm += (nLength + 1)) { nLength = 0; // get start if (*(a_pPixel + nLine*a_nWidth + nm) != 0) { nStart = nm; nLength++; //get length for (nn = nm + 1; nn < a_nWidth; nn++) { // check if segment is over, break if (nLength != 0) { if (*(a_pPixel + nLine*a_nWidth + nn) == 0) break; } if (*(a_pPixel + nLine*a_nWidth + nn) != 0) { nLength++; } } // generate segment COTSSegmentPtr pSegment = COTSSegmentPtr(new COTSSegment(nLine, nStart, nLength)); a_listSegments.push_back(pSegment); } else { continue; } } } if ((int)a_listSegments.size() == 0) { LogErrorTrace(__FILE__, __LINE__, _T("no particle is found.")); return FALSE; } return TRUE; } BOOL COTSFieldMgr::GetFeatureList1(COTSSegmentsList& a_listSegments, COTSFeatureList& a_listFeatures) { COTSSegmentsList listSegmentNew; std::map mapOneLineSegments; for each(auto s in a_listSegments) { mapOneLineSegments[s->GetHeight()].push_back(s);//sorting all the segments base on the line number. } std::map::iterator lineItr = mapOneLineSegments.begin();//find the highest line while (lineItr != mapOneLineSegments.end()) { for (auto s = lineItr->second.begin(); s < lineItr->second.end(); )//find one segment of this line. { COTSSegmentPtr bottomSeg = *s; listSegmentNew.clear(); listSegmentNew.push_back(*s); s = lineItr->second.erase(s); std::map::iterator tempItr = lineItr; tempItr++; for (; tempItr != mapOneLineSegments.end(); tempItr++)//find all other lines of segments { if (tempItr->first - bottomSeg->GetHeight() > 1) { break; } for (auto nextLineSegment = tempItr->second.begin(); nextLineSegment < tempItr->second.end();)//find next line's all segments { if (((*nextLineSegment)->GetStart() - (bottomSeg->GetStart() + bottomSeg->GetLength())) > 1) { break; } if (bottomSeg->UpDownConection(**nextLineSegment)) { listSegmentNew.push_back(*nextLineSegment); bottomSeg = *nextLineSegment; nextLineSegment = tempItr->second.erase(nextLineSegment); break; } if (tempItr->second.size() > 0) { nextLineSegment++; } else { break; } } } COTSFeaturePtr pFeature = COTSFeaturePtr(new COTSFeature()); pFeature->SetSegmentsList(listSegmentNew); //check if this new feature is connected with other found feature. COTSSegmentPtr topSeg = listSegmentNew[0];//find the toppest segment of this new feature. COTSSegmentPtr bottomSegment = listSegmentNew[listSegmentNew.size() - 1];//find the lowest segment of this new feature. bool haveMerged = false; for each(auto f in a_listFeatures) { for (auto seg : f->GetSegmentsList()) { if (bottomSegment->UpDownConection(*seg) || topSeg->UpDownConection(*seg)) { COTSSegmentsList segs = f->GetSegmentsList(); for (auto s : listSegmentNew) { segs.push_back(s); } f->SetSegmentsList(segs); haveMerged = true; break; } } if (haveMerged) { break; } } if (!haveMerged) { a_listFeatures.push_back(pFeature); } if (lineItr->second.size() == 0) { break; } } lineItr++; } return true; } BOOL COTSFieldMgr::ChangeFeaturelist(COTSFeatureList& a_listFeatures, COTSParticleList& a_listParticle) { if (a_listFeatures.size() == 0) { LogErrorTrace(__FILE__, __LINE__, _T("ChangeFeaturelist: there is no feature in the list.")); return FALSE; } // compute Rect for (auto pFeature : a_listFeatures) { COTSParticlePtr pParticle = COTSParticlePtr(new COTSParticle()); pParticle->SetFeature(pFeature); if(!pParticle->CalCoverRect()) { LogErrorTrace(__FILE__, __LINE__, _T("ChangeFeaturelist: failed to get particle rect.")); return FALSE; } a_listParticle.push_back(pParticle); } if ((int)a_listParticle.size() == 0) { LogErrorTrace(__FILE__, __LINE__, _T("Can't get particle.")); return FALSE; } return TRUE; } BOOL COTSFieldMgr::GetParticles(long a_nWidth, long a_nHeight, const BYTE* a_pPixel, COTSParticleList& a_listParticles) { ASSERT(a_pPixel); if (!a_pPixel) { LogErrorTrace(__FILE__, __LINE__, _T("GetParticles: there is no image data")); return FALSE; } a_listParticles.clear(); COTSSegmentsList listSegment; listSegment.clear(); //1. get segment line by line if(!GetSegmentList(a_nWidth, a_nHeight, a_pPixel, listSegment)) { LogErrorTrace(__FILE__, __LINE__, _T("GetParticles:failed to get segments.")); return FALSE; } if ((int)listSegment.size() == 0) { LogErrorTrace(__FILE__, __LINE__, _T("no particle is found.")); return FALSE; } //2. save the temp feature COTSFeatureList listFeature; listFeature.clear(); if (!GetFeatureList1(listSegment, listFeature)) { LogErrorTrace(__FILE__, __LINE__, _T("GetParticles:failed to get up down segment list.")); return FALSE; } if ((int)listFeature.size() == 0) { LogErrorTrace(__FILE__, __LINE__, _T("no particle is found.")); return FALSE; } COTSParticleList listParticles; listParticles.clear(); if (!ChangeFeaturelist(listFeature, a_listParticles)) { LogErrorTrace(__FILE__, __LINE__, _T("can't change feature to particle.")); return FALSE; } return TRUE; } BOOL COTSFieldMgr::GetIncAParticleList(COTSParticleList& a_listParticleOut) { // field data ASSERT(m_pFieldData); if (!m_pFieldData) { LogErrorTrace(__FILE__, __LINE__, _T("GetIncAParticleList: empty filed data pointer.")); return FALSE; } COTSParticleList listParticleIn = m_pFieldData->GetParticleList(); a_listParticleOut.clear(); for (auto pParticle : listParticleIn) { int nType = pParticle->GetType(); if (nType > (int)OTS_PARTCLE_TYPE::NO_ANALYSIS_X_RAY) { a_listParticleOut.push_back(pParticle); } } return TRUE; } BOOL COTSFieldMgr::CalIncAParticleImageProp(double a_pixelSize) { // field data ASSERT(m_pFieldData); if (!m_pFieldData) { LogErrorTrace(__FILE__, __LINE__, _T("CalIncAParticleImageProp: empty filed data pointer.")); return FALSE; } COTSParticleList& listParticleIn = m_pFieldData->GetParticleList(); for (auto pParticle : listParticleIn) { OTSIMGPROC::COTSImageProcess::CalcuParticleImagePropertes(pParticle, a_pixelSize); } return TRUE; } BOOL COTSFieldMgr::CalMergedParticleImageProp(COTSParticleList mergedParticles, double a_pixelSize) { for (auto pParticle : mergedParticles) { OTSIMGPROC::COTSImageProcess::CalcuParticleImagePropertes(pParticle, a_pixelSize); } return TRUE; } }