浏览代码

improve removeduplicateparticles algorithm

gsp 1 年之前
父节点
当前提交
c6c22c5a5a

+ 5 - 1
OTSCPP/OTSClrInterface/CommonClr/OTSParticleClr.h

@@ -174,7 +174,11 @@ namespace OTSCLRINTERFACE {
 			return m_Particle->get()->SetFeretDiameter(val);
 		}
 		double CalculateSimilarity(COTSParticleClr^ part);
-
+		String^ GetImgPortraitString()
+		{
+			return gcnew String(m_Particle->get()->GetImgPortraitString().c_str());
+		
+		}
 		String^ GetTypeName()
 		{
 			return gcnew  String(m_Particle->get()->GetClassifyName().c_str());

+ 2 - 2
OTSCPP/OTSData/Convert.h

@@ -107,8 +107,8 @@ namespace Convert
         CString ToString(const long& val) { CString str; str.Format(_T("%ld"), val); return str; }
         CString ToString(const unsigned int& val) { CString str; str.Format(_T("%ud"), val); return str; }
         CString ToString(const unsigned long& val) { CString str; str.Format(_T("%uld"), val); return str; }
-        CString ToString(const float& val) { CString str; str.Format(_T("%f"), val); return str; }
-        CString ToString(const double& val) { CString str; str.Format(_T("%lf"), val); return str; }
+        CString ToString(const float& val) { CString str; str.Format(_T("%.2f"), val); return str; }
+        CString ToString(const double& val) { CString str; str.Format(_T("%.2f"), val); return str; }
 
 
         double             ToDouble(const CString& str) { return  _ttof(str); }

+ 6 - 26
OTSCPP/OTSData/InfrastructureClass.cd

@@ -6,7 +6,7 @@
       <Compartment Name="Methods" Collapsed="true" />
     </Compartments>
     <TypeIdentifier>
-      <HashCode>KvqiiIGoKRwUSBZBAFhQIRJAgCXR8FOyBEJzFkAlsYc=</HashCode>
+      <HashCode>qvyiuIGqaRgUyIrBIFhUKULQgSRVsFPyNmpzB0E1ugc=</HashCode>
       <FileName>OTSParticle.h</FileName>
     </TypeIdentifier>
     <ShowAsAssociation>
@@ -39,7 +39,7 @@
       <Compartment Name="Methods" Collapsed="true" />
     </Compartments>
     <TypeIdentifier>
-      <HashCode>AAAAAAAAAAAAQCAIBAAAAQBAACQQIAAAQAIiIEAAIAQ=</HashCode>
+      <HashCode>AAAAAAAAAAAAQCAIhAAAAQBAACQQIAAAQAIiIEAAKAQ=</HashCode>
       <FileName>OTSSegment.h</FileName>
     </TypeIdentifier>
   </Class>
@@ -49,7 +49,7 @@
       <Compartment Name="Methods" Collapsed="true" />
     </Compartments>
     <TypeIdentifier>
-      <HashCode>KABABAAABCAAIQQEAABABcAAACAAIxAAAhIqAMIAAAA=</HashCode>
+      <HashCode>KABABAEABCAAIQAEAABABUAQACgAIxAAAhYqAMIAAAA=</HashCode>
       <FileName>OTSFieldData.h</FileName>
     </TypeIdentifier>
     <ShowAsAssociation>
@@ -82,7 +82,7 @@
       <Compartment Name="Methods" Collapsed="true" />
     </Compartments>
     <TypeIdentifier>
-      <HashCode>gCEACIAAggAIAAAAABAAAQAAAgEAIAgQAAAjAEgABAA=</HashCode>
+      <HashCode>gCEACIAAggAIACAAABAAAQAAAiEAIAgQAAgjAEgABAA=</HashCode>
       <FileName>SEMDataMsr.h</FileName>
     </TypeIdentifier>
   </Class>
@@ -190,31 +190,11 @@
     <Compartments>
       <Compartment Name="Methods" Collapsed="true" />
     </Compartments>
-    <InheritanceLine Type="OTSDATA::CPosXrayInfo" FixedFromPoint="true">
-      <Path>
-        <Point X="4" Y="11.562" />
-        <Point X="2.375" Y="11.562" />
-        <Point X="2.375" Y="12.75" />
-      </Path>
-    </InheritanceLine>
     <TypeIdentifier>
-      <HashCode>BAMgAAAAgAAAAAAAAAQApAAEAAAAIAAAACBiAEAAAAA=</HashCode>
+      <HashCode>BEOAAIBEiCAAQAASIRUApRQEAIAAIgAAACRiAEYEQAE=</HashCode>
       <FileName>PosXray.h</FileName>
     </TypeIdentifier>
   </Class>
-  <Class Name="OTSDATA::CPosXrayInfo">
-    <Position X="4" Y="10" Width="2.25" />
-    <Compartments>
-      <Compartment Name="Methods" Collapsed="true" />
-    </Compartments>
-    <TypeIdentifier>
-      <HashCode>AECAAIBECCAAQAAQAREQARAAAIAAIgAAAAQiAEYEQEE=</HashCode>
-      <FileName>PosXrayInfo.h</FileName>
-    </TypeIdentifier>
-    <ShowAsAssociation>
-      <Field Name="m_listElementQuantifyData" />
-    </ShowAsAssociation>
-  </Class>
   <Class Name="OTSDATA::CElementChemistry">
     <Position X="9.75" Y="13.75" Width="4.5" />
     <Compartments>
@@ -241,7 +221,7 @@
       <Compartment Name="Methods" Collapsed="true" />
     </Compartments>
     <TypeIdentifier>
-      <HashCode>EAAAACAAABAAACEQAgAQFABABCAAIEAAgAFiAEEIEAE=</HashCode>
+      <HashCode>EAAAACAAABAABCEQAgEQFABABCAAIEAAgAFiAEEIEAE=</HashCode>
       <FileName>BSEImg.h</FileName>
     </TypeIdentifier>
   </Class>

+ 40 - 4
OTSCPP/OTSData/OTSParticle.cpp

@@ -1,7 +1,7 @@
 #include "stdafx.h"
 #include "OTSParticle.h"
 #include "Element.h"
-
+#include "Convert.h"
 
 namespace OTSDATA {
 
@@ -132,8 +132,8 @@ namespace OTSDATA {
 		if (propertyName == "Dmin") return   this->GetDMin();
 		if (propertyName == "Area") return   this->GetActualArea();
 		if (propertyName == "Dferet") return   this->GetFeretDiameter();
-		if (propertyName == "With") return   this->GetWidth();
-		if (propertyName == "Height") return   this->GetHeight();
+		if (propertyName == "With") 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();
@@ -149,9 +149,45 @@ namespace OTSDATA {
 		//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.8)
+		{
+			return 0;
+		}
+		//-------------------------
 
 		auto  data1 = this->GetMorphData();
 		auto data2 = part->GetMorphData();

+ 6 - 4
OTSCPP/OTSData/OTSParticle.h

@@ -116,11 +116,11 @@ const double Pi = 3.14159;
 		double GetFeretDiameter() { return m_dFeretDiameter; }
 		void SetFeretDiameter(double a_dFeretDiameter) { m_dFeretDiameter = a_dFeretDiameter; }
 		//设置该颗粒的最小外接矩形的宽度
-		void SetWidth(double w) { m_Width = w; }
-		double GetWidth() { return m_Width; }
+		void SetMinWidth(double w) { m_Width = w; }
+		double GetMinWidth() { return m_Width; }
 		//设置该颗粒的最小外接矩形的长度
-		void SetHeight(double h) { m_Height = h; }
-		double GetHeight() { return m_Height; }
+		void SetMinHeight(double h) { m_Height = h; }
+		double GetMinHeight() { return m_Height; }
 		// chemical type
 		GB_CHEMICAL_TYPE GetChemicalType() { return m_nChemical; }//for GB 30834 Method2
 		void SetChemicalType(GB_CHEMICAL_TYPE a_nChemical) { m_nChemical = a_nChemical; }
@@ -159,6 +159,8 @@ const double Pi = 3.14159;
 		}
 		double GetImgPropertyValueByName(CString propertyName);
 
+		std::string GetImgPortraitString();
+
 		double CalculateSimilarity(COTSParticlePtr part);
 		
 		// calculate area, rect, average gray, and xRay pos

+ 7 - 58
OTSCPP/OTSImagePro/OTSImageProcess.cpp

@@ -395,63 +395,7 @@ namespace OTSIMGPROC
 
 		return TRUE;
 	}
-	//void COTSImageProcess::FilterParticlesByOverlap(COTSFieldDataPtr m_pFieldData)
-	//{
-	//	int overlap = m_imageProcessParam->GetOverlapParam();
-
-	//	COTSRect outBorderRect = m_pFieldData->GetOTSRect();
-	//	CPoint p1 = outBorderRect.GetTopLeft();
-	//	CPoint p2 = outBorderRect.GetBottomRight();
-	//	COTSRect inBorderRect = COTSRect(p1.x + overlap, p1.y - overlap, p2.x - overlap, p2.y + overlap);
-	//	CPoint inRecLt = inBorderRect.GetTopLeft();
-	//	CPoint inRecRb = inBorderRect.GetBottomRight();
-	//	COTSParticleList allparts = m_pFieldData->GetParticleList();
-	//	
-	//	COTSParticleList finalparts;
-	//	for (auto p : allparts)
-	//	{
-	//		auto partRec = p->GetOTSRect();
-	//		CPoint lt = partRec.GetTopLeft();
-	//		CPoint rb = partRec.GetBottomRight();
-	//		if (inBorderRect.PointInRect(lt) && inBorderRect.PointInRect(rb))//totally inside
-	//		{
-	//			finalparts.push_back(p);
-	//		}
-	//		if (inBorderRect.PointInRect(rb) && (lt.x<inRecLt.x))//on left side
-	//		{
-	//			if (m_pFieldData->GetLeftBorderParticlesBiasDefine())
-	//			{
-	//				finalparts.push_back(p);
-	//			}
-	//		}
-	//		if (inBorderRect.PointInRect(rb) && ( lt.y>inRecLt.y))//on top side
-	//		{
-	//			if (m_pFieldData->GetUpBorderParticlesBiasDefine())
-	//			{
-	//				finalparts.push_back(p);
-	//			}
-	//		}
-	//		if (inBorderRect.PointInRect(lt) && (rb.x > inRecRb.x) )//on right side
-	//		{
-	//			if (m_pFieldData->GetRightBorderParticlesBiasDefine())
-	//			{
-	//				finalparts.push_back(p);
-	//			}
-	//		}
-	//		if (inBorderRect.PointInRect(lt) && (rb.y < inRecRb.y) )//on bottom side
-	//		{
-	//			if (m_pFieldData->GetDownBorderParticlesBiasDefine())
-	//			{
-	//				finalparts.push_back(p);
-	//			}
-	//		}
-	//		
-	//	}
-
-	//	m_pFieldData->SetParticleList(finalparts);
-	//	
-	//	
-	//}
+	
 	CIntRangePtr COTSImageProcess::CalBackground(CBSEImgPtr m_pBSEImg)
 	{
 		auto ranges = CalcuGrayLevelRange(m_pBSEImg);
@@ -1055,6 +999,8 @@ namespace OTSIMGPROC
 			a_pOTSPart->SetPerimeter((w+h)*2);
 			a_pOTSPart->SetDPerp(MIN(w, h));
 			a_pOTSPart->SetDInscr(MIN(w, h));
+			a_pOTSPart->SetMinWidth(w);
+			a_pOTSPart->SetMinHeight(h);
 			return true;
 		}
 		// calculate the particle image data size, expand 3 pixel at the edge
@@ -1087,6 +1033,8 @@ namespace OTSIMGPROC
 			a_pOTSPart->SetPerimeter((w + h) * 2);
 			a_pOTSPart->SetDPerp(MIN(w, h));
 			a_pOTSPart->SetDInscr(MIN(w, h));
+			a_pOTSPart->SetMinWidth(w);
+			a_pOTSPart->SetMinHeight(h);
 			return true;
 		}
 		int imaxcontour = 0, imax = 0;
@@ -1131,7 +1079,8 @@ namespace OTSIMGPROC
 
 		a_pOTSPart->SetDMin(D_MIN*a_PixelSize);
 
-		
+		a_pOTSPart->SetMinWidth(rRect.size.width);
+		a_pOTSPart->SetMinHeight(rRect.size.height);
 		//----------calculate the perimeter
 		double d = arcLength(listEdge, true);
 		a_pOTSPart->SetPerimeter(d*a_PixelSize);

+ 1 - 1
OTSCPP/OTSImagePro/OTSImageProcessParam.h

@@ -87,7 +87,7 @@ namespace OTSIMGPROC
 		int m_BGRemoveType;
 		int m_autoBGRemoveType;
 		int m_errodDilateParam;
-		int m_overlapParam;
+		int m_overlapParam=0;
 
 		int m_xrayStep;
 		

+ 22 - 17
OTSCPP/OTSRptCalculate/GBCal/CGBCalculate.cpp

@@ -814,11 +814,22 @@ namespace OTSGBCalculate
 
 		CSEMDataMsrPtr pEMDataMsrPtr = pOTSSample->GetSEMDataMsr();
 		ASSERT(pEMDataMsrPtr);
-	
+		// scan parameters
+		CMsrParamsPtr pMsrParam = pOTSSample->GetMsrParams();
+		//CMsrParamsPtr pMsrParam = pOTSSample->get
+		COTSImageScanParamPtr pImgScanParam = pMsrParam->GetImageScanParam();
+
+
+		CSize sizePixelImage = pImgScanParam->GetImageResolution();
+
+		COTSImageProcessParamPtr pImgProcessParam = pMsrParam->GetImageProcessParam();
 
+		double overlap = pImgProcessParam->GetOverlapParam();
+		double scanfldsize = pEMDataMsrPtr->GetScanFieldSize();
+		double pixelsize = scanfldsize / sizePixelImage.cx;
 		// get field width
-		int nOTSFieldWidth = pEMDataMsrPtr->GetScanFieldSize();
-		int nOTSFieldHeight = pEMDataMsrPtr->GetScanFieldHeight();
+		int nOTSFieldWidth = pEMDataMsrPtr->GetScanFieldSize()-2*overlap;
+		int nOTSFieldHeight = pEMDataMsrPtr->GetScanFieldHeight()-2*overlap;
 		if (nOTSFieldWidth == 0 || nOTSFieldHeight==0)
 		{
 			LogErrorTrace(__FILE__, __LINE__, _T("CalGBFields: field width is zero ."));
@@ -827,13 +838,7 @@ namespace OTSGBCalculate
 
 	
 
-		// scan parameters
-		CMsrParamsPtr pMsrParam = pOTSSample->GetMsrParams();
-		//CMsrParamsPtr pMsrParam = pOTSSample->get
-		COTSImageScanParamPtr pImgScanParam = pMsrParam->GetImageScanParam();
-
-	
-		CSize sizePixelImage = pImgScanParam->GetImageResolution();
+		
 		//use OTSField width cal the OTSField height
 		
 
@@ -841,7 +846,7 @@ namespace OTSGBCalculate
 		COTSFieldDataList allOTSFields;
 		allOTSFields = pSmplMsrResultFile->GetFieldData();
 		// convert ots fields to gb fields
-		if (!OTSFieldToGBField( allOTSFields, &m_listGBFields, sizePixelImage, nOTSFieldWidth, nOTSFieldHeight))
+		if (!OTSFieldToGBField( allOTSFields, &m_listGBFields, pixelsize, nOTSFieldWidth, nOTSFieldHeight))
 		{
 			LogErrorTrace(__FILE__, __LINE__, _T("CalGBFields: call OTSFieldToGBField failed."));
 			return m_listGBFields;
@@ -857,7 +862,7 @@ namespace OTSGBCalculate
 
 
 	// Turn OTSField to GBField
-	BOOL CGBCalculate::OTSFieldToGBField(COTSFieldDataList allOTSFields, CGBFieldList* m_listGBFields,CSize sizePixelImage,int nOTSFieldWidth,int nOTSFieldHeight)
+	BOOL CGBCalculate::OTSFieldToGBField(COTSFieldDataList allOTSFields, CGBFieldList* m_listGBFields,double pixelsize,int nOTSFieldWidth,int nOTSFieldHeight)
 	{
 	
 		if (allOTSFields.empty())
@@ -919,7 +924,7 @@ namespace OTSGBCalculate
 				CGBFieldDataPtr pGBFieldData;
 			
 				
-				pGBFieldData = GetOneGBField(rectGBField, allOTSFields, sizePixelImage, nOTSFieldWidth, nOTSFieldHeight);
+				pGBFieldData = GetOneGBField(rectGBField, allOTSFields, pixelsize, nOTSFieldWidth, nOTSFieldHeight);
 				if (!pGBFieldData)
 				{
 					continue;
@@ -963,7 +968,7 @@ namespace OTSGBCalculate
 	//  get the GB field within a rectangle
 	CGBFieldDataPtr CGBCalculate::GetOneGBField(COTSRect a_rectGBField,
 		COTSFieldDataList& allOTSFields,
-		CSize a_sizePixelImage,
+		double pixelsize,
 		int nOTSFieldWidth, int nOTSFieldHeight)
 	{
 		// GB Field handle
@@ -1000,7 +1005,7 @@ namespace OTSGBCalculate
 		}
 
 		
-			pGBFieldData = NormalizeParticlesAndIdentifyChemicalType(a_rectGBField, myOTSFields, a_sizePixelImage, nOTSFieldWidth, nOTSFieldHeight);
+			pGBFieldData = NormalizeParticlesAndIdentifyChemicalType(a_rectGBField, myOTSFields, pixelsize, nOTSFieldWidth, nOTSFieldHeight);
 			pGBFieldData->myReleventOTSFlds = myOTSFields;
 	
 		return pGBFieldData;
@@ -1010,7 +1015,7 @@ namespace OTSGBCalculate
 
 
 	// normalize particles for the GBFields
-	CGBFieldDataPtr CGBCalculate::NormalizeParticlesAndIdentifyChemicalType(COTSRect a_rectGBField, COTSFieldDataList myOTSFields, CSize a_sizePixelImage, int nFieldWidth,int nFieldHeight)
+	CGBFieldDataPtr CGBCalculate::NormalizeParticlesAndIdentifyChemicalType(COTSRect a_rectGBField, COTSFieldDataList myOTSFields, double pixelsize, int nFieldWidth,int nFieldHeight)
 	{
 		// inits
 		CGBFieldDataPtr pGBFieldData(new CGBFieldData);
@@ -1034,7 +1039,7 @@ namespace OTSGBCalculate
 			
 				CPoint fieldTopLeft = OTSField->GetOTSRect().GetTopLeft();
 				double fwidth = nFieldWidth;
-				double pixelsize = fwidth / a_sizePixelImage.cx;
+			/*	double pixelsize = fwidth / a_sizePixelImage.cx;*/
 				CPoint xrayPosInFieldByPixel= part->GetXRayPos();
 
 				CPoint partPos = CPoint(fieldTopLeft.x + xrayPosInFieldByPixel.x * pixelsize, fieldTopLeft.y - xrayPosInFieldByPixel.y * pixelsize);

+ 3 - 3
OTSCPP/OTSRptCalculate/GBCal/CGBCalculate.h

@@ -37,11 +37,11 @@ namespace OTSGBCalculate
 	
 	
 		// convert ots fields to gb fields
-		BOOL OTSFieldToGBField(COTSFieldDataList allOTSFields, CGBFieldList* m_listGBFields,  CSize sizePixelImage, int a_nFieldWidth, int a_nFieldHeight);
+		BOOL OTSFieldToGBField(COTSFieldDataList allOTSFields, CGBFieldList* m_listGBFields, double pixelsize, int a_nFieldWidth, int a_nFieldHeight);
 		//get the GB field within thr rectangle
-		CGBFieldDataPtr GetOneGBField(COTSRect a_rectGBField, COTSFieldDataList& a_listOTSFields, CSize sizePixelImage, int a_nFieldWidth, int nOTSFieldHeight);
+		CGBFieldDataPtr GetOneGBField(COTSRect a_rectGBField, COTSFieldDataList& a_listOTSFields, double pixelsize, int a_nFieldWidth, int nOTSFieldHeight);
 		//  normalize particles for the GBFields
-		CGBFieldDataPtr NormalizeParticlesAndIdentifyChemicalType(COTSRect a_rectGBField, COTSFieldDataList a_listOTSFields, CSize sizePixelImage, int a_nFieldWidth, int a_nFieldHeight);
+		CGBFieldDataPtr NormalizeParticlesAndIdentifyChemicalType(COTSRect a_rectGBField, COTSFieldDataList a_listOTSFields, double pixelsize, int a_nFieldWidth, int a_nFieldHeight);
 
 		//计算一个数据源中所获得的GBFields转化的统计数据
 		CGridDatasList GetGridDataListForOneDataSource(CGBGradeData* gradeData, CALCULATE_TABLE_TYPE tableType);

+ 11 - 3
OTSCommon/ReportModel/ResultFile.cs

@@ -199,9 +199,17 @@ public    enum OTS_Y_AXIS_DIRECTION
         {
             Dictionary<string, object> sampleMembers = ((Dictionary<string, object>)((Dictionary<string, object>)ResultInfo["Sample"])["Members"]);
             Dictionary<string, object> imageProcParam = (Dictionary<string, object>)((Dictionary<string, object>)((Dictionary<string, object>)sampleMembers["MsrParams"])["Members"])["ImageProcessParam"];
-
-            string overlap = imageProcParam["OverlapParam"].ToString();
-            return Convert.ToInt32(overlap);
+            try
+            {
+                string overlap = imageProcParam["OverlapParam"].ToString();
+                return Convert.ToInt32(overlap);
+            }
+            catch 
+            {
+                return 0;
+            }
+           
+            
         }
         public int GetIncASteeltech()
         {

+ 64 - 33
OTSIncAMeasureApp/0-OTSModel/OTSDataType/COTSField.cs

@@ -235,6 +235,8 @@ namespace OTSDataType
                             if ( sim> 0.95)
                             {
                                 log.Warn("remove left side duplicate particle,similarity:" + sim.ToString("F3"));
+                                log.Warn("P1:" + p.GetImgPortraitString());
+                                log.Warn("P2:" + p1.GetImgPortraitString());
                                 findsimilar = true;
                                 break;
                             }
@@ -243,7 +245,11 @@ namespace OTSDataType
                     }
                     if (findsimilar == false)
                     {
-                        finalparts.Add(p);
+                        if (!finalparts.Contains(p))//particles in the four corner are processed more than one time
+                        {
+                            finalparts.Add(p);
+                        }
+                       
                     }
 
 
@@ -280,6 +286,8 @@ namespace OTSDataType
                             if (sim > 0.95)
                             {
                                 log.Warn("remove upside duplicate particle,similarity:" + sim.ToString("F3"));
+                                log.Warn("P1:" + p.GetImgPortraitString());
+                                log.Warn("P2:" + p1.GetImgPortraitString());
                                 findsimilar = true;
                                 break;
                             }
@@ -288,7 +296,10 @@ namespace OTSDataType
                     }
                     if (findsimilar == false)
                     {
-                        finalparts.Add(p);
+                        if (!finalparts.Contains(p))
+                        {
+                            finalparts.Add(p);
+                        }
                     }
 
 
@@ -298,7 +309,10 @@ namespace OTSDataType
             {
                 foreach (var p in this.GetSideParticlesByOverlap(SORTING_DIRECTION.UP, overlap))
                 {
-                    finalparts.Add(p);
+                    if (!finalparts.Contains(p))
+                    {
+                        finalparts.Add(p);
+                    }
                 }
             }
             if (rightField != null && rightField.measureSequence < this.measureSequence)
@@ -325,6 +339,8 @@ namespace OTSDataType
                             if (sim > 0.95)
                             {
                                 log.Warn("remove right side duplicate particle,similarity:" + sim.ToString("F3"));
+                                log.Warn("P1:" + p.GetImgPortraitString());
+                                log.Warn("P2:" + p1.GetImgPortraitString());
                                 findsimilar = true;
                                 break;
                             }
@@ -333,7 +349,10 @@ namespace OTSDataType
                     }
                     if (findsimilar == false)
                     {
-                        finalparts.Add(p);
+                        if (!finalparts.Contains(p))
+                        {
+                            finalparts.Add(p);
+                        }
                     }
 
 
@@ -343,7 +362,10 @@ namespace OTSDataType
             {
                 foreach (var p in this.GetSideParticlesByOverlap(SORTING_DIRECTION.RIGHT, overlap))
                 {
-                    finalparts.Add(p);
+                    if (!finalparts.Contains(p))
+                    {
+                        finalparts.Add(p);
+                    }
                 }
             }
             if (downField != null && downField.measureSequence < this.measureSequence)
@@ -370,6 +392,8 @@ namespace OTSDataType
                             if (sim > 0.95)
                             {
                                 log.Warn("remove down side duplicate particle,similarity:" + sim.ToString("F3"));
+                                log.Warn("P1:" + p.GetImgPortraitString());
+                                log.Warn("P2:" + p1.GetImgPortraitString());
                                 findsimilar = true;
                                 break;
                             }
@@ -378,7 +402,10 @@ namespace OTSDataType
                     }
                     if (findsimilar == false)
                     {
-                        finalparts.Add(p);
+                        if (!finalparts.Contains(p))
+                        {
+                            finalparts.Add(p);
+                        }
                     }
 
 
@@ -388,30 +415,38 @@ namespace OTSDataType
             {
                 foreach (var p in this.GetSideParticlesByOverlap(SORTING_DIRECTION.DOWN, overlap))
                 {
-                    finalparts.Add(p);
+                    if (!finalparts.Contains(p))
+                    {
+                        finalparts.Add(p);
+                    }
                 }
             }
 
             foreach (var p in this.GetSideParticlesByOverlap(SORTING_DIRECTION.CENTER, overlap))
             {
-                finalparts.Add(p);
+                if (!finalparts.Contains(p))
+                {
+                    finalparts.Add(p);
+                }
             }
 
             this.SetListAnalysisParticles(finalparts);
+            log.Info("removing duplicate particles result:" + finalparts.Count);
         }
         private List<COTSParticleClr> GetSideParticlesByOverlap(SORTING_DIRECTION direction,int overlap)
         {
             List<COTSParticleClr> sideparts = new List<COTSParticleClr>();
             if (direction == SORTING_DIRECTION.LEFT)
             {
-                foreach (var p in this.GetAllParticles())
+                var leftborderParts = this.GetLeftBorderedParticles();
+                foreach (var p in this.GetListAnalysisParticles())
                 {
                     int left = 0, top = 0, right = 0, bottom = 0;
                     p.GetOTSRect(ref left, ref top, ref right, ref bottom);
 
                     if ((right - this.GetOTSRect().GetTopLeft().X) < 2 * overlap)
                     {
-                        if (left != this.GetOTSRect().GetTopLeft().X || Math.Abs(left-right)>2*overlap )//not on the border or it's a big particle
+                        if (!leftborderParts.Contains(p) || Math.Abs(left-right)>2*overlap )//not on the border or it's a big particle
                         {
                             sideparts.Add(p);
                         }
@@ -423,13 +458,14 @@ namespace OTSDataType
             }
             if (direction == SORTING_DIRECTION.RIGHT)
             {
-                foreach (var p in this.GetAllParticles())
+                var rightborderParts = this.GetRightBorderedParticles();
+                foreach (var p in this.GetListAnalysisParticles())
                 {
                     int left = 0, top = 0, right = 0, bottom = 0;
                     p.GetOTSRect(ref left, ref top, ref right, ref bottom);
                     if ((this.GetOTSRect().GetBottomRight().X-left) < 2 * overlap)
                     {
-                        if (right != this.GetOTSRect().GetBottomRight().X || Math.Abs(left - right) > 2 * overlap)//not on the border
+                        if (!rightborderParts.Contains(p)|| Math.Abs(left - right) > 2 * overlap)//not on the border or is a big part
                         {
                             sideparts.Add(p);
                         }
@@ -440,13 +476,14 @@ namespace OTSDataType
             }
             if (direction == SORTING_DIRECTION.UP)
             {
-                foreach (var p in this.GetAllParticles())
+                var upborderParts = this.GetTopBorderedParticles();
+                foreach (var p in this.GetListAnalysisParticles())
                 {
                     int left = 0, top = 0, right = 0, bottom = 0;
                     p.GetOTSRect(ref left, ref top, ref right, ref bottom);
                     if ((this.GetOTSRect().GetTopLeft().Y - bottom) < 2 * overlap)
                     {
-                        if (top != this.GetOTSRect().GetTopLeft().Y || Math.Abs(top - bottom) > 2 * overlap)//not on the border
+                        if (!upborderParts.Contains(p) || Math.Abs(top - bottom) > 2 * overlap)//not on the border
                         {
                             sideparts.Add(p);
                         }
@@ -457,13 +494,14 @@ namespace OTSDataType
             }
             if (direction == SORTING_DIRECTION.DOWN)
             {
-                foreach (var p in this.GetAllParticles())
+                var downborderParts = this.GetBottomBorderedParticles();
+                foreach (var p in this.GetListAnalysisParticles())
                 {
                     int left = 0, top = 0, right = 0, bottom = 0;
                     p.GetOTSRect(ref left, ref top, ref right, ref bottom);
                     if ((top-this.GetOTSRect().GetBottomRight().Y ) < 2 * overlap)
                     {
-                        if (bottom != this.GetOTSRect().GetBottomRight().Y || Math.Abs(top - bottom) > 2 * overlap)//not on the border
+                        if (!downborderParts.Contains(p)|| Math.Abs(top - bottom) > 2 * overlap)//not on the border
                         {
                             sideparts.Add(p);
                         }
@@ -474,7 +512,7 @@ namespace OTSDataType
             }
             if (direction == SORTING_DIRECTION.CENTER)
             {
-                foreach (var p in this.GetAllParticles())
+                foreach (var p in this.GetListAnalysisParticles())
                 {
                     int left = 0, top = 0, right = 0, bottom = 0;
                     p.GetOTSRect(ref left, ref top, ref right, ref bottom);
@@ -546,7 +584,7 @@ namespace OTSDataType
                
                
             }
-            log.Info("Total Particles: (>" + rMin.ToString("f2") + "): "+ "<" + rMax.ToString("f2") + "): " + m_listAllParticles.Count);
+            log.Info("Total analysis Particles: (>" + rMin.ToString("f2") + "): "+ "<" + rMax.ToString("f2") + "): " + m_listAnalysisParticles.Count);
            
 
      
@@ -605,21 +643,14 @@ namespace OTSDataType
         public bool PositionEquals(COTSField a_oSource)         
         {
 
-            var xoffSet = imgwidth * m_pixelSize /2;
-            var yoffSet = imgheight * m_pixelSize/2 ;
-            if (a_oSource.m_otsPos.X < (m_otsPos.X+xoffSet) && a_oSource.m_otsPos.X>( m_otsPos.X-xoffSet))
+           
+            if (a_oSource.m_otsPos == this.m_otsPos)
             {
-                if (a_oSource.m_otsPos.Y < (m_otsPos.Y + yoffSet) && a_oSource.m_otsPos.Y > (m_otsPos.Y - yoffSet))
-                {
-                    return true;
-                }
-                return false;
-
+                return true;
             }
-            else
+            else 
             {
                 return false;
-
             }
     
            
@@ -653,7 +684,7 @@ namespace OTSDataType
         public List<COTSParticleClr>    GetTopBorderedParticles()
         {
             List<COTSParticleClr> parts = new List<COTSParticleClr>();
-            foreach (var p in m_listAllParticles)
+            foreach (var p in m_listAnalysisParticles)
             {
                
                 var segs = p.GetFeature().GetSegmentsList();//COTSSegment
@@ -672,7 +703,7 @@ namespace OTSDataType
         public List< COTSParticleClr > GetBottomBorderedParticles()
         {
             List<COTSParticleClr> parts = new List<COTSParticleClr>();
-            foreach (var p in m_listAllParticles)
+            foreach (var p in m_listAnalysisParticles)
             {
                 var segs = p.GetFeature().GetSegmentsList();
                 foreach (var seg in segs)
@@ -691,7 +722,7 @@ namespace OTSDataType
         public  List<COTSParticleClr> GetLeftBorderedParticles()
         {
             List<COTSParticleClr> parts = new List<COTSParticleClr>();
-            foreach (var p in m_listAllParticles)
+            foreach (var p in m_listAnalysisParticles)
             {
                 var segs = p.GetFeature().GetSegmentsList();
                 foreach (var seg in segs)
@@ -710,7 +741,7 @@ namespace OTSDataType
         public  List <COTSParticleClr> GetRightBorderedParticles()
         {
             List<COTSParticleClr> parts = new List<COTSParticleClr>();
-            foreach (var p in m_listAllParticles)
+            foreach (var p in m_listAnalysisParticles)
             {
                 var segs = p.GetFeature().GetSegmentsList();
                 foreach (var seg in segs)

+ 11 - 15
OTSIncAMeasureApp/1-OTSMeasure/Measure/3-MeasureFlow/CSmplMeasure.cs

@@ -750,7 +750,10 @@ namespace OTSModelSharp
 
                     if (pXRayParam.GetUsingXray() == true)
                     {
-
+                        foreach (var p in curFld.GetListAnalysisParticles())
+                        {
+                            p.SetIsXrayParticle(true);
+                        }
                        CollectParticlesXrayData(curFld);
 
 
@@ -833,8 +836,11 @@ namespace OTSModelSharp
             log.Info("Begin to process image and get all particles!");
             GetOriginalParticles(ref curFldData);
 
+            log.Info("Begin to filter particles!");
+            FilterParticles(ref curFldData);//filter according to the xraylimit
+
             log.Info("Begin to Calculate the image property of every particle!");
-            var analysisparts = curFldData.GetAllParticles();
+            var analysisparts = curFldData.GetListAnalysisParticles();
             curFldData.CalParticleImageProp(analysisparts);//calculate particle image property such as feret diameter, DMAX etc.
             CSampleParam pMsrParam = m_Sample.GetMsrParams();
             COTSImageProcParam pImgProcessParam = pMsrParam.GetImageProcessParam();
@@ -844,9 +850,7 @@ namespace OTSModelSharp
                 curFldData.RemoveDuplicateOverlapParticles(overlap);
             }
            
-            log.Info("Begin to filter particles!");
-
-            FilterParticles(ref curFldData);//filter according to the xraylimit
+            
 
             CalculateParticleAbsolutPos(ref curFldData);
            
@@ -859,7 +863,7 @@ namespace OTSModelSharp
         private void FilterParticles(ref COTSField curFldData)
         {
           
-            var listXray = curFldData.GetListAnalysisParticles().OrderByDescending(x => x.GetActualArea()).ToList();
+            var listXray = curFldData.GetAllParticles().OrderByDescending(x => x.GetActualArea()).ToList();
             var listXray1 = new List<COTSParticleClr>();
             var pXRayParam =m_Sample.GetMsrParams().GetXRayParam();
             if (listXray.Count > pXRayParam.GetXrayLimit())
@@ -904,16 +908,8 @@ namespace OTSModelSharp
             var ifCollectxray = pMsrParam.GetXRayParam().GetUsingXray();
             // remove BES image background
             curFldData.RemoveImgBGAndGetParticles(pImgProcessParam, pixelsize, ifCollectxray);
-           
 
-            // check if this is an empty image
-            if (curFldData.NoParticle())
-            { // empty fields
-                log.Info("ImageProcess: empty field.");
-                return;
-            }
-
-          
+            log.Info("Find all particle num:" +curFldData.GetAllParticles().Count);
            
             return;
         }

+ 1 - 1
OTSIncAMeasureApp/1-OTSMeasure/Measure/ParamData/COTSMsrPrjResultData.cs

@@ -371,7 +371,7 @@ namespace OTSModelSharp
             {
                 bool haveData = false;
                 var emptyFld = new COTSField(p, pixelSize);
-                emptyFld.SetOTSPosition(p);
+               
                 foreach (var fld in allFldsWithdata)
                 {