소스 검색

optimize the mining measure flow.

gsp 2 년 전
부모
커밋
d428273e2d

+ 4 - 0
OTSCPP/OTSClrInterface/CommonClr/OTSParticleClr.h

@@ -64,6 +64,10 @@ namespace OTSCLRINTERFACE {
 		{
 			m_Particle->get()->CalXRayPos();
 		}
+		void CalCoverRect()
+		{
+			m_Particle->get()->CalCoverRect();
+		}
 
 		void SetAbsolutPos(System::Drawing::Point^ a_pAbsPos);
 		System::Drawing::Point^ GetAbsolutPos()

+ 3 - 3
OTSCPP/OTSClrInterface/ImageProClr/ImageProForClr.h

@@ -34,13 +34,13 @@ namespace OTSCLRINTERFACE
 			  bool ret = COTSImageProcess::SplitRawParticleIntoMatricsParticle(particle->GetOTSParticlePtr(),imageWidth,imageHeight, a_PixelSize,a_xrayStep);
 			  return ret;
 		  }
-		  bool SplitRawParticleIntoGreyScaleParticle(COTSParticleClr^ particle,double a_PixelSize, CBSEImgClr^ fieldImg)
+		  bool SplitRawParticleIntoGreyScaleParticle(COTSParticleClr^ particle,CDoubleRangeClr^ ecdRange,double a_PixelSize, CBSEImgClr^ fieldImg)
 		  {
-			  bool ret = COTSImageProcess::SplitRawParticleIntoGreyScaleParticle(particle->GetOTSParticlePtr(),  a_PixelSize, fieldImg->GetBSEImgPtr());
+			  bool ret = COTSImageProcess::SplitRawParticleIntoGreyScaleParticle(particle->GetOTSParticlePtr(), ecdRange->GetCDoubleRangePtr(), a_PixelSize, fieldImg->GetBSEImgPtr());
 			  return ret;
 		  }
 		 
-		  BOOL MergeBigBoundaryParticles(System::Collections::Generic::List<COTSFieldDataClr^>^  allFields, double pixelSize, int scanFieldSize, Size ResolutionSize, System::Collections::Generic::List<COTSParticleClr^>^ mergedParts)
+		  BOOL MergeBigBoundaryParticles(System::Collections::Generic::List<COTSFieldDataClr^>^  allFields,  double pixelSize, int scanFieldSize, Size ResolutionSize, System::Collections::Generic::List<COTSParticleClr^>^ mergedParts)
 		  {
 			  std::vector<COTSFieldDataPtr> allFlds;
 			  COTSParticleList mergedParticles;

+ 2 - 1
OTSCPP/OTSImagePro/GBImgPropCal.cpp

@@ -14,7 +14,8 @@ namespace OTSIMGPROC {
 	using namespace cv;
 	
 	using namespace std;
-	
+	//make matrix filled with 255 
+	const int nBlackColor = 255;
 	// construct
 	CGBImgPropCal::CGBImgPropCal()
 	{

+ 2 - 0
OTSCPP/OTSImagePro/OTSImagePro.vcxproj

@@ -607,6 +607,7 @@
       <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='LithiumCleanness|Win32'">false</CompileAsManaged>
     </ClCompile>
     <ClCompile Include="OTSImageScanParam.cpp" />
+    <ClCompile Include="OTSMorphology.cpp" />
     <ClCompile Include="stdafx.cpp">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release_oxford50|Win32'">Create</PrecompiledHeader>
@@ -634,6 +635,7 @@
     <ClInclude Include="Resource.h" />
     <ClInclude Include="stdafx.h" />
     <ClInclude Include="targetver.h" />
+    <ClInclude Include="OTSMorphology.h" />
   </ItemGroup>
   <ItemGroup>
     <None Include="ImageProDll.def" />

+ 2 - 0
OTSCPP/OTSImagePro/OTSImagePro.vcxproj.filters

@@ -8,6 +8,7 @@
     <ClCompile Include="stdafx.cpp" />
     <ClCompile Include="FieldMgr.cpp" />
     <ClCompile Include="OTSImageScanParam.cpp" />
+    <ClCompile Include="OTSMorphology.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="GBImgPropCal.h" />
@@ -19,6 +20,7 @@
     <ClInclude Include="targetver.h" />
     <ClInclude Include="FieldMgr.h" />
     <ClInclude Include="OTSImageScanParam.h" />
+    <ClInclude Include="OTSMorphology.h" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="ImageProDll.rc" />

+ 44 - 813
OTSCPP/OTSImagePro/OTSImageProcess.cpp

@@ -8,6 +8,7 @@
 #include "OTSImageProcess.h"
 #include "OTSImageProcessParam.h"
 #include <OTSFieldData.h>
+#include "OTSMorphology.h"
 #include "../OTSLog/COTSUtilityDllFunExport.h"
 #include "FieldMgr.h"
 using namespace cv;
@@ -15,6 +16,22 @@ using namespace std;
 
 namespace OTSIMGPROC
 {   
+	// Re-magnification
+	const int nImage_Size = 3;
+
+	//make matrix filled with 255 
+	const int nBlackColor = 255;
+
+	//make binary processing parameter 128 
+	const int nProcessParam = 100;
+
+	//picture size
+	const int nPictureSize = 128;
+
+	// added to filtered pixels
+	const double delta = 0;
+
+	using namespace std;
 	namespace 
 	{
 		
@@ -291,748 +308,7 @@ namespace OTSIMGPROC
 	{
 	}
 
-	// use verticl line of 3 pixel to erode a image
-	void COTSImageProcess::BErodeVertical3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
-	{
-		WORD x, y, wcounts;
-
-		if (rows <= 2 || columns <= 2)return;
-
-		// top line
-		for (x = 0; x < columns; x++)
-		{
-			*(target + x) = 0;
-		}
-
-		// bottom line
-		for (x = 0; x < columns; x++)
-		{
-			*(target + (DWORD)(rows - 1)*columns + x) = 0;
-		}
-
-		for (y = 1; y<rows - 1; y++)
-		{
-			for (x = 0; x<columns; x++)
-			{
-				if (*(source + (DWORD)y*columns + x) == 0)
-				{
-					*(target + (DWORD)y*columns + x) = 0;
-					continue;
-				}
-
-				wcounts = 0;
-				if (*(source + (DWORD)(y - 1)*columns + x) == 255)
-				{
-					wcounts++;
-				}
-				if (*(source + (DWORD)(y + 1)*columns + x) == 255)
-				{
-					wcounts++;
-				}
-
-				if (wcounts == 2) *(target + (DWORD)y*columns + x) = 255;
-				else *(target + (DWORD)y*columns + x) = 0;
-			}
-		}
-
-	}
-	// use left 45 degree line of 3 pixel to erode a image
-	void COTSImageProcess::BErodeLeft45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
-	{
-		WORD x, y, wcounts;
-
-		if (rows <= 2 || columns <= 2)return;
-
-		// top line
-		for (x = 0; x < columns; x++)
-		{
-			*(target + x) = 0;
-		}
-
-		// bottom line
-		for (x = 0; x < columns; x++)
-		{
-			*(target + (DWORD)(rows - 1)*columns + x) = 0;
-		}
-
-		// left line
-		for (y = 0; y<rows; y++)
-		{
-			*(target + (DWORD)y*columns) = 0;
-		}
-
-		// right line
-		for (y = 0; y<rows; y++)
-		{
-			*(target + (DWORD)y*columns + columns - 1) = 0;
-		}
-
 
-		for (y = 1; y < rows - 1; y++)
-		{
-			for (x = 1; x < columns - 1; x++)
-			{
-				if (*(source + (DWORD)y*columns + x) == 0)
-				{
-					*(target + (DWORD)y*columns + x) = 0;
-					continue;
-				}
-
-				wcounts = 0;
-				if (*(source + (DWORD)(y - 1)*columns + x - 1) == 255)
-				{
-					wcounts++;
-				}
-				if (*(source + (DWORD)(y + 1)*columns + x + 1) == 255)
-				{
-					wcounts++;
-				}
-
-				if (wcounts == 2) *(target + (DWORD)y*columns + x) = 255;
-				else *(target + (DWORD)y*columns + x) = 0;
-			}
-
-		}
-		
-
-	}
-	// use horizoontal line of 3 pixel to erode a image
-	void COTSImageProcess::BErodeHorizontal3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
-	{
-		WORD x, y, wcounts;
-
-		if (rows <= 2 || columns <= 2)return;
-
-		// left line
-		for (y = 0; y<rows; y++)
-		{
-			*(target + (DWORD)y*columns) = 0;
-		}
-
-		// right line
-		for (y = 0; y<rows; y++)
-		{
-			*(target + (DWORD)y*columns + columns - 1) = 0;
-		}
-
-
-		for (y = 0; y<rows; y++)
-		{
-			for (x = 1; x<columns - 1; x++)
-			{
-				if (*(source + (DWORD)y*columns + x) == 0)
-				{
-					*(target + (DWORD)y*columns + x) = 0;
-					continue;
-				}
-
-				wcounts = 0;
-				if (*(source + (DWORD)y*columns + x - 1) == 255)
-				{
-					wcounts++;
-				}
-				if (*(source + (DWORD)y*columns + x + 1) == 255)
-				{
-					wcounts++;
-				}
-
-				if (wcounts == 2) *(target + (DWORD)y*columns + x) = 255;
-				else *(target + (DWORD)y*columns + x) = 0;
-			}
-		}
-
-	}
-	// use right 45 degree line of 3 pixel to erode a image
-	void COTSImageProcess::BErodeRight45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
-	{
-		WORD x, y, wcounts;
-
-		if (rows <= 2 || columns <= 2)return;
-
-		// top line
-		for (x = 0; x < columns; x++)
-		{
-			*(target + x) = 0;
-		}
-
-		// bottom line
-		for (x = 0; x < columns; x++)
-		{
-			*(target + (DWORD)(rows - 1)*columns + x) = 0;
-		}
-
-		// left line
-		for (y = 0; y<rows; y++)
-		{
-			*(target + (DWORD)y*columns) = 0;
-		}
-
-		// right line
-		for (y = 0; y<rows; y++)
-		{
-			*(target + (DWORD)y*columns + columns - 1) = 0;
-		}
-
-
-		for (y = 1; y<rows - 1; y++)
-		{
-			for (x = 1; x<columns - 1; x++)
-			{
-				if (*(source + (DWORD)y*columns + x) == 0)
-				{
-					*(target + (DWORD)y*columns + x) = 0;
-					continue;
-				}
-
-				wcounts = 0;
-				if (*(source + (DWORD)(y - 1)*columns + x + 1) == 255)
-				{
-					wcounts++;
-				}
-				if (*(source + (DWORD)(y + 1)*columns + x - 1) == 255)
-				{
-					wcounts++;
-				}
-
-				if (wcounts == 2) *(target + (DWORD)y*columns + x) = 255;
-				else *(target + (DWORD)y*columns + x) = 0;
-			}
-		}
-
-	
-	}
-	void COTSImageProcess::BDilateVertical3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
-	{
-		WORD x, y;
-
-		if (rows <= 2 || columns <= 2)return;
-
-		// top line
-		for (x = 0; x<columns; x++)
-		{
-			if (*(source + x) != 0)
-			{
-				*(target + x) = 0xff;
-			}
-		}
-
-		// bottom line
-		for (x = 0; x<columns; x++)
-		{
-			if (*(source + (DWORD)(rows - 1)*columns + x) != 0)
-			{
-				*(target + (DWORD)(rows - 1)*columns + x) = 0xff;
-			}
-		}
-
-		for (y = 1; y<rows - 1; y++)
-		{
-			for (x = 1; x<columns - 1; x++)
-			{
-				if (*(source + (DWORD)y*columns + x) != 0)
-				{
-					*(target + (DWORD)y*columns + x) = 0xff;
-					*(target + (DWORD)(y - 1)*columns + x) = 255;
-					*(target + (DWORD)(y + 1)*columns + x) = 255;
-				}
-				else *(target + (DWORD)y*columns + x) = 0;
-			}
-		}
-
-	}
-	void COTSImageProcess::BDilateLeft45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
-	{
-		WORD x, y;
-
-		if (rows <= 2 || columns <= 2)return;
-
-		// top line
-		for (x = 0; x<columns; x++)
-		{
-			if (*(source + x) != 0)
-			{
-				*(target + x) = 0xff;
-			}
-		}
-
-		// bottom line
-		for (x = 0; x<columns; x++)
-		{
-			if (*(source + (DWORD)(rows - 1)*columns + x) != 0)
-			{
-				*(target + (DWORD)(rows - 1)*columns + x) = 0xff;
-			}
-		}
-
-		// left line
-		for (y = 0; y<rows; y++)
-		{
-			if (*(source + (DWORD)y*columns) != 0)
-			{
-				*(target + (DWORD)y*columns) = 0xff;
-			}
-		}
-
-		// right line
-		for (y = 0; y<rows; y++)
-		{
-			if (*(source + (DWORD)y*columns + columns - 1) != 0)
-			{
-				*(target + (DWORD)y*columns + columns - 1) = 0xff;
-			}
-		}
-
-		for (y = 1; y<rows - 1; y++)
-		{
-			for (x = 1; x<columns - 1; x++)
-			{
-				if (*(source + (DWORD)y*columns + x) != 0)
-				{
-					*(target + (DWORD)y*columns + x) = 0xff;
-					*(target + (DWORD)(y - 1)*columns + x - 1) = 255;
-					*(target + (DWORD)(y + 1)*columns + x + 1) = 255;
-				}
-				else *(target + (DWORD)y*columns + x) = 0;
-			}
-		}
-
-	}
-	void COTSImageProcess::BDilateHorizontal3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
-	{
-		WORD x, y;
-
-		if (rows <= 2 || columns <= 2)return;
-
-		// left line
-		for (y = 0; y<rows; y++)
-		{
-			if (*(source + (DWORD)y*columns) != 0)
-			{
-				*(target + (DWORD)y*columns) = 0xff;
-			}
-		}
-
-		// right line
-		for (y = 0; y<rows; y++)
-		{
-			if (*(source + (DWORD)y*columns + columns - 1) != 0)
-			{
-				*(target + (DWORD)y*columns + columns - 1) = 0xff;
-			}
-		}
-
-		for (y = 1; y<rows - 1; y++)
-		{
-			for (x = 1; x<columns - 1; x++)
-			{
-				if (*(source + (DWORD)y*columns + x) != 0)
-				{
-					*(target + (DWORD)y*columns + x) = 0xff;
-					*(target + (DWORD)y*columns + x - 1) = 255;
-					*(target + (DWORD)y*columns + x + 1) = 255;
-				}
-				else *(target + (DWORD)y*columns + x) = 0;
-			}
-		}
-	}
-	void COTSImageProcess::BDilateRight45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
-	{
-		WORD x, y;
-
-		if (rows <= 2 || columns <= 2)return;
-
-		// top line
-		for (x = 0; x<columns; x++)
-		{
-			if (*(source + x) != 0)
-			{
-				*(target + x) = 0xff;
-			}
-		}
-
-		// bottom line
-		for (x = 0; x<columns; x++)
-		{
-			if (*(source + (DWORD)(rows - 1)*columns + x) != 0)
-			{
-				*(target + (DWORD)(rows - 1)*columns + x) = 0xff;
-			}
-		}
-
-		// left line
-		for (y = 0; y<rows; y++)
-		{
-			if (*(source + (DWORD)y*columns) != 0)
-			{
-				*(target + (DWORD)y*columns) = 0xff;
-			}
-		}
-
-		// right line
-		for (y = 0; y<rows; y++)
-		{
-			if (*(source + (DWORD)y*columns + columns - 1) != 0)
-			{
-				*(target + (DWORD)y*columns + columns - 1) = 0xff;
-			}
-		}
-
-		for (y = 1; y<rows - 1; y++)
-		{
-			for (x = 1; x<columns - 1; x++)
-			{
-				if (*(source + (DWORD)y*columns + x) != 0)
-				{
-					*(target + (DWORD)y*columns + x) = 0xff;
-					*(target + (DWORD)(y - 1)*columns + x + 1) = 255;
-					*(target + (DWORD)(y + 1)*columns + x - 1) = 255;
-				}
-				else *(target + (DWORD)y*columns + x) = 0;
-			}
-		}
-
-	}
-	void COTSImageProcess::BErode3(LPBYTE source, LPBYTE target, WORD wDegree, WORD rows, WORD columns)
-	{
-		WORD x, y, i, j, wcounts;
-
-		if (rows == 1 || columns == 1)return;
-
-		for (y = 1; y<rows - 1; y++)
-		{
-			for (x = 1; x<columns - 1; x++)
-			{
-				if (*(source + (DWORD)y*columns + x) == 0)
-				{
-					*(target + (DWORD)y*columns + x) = 0;
-					continue;
-				}
-				wcounts = 0;
-				for (i = (WORD)(y - 1); i <= (WORD)(y + 1); i++)
-
-				{
-					for (j = (WORD)(x - 1); j <= (WORD)(x + 1); j++)
-					{
-						if (*(source + (DWORD)i*columns + j) == 0)
-						{
-							wcounts++;
-						}
-					}
-				}
-				if (wcounts >= wDegree) *(target + (DWORD)y*columns + x) = 0;
-				else *(target + (DWORD)y*columns + x) = 0xff;
-			}
-		}
-
-		// top line
-		for (x = 1; x<columns - (WORD)1; x++)
-		{
-			if (*(source + x) == 0)
-			{
-				*(target + x) = 0;
-				continue;
-			}
-			wcounts = 0;
-			for (i = 0; i <= 1; i++)
-
-			{
-				for (j = (WORD)(x - 1); j <= (WORD)(x + 1); j++)
-				{
-					if (*(source + (DWORD)i*columns + j) == 0) wcounts++;
-				}
-			}
-			if (wcounts >= wDegree * 5 / 8) *(target + x) = 0;
-			else *(target + x) = 0xff;
-		}
-
-		// bottom line
-		for (x = 1; x<columns - 1; x++)
-		{
-			if (*(source + (DWORD)(rows - 1)*columns + x) == 0)
-			{
-				*(target + (DWORD)(rows - 1)*columns + x) = 0;
-				continue;
-			}
-			wcounts = 0;
-			for (i = (WORD)(rows - 2); i <= (WORD)(rows - 1); i++)
-
-			{
-				for (j = (WORD)(x - 1); j <= (WORD)(x + 1); j++)
-				{
-					if (*(source + (DWORD)i*columns + j) == 0) wcounts++;
-				}
-			}
-			if (wcounts >= wDegree * 5 / 8) *(target + (DWORD)(rows - 1)*columns + x) = 0;
-			else *(target + (DWORD)(rows - 1)*columns + x) = 0xff;
-		}
-
-		// left line
-		for (y = 1; y<rows - 1; y++)
-		{
-			if (*(source + (DWORD)y*columns) == 0)
-			{
-				*(target + (DWORD)y*columns) = 0;
-				continue;
-			}
-			wcounts = 0;
-			for (i = (WORD)(y - 1); i <= (WORD)(y + 1); i++)
-			{
-				for (j = 0; j <= 1; j++)
-				{
-					if (*(source + (DWORD)i*columns + j) == 0) wcounts++;
-				}
-			}
-			if (wcounts >= wDegree * 5 / 8) *(target + (DWORD)y*columns) = 0;
-			else *(target + (DWORD)y*columns) = 0xff;
-		}
-
-		// right line
-		for (y = 1; y<rows - 1; y++)
-		{
-			if (*(source + (DWORD)y*columns + columns - 1) == 0)
-			{
-				*(target + (DWORD)y*columns + columns - 1) = 0;
-				continue;
-			}
-			wcounts = 0;
-			for (i = (WORD)(y - 1); i <= (WORD)(y + 1); i++)
-
-			{
-				for (j = (WORD)(columns - 2); j <= (WORD)(columns - 1); j++)
-				{
-					if (*(source + (DWORD)i*columns + j) == 0) wcounts++;
-				}
-			}
-			if (wcounts >= wDegree * 5 / 8) *(target + (DWORD)y*columns + columns - 1) = 0;
-			else *(target + (DWORD)y*columns + columns - 1) = 0xff;
-		}
-
-		return;
-	}
-	void COTSImageProcess::BDilate3(LPBYTE source, LPBYTE target, WORD wDegree, WORD rows, WORD columns)
-	{
-		WORD x, y, i, j, wcounts;
-
-		for (y = 1; y<rows - 1; y++)
-		{
-			for (x = 1; x<columns - 1; x++)
-			{
-				if (*(source + (DWORD)y*columns + x) != 0)
-				{
-					*(target + (DWORD)y*columns + x) = 0xff;
-					continue;
-				}
-				wcounts = 0;
-				for (i = (WORD)(y - 1); i <= (WORD)(y + 1); i++)
-				{
-					for (j = (WORD)(x - 1); j <= (WORD)(x + 1); j++)
-					{
-						if (*(source + (DWORD)i*columns + j) != 0)	wcounts++;
-					}
-				}
-				if (wcounts >= wDegree) *(target + (DWORD)y*columns + x) = 0xff;
-				else *(target + (DWORD)y*columns + x) = 0;
-			}
-		}
-
-		// top line
-		for (x = 1; x<columns - 1; x++)
-		{
-			if (*(source + x) != 0)
-			{
-				*(target + x) = 0xff;
-				continue;
-			}
-			wcounts = 0;
-			for (i = 0; i <= 1; i++)
-			{
-				for (j = (WORD)(x - 1); j <= (WORD)(x + 1); j++)
-				{
-					if (*(source + (DWORD)i*columns + j) != 0) wcounts++;
-				}
-			}
-
-			if (wcounts >= wDegree * 5 / 8)	// but does not mater, as we have border of 2 now
-			{
-				*(target + x) = 0xff;
-			}
-			else { *(target + x) = 0; }
-		}
-
-		// bottom line
-		for (x = 1; x<columns - 1; x++)
-		{
-			if (*(source + (DWORD)(rows - 1)*columns + x) != 0)
-			{
-				*(target + (DWORD)(rows - 1)*columns + x) = 0xff;
-				continue;
-			}
-			wcounts = 0;
-			for (i = (WORD)(rows - 2); i <= (WORD)(rows - 1); i++)
-			{
-				for (j = (WORD)(x - 1); j <= (WORD)(x + 1); j++)
-				{
-					if (*(source + (DWORD)i*columns + j) != 0) wcounts++;
-				}
-			}
-
-			if (wcounts > wDegree * 5 / 8)
-			{
-				*(target + (DWORD)(rows - 1)*columns + x) = 0xff;
-			}
-			else
-			{
-				*(target + (DWORD)(rows - 1)*columns + x) = 0;
-			}
-		}
-
-		// left line
-		for (y = 1; y<rows - 1; y++)
-		{
-			if (*(source + (DWORD)y*columns) != 0)
-			{
-				*(target + (DWORD)y*columns) = 0xff;
-				continue;
-			}
-			wcounts = 0;
-			for (i = (WORD)(y - 1); i <= (WORD)(y + 1); i++)
-			{
-				for (j = 0; j <= (WORD)1; j++)
-				{
-					if (*(source + (DWORD)i*columns + j) != 0) wcounts++;
-				}
-			}
-			if (wcounts >= wDegree * 5 / 8)
-			{
-				*(target + (DWORD)y*columns) = 0xff;
-			}
-			else
-			{
-				*(target + (DWORD)y*columns) = 0;
-			}
-		}
-
-		// right line
-		for (y = 1; y<rows - 1; y++)
-		{
-			if (*(source + (DWORD)y*columns + columns - 1) != 0)
-			{
-				*(target + (DWORD)y*columns + columns - 1) = 0xff;
-				continue;
-			}
-			wcounts = 0;
-			for (i = (WORD)(y - 1); i <= (WORD)(y + 1); i++)
-			{
-				for (j = (WORD)(columns - 2); j <= (WORD)(columns - 1); j++)
-				{
-					if (*(source + (DWORD)i*columns + j) != 0) wcounts++;
-				}
-			}
-			if (wcounts >= wDegree * 5 / 8)
-			{
-				*(target + (DWORD)y*columns + columns - 1) = 0xff;
-			}
-			else
-			{
-				*(target + (DWORD)y*columns + columns - 1) = 0;
-			}
-		}
-
-		// four cornor points treated separately here
-		// top-left
-		if (*(source) != 0)
-		{
-			*target = 0xff;
-		}
-		else
-		{
-			wcounts = 0;
-			if (*(source + 1) != 0) wcounts++;
-			if (*(source + columns) != 0) wcounts++;
-			if (*(source + columns + 1) != 0) wcounts++;
-
-			//        if (wcounts >= wDegree*3/8)  // this is a bug here - interger division
-			if (wcounts * 8 >= wDegree * 3)
-			{
-				*target = 0xff;
-			}
-			else
-			{
-				*target = 0;
-			}
-		}
-
-		//top-right
-		if (*(source + columns - 1) != 0)
-		{
-			*(target + columns - 1) = 0xff;
-		}
-		else
-		{
-			wcounts = 0;
-			if (*(source + columns - 2) != 0) wcounts++;
-			if (*(source + columns * 2 - 1) != 0) wcounts++;
-			if (*(source + columns * 2 - 2) != 0) wcounts++;
-
-			//        if (wcounts >= wDegree*3/8)  // this is a bug here - interger division
-			if (wcounts * 8 >= wDegree * 3)
-			{
-				*(target + columns - 1) = 0xff;
-			}
-			else
-			{
-				*(target + columns - 1) = 0;
-			}
-		}
-
-		//bottom-left
-		if (*(source + (DWORD)columns * (rows - 1)) != 0)
-		{
-			*(target + (DWORD)columns * (rows - 1)) = 0xff;
-		}
-		else
-		{
-			wcounts = 0;
-			if (*(source + (DWORD)columns * (rows - 1) + 1) != 0) wcounts++;
-			if (*(source + (DWORD)columns * (rows - 2)) != 0) wcounts++;
-			if (*(source + (DWORD)columns * (rows - 2) + 1) != 0) wcounts++;
-
-			//        if (wcounts >= wDegree*3/8)  // this is a bug here - interger division
-			if (wcounts * 8 >= wDegree * 3)
-			{
-				*(target + (DWORD)columns * (rows - 1)) = 0xff;
-			}
-			else
-			{
-				*(target + (DWORD)columns * (rows - 1)) = 0;
-			}
-		}
-
-		//bottom-right
-		if (*(source + (DWORD)columns * rows - 1) != 0)
-		{
-			*(target + (DWORD)columns * rows - 1) = 0xff;
-		}
-		else
-		{
-			wcounts = 0;
-			if (*(source + (DWORD)columns * rows - 2) != 0) wcounts++;
-			if (*(source + (DWORD)columns * (rows - 1) - 2) != 0) wcounts++;
-			if (*(source + (DWORD)columns * (rows - 1) - 1) != 0) wcounts++;
-
-			//        if (wcounts >= wDegree*3/8)  // this is a bug here - interger division
-			if (wcounts * 8 >= wDegree * 3)
-			{
-				*(target + (DWORD)columns * rows - 1) = 0xff;
-			}
-			else
-			{
-				*(target + (DWORD)columns * rows - 1) = 0;
-			}
-		}
-
-		return;
-	}
 
 	// ReZoom the picture with re-magnification 
 	BOOL COTSImageProcess::ReZoom(CString InPutPath, CString OutPutPath)
@@ -1090,25 +366,10 @@ namespace OTSIMGPROC
 	BOOL COTSImageProcess::RemoveBSEImageBG(CBSEImgPtr m_pBSEImg, COTSImageProcessParamPtr a_pImgProcessParam,COTSFieldDataPtr m_pFieldData)
 	{
 		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_pImgProcessParam);
-		if (!a_pImgProcessParam)
-		{
-			LogErrorTrace(__FILE__, __LINE__, _T("RemoveBSEImageBG: there is no image process data"));
-			return FALSE;
-		}
 
 		int nWidthImg = m_pBSEImg->GetWidth();
 		int nHeightImg = m_pBSEImg->GetHeight();
@@ -1891,8 +1152,8 @@ namespace OTSIMGPROC
 			//Mat cvcopyImg = Mat(nHeightImg, nWidthImg, CV_8UC1, pPixel);// use the medianblur method to achieve the same effect as open morphology(errod and dialate).
 			//pPixel = cvcopyImg.data;
 			
-				COTSImageProcess::BErode3(pPixel, pTempImg, 5, nHeightImg, nWidthImg);
-				COTSImageProcess::BDilate3(pTempImg, pPixel, 5, nHeightImg, nWidthImg);
+				BErode3(pPixel, pTempImg, 5, nHeightImg, nWidthImg);
+				BDilate3(pTempImg, pPixel, 5, nHeightImg, nWidthImg);
 			
 			
 			
@@ -1920,7 +1181,7 @@ namespace OTSIMGPROC
 		BYTE* pSrcImg = a_pImgIn->GetImageDataPointer();
 	
 
-	     BYTE* pPixel = new byte[nImgSize];
+	    BYTE* pPixel = new byte[nImgSize];
 	
 		
 
@@ -1956,8 +1217,8 @@ namespace OTSIMGPROC
 			int errodDilateParam = a_pImageProcessParam->GetErrodDilateParam();
 			if (errodDilateParam > 0)
 			{
-				COTSImageProcess::BErode3(pPixel, pTempImg, errodDilateParam, nHeightImg, nWidthImg);
-				COTSImageProcess::BDilate3(pTempImg, pPixel, errodDilateParam, nHeightImg, nWidthImg);
+				BErode3(pPixel, pTempImg, errodDilateParam, nHeightImg, nWidthImg);
+				BDilate3(pTempImg, pPixel, errodDilateParam, nHeightImg, nWidthImg);
 			}
 			
 			//Mat cvcopyImg = Mat(nHeightImg, nWidthImg, CV_8UC1, pPixel);// use the medianblur method to achieve the same effect as open morphology(errod and dialate).
@@ -2025,8 +1286,8 @@ namespace OTSIMGPROC
 			int errodDilateParam = a_pImageProcessParam->GetErrodDilateParam();
 			if (errodDilateParam > 0)
 			{
-				COTSImageProcess::BErode3(pPixel, pTempImg, errodDilateParam, nHeightImg, nWidthImg);
-				COTSImageProcess::BDilate3(pTempImg, pPixel, errodDilateParam, nHeightImg, nWidthImg);
+				BErode3(pPixel, pTempImg, errodDilateParam, nHeightImg, nWidthImg);
+				BDilate3(pTempImg, pPixel, errodDilateParam, nHeightImg, nWidthImg);
 			}
 			/*Mat cvcopyImg = Mat(nHeightImg, nWidthImg, CV_8UC1, pPixel);
 			medianBlur(cvcopyImg, cvcopyImg, 5);
@@ -2596,53 +1857,7 @@ namespace OTSIMGPROC
 			a_pOTSPart->SetDInscr(MIN(w, h));
 			return true;
 		}
-		// calculate the particle image data size, expand 3 pixel at the edge
-		Mat particleImage = Mat::zeros(rect.Height() + nExpand_Size, rect.Width() + nExpand_Size, CV_8U);
-		// get the segment list
-		COTSSegmentsList listSegment = a_pOTSPart->GetFeature()->GetSegmentsList();
-		for (auto pSegment : listSegment)
-		{
-			int nStart = pSegment->GetStart() - rect.left + nExpand_Size;
-			int nEnd = pSegment->GetStart() + pSegment->GetLength() - rect.left - 1 + nExpand_Size;
-			int nHeight = pSegment->GetHeight() - rect.top + nExpand_Size;
-			line(particleImage, Point(nStart, nHeight), Point(nEnd, nHeight), Scalar(nBlackColor), nThickness, nLineType);
-		}
-		//--------abstract the contour of the particle.
-		Mat cvcopyImg;
-		medianBlur(particleImage, cvcopyImg, 5);//smooth the edge
-		vector<vector<Point>>contours;
-
-		findContours(cvcopyImg, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
-		if (contours.size() == 0)// the particle is too odd that openCV can't find a contour of it. Then we take the upright rect of the particle as it's minArea rect.
-		{
-			double w = 0, h = 0;
-			w = (double)rect.Width() * a_PixelSize;
-			h = (double)rect.Height() * a_PixelSize;
-			a_pOTSPart->SetDMax(MAX(w, h));
-			a_pOTSPart->SetDMin(MIN(w, h));
-			a_pOTSPart->SetDMean((w + h) / 2);
-			a_pOTSPart->SetFeretDiameter((w + h) / 2);
-			a_pOTSPart->SetDElong(MAX(w, h));
-			a_pOTSPart->SetPerimeter((w + h) * 2);
-			a_pOTSPart->SetDPerp(MIN(w, h));
-			a_pOTSPart->SetDInscr(MIN(w, h));
-			return true;
-		}
-		int imaxcontour = 0, imax = 0;
-		for (unsigned int i = 0; i < contours.size(); i++) {
-
-			int itmp = contourArea(contours[i]);
-
-			if (imaxcontour < itmp) {
-
-				imax = i;
-
-				imaxcontour = itmp;
-
-			}
-		}
-
-		vector<Point > listEdge = contours[imax];
+		
 		if (a_XrayStep > 0)
 		{
 			COTSParticleList matricsParts;
@@ -2652,7 +1867,7 @@ namespace OTSIMGPROC
 		}
 		//-----------
 	}
-	BOOL COTSImageProcess::SplitRawParticleIntoGreyScaleParticle(COTSParticlePtr a_pOTSPart, double a_PixelSize ,CBSEImgPtr fieldImg)
+	BOOL COTSImageProcess::SplitRawParticleIntoGreyScaleParticle(COTSParticlePtr a_pOTSPart,CDoubleRangePtr ecdRange, double a_PixelSize ,CBSEImgPtr fieldImg)
 	{
 		//--------- convert this particle data to image data,construct an image only with this particle.------
 		const int nExpand_Size = 3;
@@ -2696,7 +1911,7 @@ namespace OTSIMGPROC
 		}
 		/*ImshowImage(onePartImg);
 		ImshowChartData(onePartImg);*/
-		
+		BlurImage(onePartImg);
 		std::vector<CIntRangePtr> rngs = CalcuGrayLevelRange(onePartImg);
 		
 		
@@ -2706,7 +1921,8 @@ namespace OTSIMGPROC
 		for (int i = 0; i < rngs.size(); i++)
 		{
 			partAreaMap.clear();
-			GetParticlesBySpecialGrayRange(onePartImg, rngs[i], CDoubleRangePtr(new CDoubleRange(0, 2000)), a_PixelSize, partData);
+			
+			GetParticlesBySpecialGrayRange(onePartImg, rngs[i], ecdRange, a_PixelSize, partData);
 
 		
 			
@@ -2738,6 +1954,7 @@ namespace OTSIMGPROC
 
 					}
 				theBiggestPart->GetFeature()->SetSegmentsList(partsegs, true);
+				theBiggestPart->CalCoverRect();
 				theBiggestPart->SetFieldId(a_pOTSPart->GetFieldId());
 				theBiggestPart->SetAnalysisId(a_pOTSPart->GetAnalysisId());
 				a_pOTSPart->AddSubParticle(theBiggestPart);
@@ -2796,6 +2013,20 @@ namespace OTSIMGPROC
 
 		cv::waitKey();
 	}
+	void COTSImageProcess::BlurImage(CBSEImgPtr inImg)
+	{
+		int rows, cols;
+		cols = inImg->GetWidth();
+		rows = inImg->GetHeight();
+		BYTE* pPixel = inImg->GetImageDataPointer();
+		Mat cvcopyImg = Mat(rows, cols, CV_8UC1, pPixel);
+		//Mat blurImg;
+		medianBlur(cvcopyImg, cvcopyImg, 7);//get rid of the noise point.
+		//cv::GaussianBlur(cvcopyImg, cvcopyImg, Size(3, 3), 7);
+		//inImg->SetImageData(cvcopyImg.data, width, height);
+		/*outImg = inImg;*/
+	}
+
 	BOOL COTSImageProcess::MergeBigBoundaryParticles(COTSFieldDataList allFields,double pixelSize,int scanFieldSize, CSize ResolutionSize, COTSParticleList& mergedParts)
 	{
 		COTSSegmentsList boarderSegs;

+ 2 - 47
OTSCPP/OTSImagePro/OTSImageProcess.h

@@ -7,58 +7,12 @@
 namespace OTSIMGPROC {
 	using namespace OTSDATA;
 	
-	// Re-magnification
-	const int nImage_Size = 3;
-
-	//make matrix filled with 255 
-	const int nBlackColor = 255;
-
-	//make binary processing parameter 128 
-	const int nProcessParam = 100;
-
-	//picture size
-	const int nPictureSize = 128;
-	
-	// added to filtered pixels
-	const double delta = 0;
-
-	using namespace std;
-
 	class __declspec(dllexport) COTSImageProcess
 	{
 	public:
 		COTSImageProcess();
 		~COTSImageProcess();
 
-		// image process
-
-		// morphology
-		// LPBYTE source£º binary image pointer input£¬0, and 255
-		// LPBYTE target:  image pointer output
-		// WORD rows: image height
-		// WORD clumns: image width
-		// WORD wDegree: 1~8, eight direction selction.
-
-		// erode image with a structure of verticle 3 element
-		static void BErodeVertical3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
-		// erode image with a left 45 degree structure of 3 element
-		static void BErodeLeft45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
-		// erode image with a structure of horizontal 3 element
-		static void BErodeHorizontal3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
-		// erode image with a right 45 degree structure of 3 element
-		static void BErodeRight45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
-		// dilate image with a structure of verticle 3 element
-		static void BDilateVertical3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
-		// dilate image with a left 45 degree structure of 3 element
-		static void BDilateLeft45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
-		// dilate image with a structure of horizontal 3 element
-		static void BDilateHorizontal3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
-		// dilate image with a right 45 degree structure of 3 element
-		static void BDilateRight45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
-		// erode image with a structure of verticle 8 element
-		static void BErode3(LPBYTE source, LPBYTE target, WORD wDegree, WORD rows, WORD columns);
-		// dilate image with a structure of verticle 8 element
-		static void BDilate3(LPBYTE source, LPBYTE target, WORD wDegree, WORD rows, WORD columns);
 		// ReZoom the picture with re-magnification
 		static BOOL ReZoom(CString InPutPath, CString OutPutPath);
 		static BOOL RemoveBSEImageBG(CBSEImgPtr m_pBSEImg, COTSImageProcessParamPtr a_pImageProcessParam, COTSFieldDataPtr m_pFieldData);
@@ -73,7 +27,7 @@ namespace OTSIMGPROC {
 		static void RemoveBackGround(CBSEImgPtr a_pImgIn, COTSImageProcessParamPtr a_pImageProcessParam, CBSEImgPtr a_pImgOut,long& foundedPixelNum);
 		static BOOL CalcuParticleImagePropertes(COTSParticlePtr part, double a_PixelSize);
 		static BOOL SplitRawParticleIntoMatricsParticle(COTSParticlePtr part, int imageWidth, int imageHeight, double a_PixelSize, double a_XrayStep );
-		static BOOL SplitRawParticleIntoGreyScaleParticle(COTSParticlePtr part,  double a_PixelSize, CBSEImgPtr fieldImg);
+		static BOOL SplitRawParticleIntoGreyScaleParticle(COTSParticlePtr part, CDoubleRangePtr ecdRange, double a_PixelSize, CBSEImgPtr fieldImg);
 		static BOOL MergeBigBoundaryParticles(COTSFieldDataList allFields, double pixelSize, int scanFieldSize, CSize ResolutionSize, COTSParticleList& mergedParts);
 		
 	protected:
@@ -84,6 +38,7 @@ namespace OTSIMGPROC {
 		static BOOL ChangeFeaturelist(COTSFeatureList& a_listFeatures, COTSParticleList& a_listParticle);
 		static void ImshowImage(CBSEImgPtr img);
 		static void ImshowChartData(CBSEImgPtr img);
+		static void BlurImage(CBSEImgPtr inImg);
 		
 		
 	};

+ 745 - 0
OTSCPP/OTSImagePro/OTSMorphology.cpp

@@ -0,0 +1,745 @@
+#include <stdafx.h>
+#include "OTSMorphology.h"
+// use verticl line of 3 pixel to erode a image
+void BErodeVertical3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
+{
+	WORD x, y, wcounts;
+
+	if (rows <= 2 || columns <= 2)return;
+
+	// top line
+	for (x = 0; x < columns; x++)
+	{
+		*(target + x) = 0;
+	}
+
+	// bottom line
+	for (x = 0; x < columns; x++)
+	{
+		*(target + (DWORD)(rows - 1) * columns + x) = 0;
+	}
+
+	for (y = 1; y < rows - 1; y++)
+	{
+		for (x = 0; x < columns; x++)
+		{
+			if (*(source + (DWORD)y * columns + x) == 0)
+			{
+				*(target + (DWORD)y * columns + x) = 0;
+				continue;
+			}
+
+			wcounts = 0;
+			if (*(source + (DWORD)(y - 1) * columns + x) == 255)
+			{
+				wcounts++;
+			}
+			if (*(source + (DWORD)(y + 1) * columns + x) == 255)
+			{
+				wcounts++;
+			}
+
+			if (wcounts == 2) *(target + (DWORD)y * columns + x) = 255;
+			else *(target + (DWORD)y * columns + x) = 0;
+		}
+	}
+
+}
+// use left 45 degree line of 3 pixel to erode a image
+void BErodeLeft45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
+{
+	WORD x, y, wcounts;
+
+	if (rows <= 2 || columns <= 2)return;
+
+	// top line
+	for (x = 0; x < columns; x++)
+	{
+		*(target + x) = 0;
+	}
+
+	// bottom line
+	for (x = 0; x < columns; x++)
+	{
+		*(target + (DWORD)(rows - 1) * columns + x) = 0;
+	}
+
+	// left line
+	for (y = 0; y < rows; y++)
+	{
+		*(target + (DWORD)y * columns) = 0;
+	}
+
+	// right line
+	for (y = 0; y < rows; y++)
+	{
+		*(target + (DWORD)y * columns + columns - 1) = 0;
+	}
+
+
+	for (y = 1; y < rows - 1; y++)
+	{
+		for (x = 1; x < columns - 1; x++)
+		{
+			if (*(source + (DWORD)y * columns + x) == 0)
+			{
+				*(target + (DWORD)y * columns + x) = 0;
+				continue;
+			}
+
+			wcounts = 0;
+			if (*(source + (DWORD)(y - 1) * columns + x - 1) == 255)
+			{
+				wcounts++;
+			}
+			if (*(source + (DWORD)(y + 1) * columns + x + 1) == 255)
+			{
+				wcounts++;
+			}
+
+			if (wcounts == 2) *(target + (DWORD)y * columns + x) = 255;
+			else *(target + (DWORD)y * columns + x) = 0;
+		}
+
+	}
+
+
+}
+// use horizoontal line of 3 pixel to erode a image
+void BErodeHorizontal3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
+{
+	WORD x, y, wcounts;
+
+	if (rows <= 2 || columns <= 2)return;
+
+	// left line
+	for (y = 0; y < rows; y++)
+	{
+		*(target + (DWORD)y * columns) = 0;
+	}
+
+	// right line
+	for (y = 0; y < rows; y++)
+	{
+		*(target + (DWORD)y * columns + columns - 1) = 0;
+	}
+
+
+	for (y = 0; y < rows; y++)
+	{
+		for (x = 1; x < columns - 1; x++)
+		{
+			if (*(source + (DWORD)y * columns + x) == 0)
+			{
+				*(target + (DWORD)y * columns + x) = 0;
+				continue;
+			}
+
+			wcounts = 0;
+			if (*(source + (DWORD)y * columns + x - 1) == 255)
+			{
+				wcounts++;
+			}
+			if (*(source + (DWORD)y * columns + x + 1) == 255)
+			{
+				wcounts++;
+			}
+
+			if (wcounts == 2) *(target + (DWORD)y * columns + x) = 255;
+			else *(target + (DWORD)y * columns + x) = 0;
+		}
+	}
+
+}
+// use right 45 degree line of 3 pixel to erode a image
+void BErodeRight45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
+{
+	WORD x, y, wcounts;
+
+	if (rows <= 2 || columns <= 2)return;
+
+	// top line
+	for (x = 0; x < columns; x++)
+	{
+		*(target + x) = 0;
+	}
+
+	// bottom line
+	for (x = 0; x < columns; x++)
+	{
+		*(target + (DWORD)(rows - 1) * columns + x) = 0;
+	}
+
+	// left line
+	for (y = 0; y < rows; y++)
+	{
+		*(target + (DWORD)y * columns) = 0;
+	}
+
+	// right line
+	for (y = 0; y < rows; y++)
+	{
+		*(target + (DWORD)y * columns + columns - 1) = 0;
+	}
+
+
+	for (y = 1; y < rows - 1; y++)
+	{
+		for (x = 1; x < columns - 1; x++)
+		{
+			if (*(source + (DWORD)y * columns + x) == 0)
+			{
+				*(target + (DWORD)y * columns + x) = 0;
+				continue;
+			}
+
+			wcounts = 0;
+			if (*(source + (DWORD)(y - 1) * columns + x + 1) == 255)
+			{
+				wcounts++;
+			}
+			if (*(source + (DWORD)(y + 1) * columns + x - 1) == 255)
+			{
+				wcounts++;
+			}
+
+			if (wcounts == 2) *(target + (DWORD)y * columns + x) = 255;
+			else *(target + (DWORD)y * columns + x) = 0;
+		}
+	}
+
+
+}
+void BDilateVertical3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
+{
+	WORD x, y;
+
+	if (rows <= 2 || columns <= 2)return;
+
+	// top line
+	for (x = 0; x < columns; x++)
+	{
+		if (*(source + x) != 0)
+		{
+			*(target + x) = 0xff;
+		}
+	}
+
+	// bottom line
+	for (x = 0; x < columns; x++)
+	{
+		if (*(source + (DWORD)(rows - 1) * columns + x) != 0)
+		{
+			*(target + (DWORD)(rows - 1) * columns + x) = 0xff;
+		}
+	}
+
+	for (y = 1; y < rows - 1; y++)
+	{
+		for (x = 1; x < columns - 1; x++)
+		{
+			if (*(source + (DWORD)y * columns + x) != 0)
+			{
+				*(target + (DWORD)y * columns + x) = 0xff;
+				*(target + (DWORD)(y - 1) * columns + x) = 255;
+				*(target + (DWORD)(y + 1) * columns + x) = 255;
+			}
+			else *(target + (DWORD)y * columns + x) = 0;
+		}
+	}
+
+}
+void BDilateLeft45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
+{
+	WORD x, y;
+
+	if (rows <= 2 || columns <= 2)return;
+
+	// top line
+	for (x = 0; x < columns; x++)
+	{
+		if (*(source + x) != 0)
+		{
+			*(target + x) = 0xff;
+		}
+	}
+
+	// bottom line
+	for (x = 0; x < columns; x++)
+	{
+		if (*(source + (DWORD)(rows - 1) * columns + x) != 0)
+		{
+			*(target + (DWORD)(rows - 1) * columns + x) = 0xff;
+		}
+	}
+
+	// left line
+	for (y = 0; y < rows; y++)
+	{
+		if (*(source + (DWORD)y * columns) != 0)
+		{
+			*(target + (DWORD)y * columns) = 0xff;
+		}
+	}
+
+	// right line
+	for (y = 0; y < rows; y++)
+	{
+		if (*(source + (DWORD)y * columns + columns - 1) != 0)
+		{
+			*(target + (DWORD)y * columns + columns - 1) = 0xff;
+		}
+	}
+
+	for (y = 1; y < rows - 1; y++)
+	{
+		for (x = 1; x < columns - 1; x++)
+		{
+			if (*(source + (DWORD)y * columns + x) != 0)
+			{
+				*(target + (DWORD)y * columns + x) = 0xff;
+				*(target + (DWORD)(y - 1) * columns + x - 1) = 255;
+				*(target + (DWORD)(y + 1) * columns + x + 1) = 255;
+			}
+			else *(target + (DWORD)y * columns + x) = 0;
+		}
+	}
+
+}
+void BDilateHorizontal3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
+{
+	WORD x, y;
+
+	if (rows <= 2 || columns <= 2)return;
+
+	// left line
+	for (y = 0; y < rows; y++)
+	{
+		if (*(source + (DWORD)y * columns) != 0)
+		{
+			*(target + (DWORD)y * columns) = 0xff;
+		}
+	}
+
+	// right line
+	for (y = 0; y < rows; y++)
+	{
+		if (*(source + (DWORD)y * columns + columns - 1) != 0)
+		{
+			*(target + (DWORD)y * columns + columns - 1) = 0xff;
+		}
+	}
+
+	for (y = 1; y < rows - 1; y++)
+	{
+		for (x = 1; x < columns - 1; x++)
+		{
+			if (*(source + (DWORD)y * columns + x) != 0)
+			{
+				*(target + (DWORD)y * columns + x) = 0xff;
+				*(target + (DWORD)y * columns + x - 1) = 255;
+				*(target + (DWORD)y * columns + x + 1) = 255;
+			}
+			else *(target + (DWORD)y * columns + x) = 0;
+		}
+	}
+}
+void BDilateRight45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns)
+{
+	WORD x, y;
+
+	if (rows <= 2 || columns <= 2)return;
+
+	// top line
+	for (x = 0; x < columns; x++)
+	{
+		if (*(source + x) != 0)
+		{
+			*(target + x) = 0xff;
+		}
+	}
+
+	// bottom line
+	for (x = 0; x < columns; x++)
+	{
+		if (*(source + (DWORD)(rows - 1) * columns + x) != 0)
+		{
+			*(target + (DWORD)(rows - 1) * columns + x) = 0xff;
+		}
+	}
+
+	// left line
+	for (y = 0; y < rows; y++)
+	{
+		if (*(source + (DWORD)y * columns) != 0)
+		{
+			*(target + (DWORD)y * columns) = 0xff;
+		}
+	}
+
+	// right line
+	for (y = 0; y < rows; y++)
+	{
+		if (*(source + (DWORD)y * columns + columns - 1) != 0)
+		{
+			*(target + (DWORD)y * columns + columns - 1) = 0xff;
+		}
+	}
+
+	for (y = 1; y < rows - 1; y++)
+	{
+		for (x = 1; x < columns - 1; x++)
+		{
+			if (*(source + (DWORD)y * columns + x) != 0)
+			{
+				*(target + (DWORD)y * columns + x) = 0xff;
+				*(target + (DWORD)(y - 1) * columns + x + 1) = 255;
+				*(target + (DWORD)(y + 1) * columns + x - 1) = 255;
+			}
+			else *(target + (DWORD)y * columns + x) = 0;
+		}
+	}
+
+}
+void BErode3(LPBYTE source, LPBYTE target, WORD wDegree, WORD rows, WORD columns)
+{
+	WORD x, y, i, j, wcounts;
+
+	if (rows == 1 || columns == 1)return;
+
+	for (y = 1; y < rows - 1; y++)
+	{
+		for (x = 1; x < columns - 1; x++)
+		{
+			if (*(source + (DWORD)y * columns + x) == 0)
+			{
+				*(target + (DWORD)y * columns + x) = 0;
+				continue;
+			}
+			wcounts = 0;
+			for (i = (WORD)(y - 1); i <= (WORD)(y + 1); i++)
+
+			{
+				for (j = (WORD)(x - 1); j <= (WORD)(x + 1); j++)
+				{
+					if (*(source + (DWORD)i * columns + j) == 0)
+					{
+						wcounts++;
+					}
+				}
+			}
+			if (wcounts >= wDegree) *(target + (DWORD)y * columns + x) = 0;
+			else *(target + (DWORD)y * columns + x) = 0xff;
+		}
+	}
+
+	// top line
+	for (x = 1; x < columns - (WORD)1; x++)
+	{
+		if (*(source + x) == 0)
+		{
+			*(target + x) = 0;
+			continue;
+		}
+		wcounts = 0;
+		for (i = 0; i <= 1; i++)
+
+		{
+			for (j = (WORD)(x - 1); j <= (WORD)(x + 1); j++)
+			{
+				if (*(source + (DWORD)i * columns + j) == 0) wcounts++;
+			}
+		}
+		if (wcounts >= wDegree * 5 / 8) *(target + x) = 0;
+		else *(target + x) = 0xff;
+	}
+
+	// bottom line
+	for (x = 1; x < columns - 1; x++)
+	{
+		if (*(source + (DWORD)(rows - 1) * columns + x) == 0)
+		{
+			*(target + (DWORD)(rows - 1) * columns + x) = 0;
+			continue;
+		}
+		wcounts = 0;
+		for (i = (WORD)(rows - 2); i <= (WORD)(rows - 1); i++)
+
+		{
+			for (j = (WORD)(x - 1); j <= (WORD)(x + 1); j++)
+			{
+				if (*(source + (DWORD)i * columns + j) == 0) wcounts++;
+			}
+		}
+		if (wcounts >= wDegree * 5 / 8) *(target + (DWORD)(rows - 1) * columns + x) = 0;
+		else *(target + (DWORD)(rows - 1) * columns + x) = 0xff;
+	}
+
+	// left line
+	for (y = 1; y < rows - 1; y++)
+	{
+		if (*(source + (DWORD)y * columns) == 0)
+		{
+			*(target + (DWORD)y * columns) = 0;
+			continue;
+		}
+		wcounts = 0;
+		for (i = (WORD)(y - 1); i <= (WORD)(y + 1); i++)
+		{
+			for (j = 0; j <= 1; j++)
+			{
+				if (*(source + (DWORD)i * columns + j) == 0) wcounts++;
+			}
+		}
+		if (wcounts >= wDegree * 5 / 8) *(target + (DWORD)y * columns) = 0;
+		else *(target + (DWORD)y * columns) = 0xff;
+	}
+
+	// right line
+	for (y = 1; y < rows - 1; y++)
+	{
+		if (*(source + (DWORD)y * columns + columns - 1) == 0)
+		{
+			*(target + (DWORD)y * columns + columns - 1) = 0;
+			continue;
+		}
+		wcounts = 0;
+		for (i = (WORD)(y - 1); i <= (WORD)(y + 1); i++)
+
+		{
+			for (j = (WORD)(columns - 2); j <= (WORD)(columns - 1); j++)
+			{
+				if (*(source + (DWORD)i * columns + j) == 0) wcounts++;
+			}
+		}
+		if (wcounts >= wDegree * 5 / 8) *(target + (DWORD)y * columns + columns - 1) = 0;
+		else *(target + (DWORD)y * columns + columns - 1) = 0xff;
+	}
+
+	return;
+}
+void BDilate3(LPBYTE source, LPBYTE target, WORD wDegree, WORD rows, WORD columns)
+{
+	WORD x, y, i, j, wcounts;
+
+	for (y = 1; y < rows - 1; y++)
+	{
+		for (x = 1; x < columns - 1; x++)
+		{
+			if (*(source + (DWORD)y * columns + x) != 0)
+			{
+				*(target + (DWORD)y * columns + x) = 0xff;
+				continue;
+			}
+			wcounts = 0;
+			for (i = (WORD)(y - 1); i <= (WORD)(y + 1); i++)
+			{
+				for (j = (WORD)(x - 1); j <= (WORD)(x + 1); j++)
+				{
+					if (*(source + (DWORD)i * columns + j) != 0)	wcounts++;
+				}
+			}
+			if (wcounts >= wDegree) *(target + (DWORD)y * columns + x) = 0xff;
+			else *(target + (DWORD)y * columns + x) = 0;
+		}
+	}
+
+	// top line
+	for (x = 1; x < columns - 1; x++)
+	{
+		if (*(source + x) != 0)
+		{
+			*(target + x) = 0xff;
+			continue;
+		}
+		wcounts = 0;
+		for (i = 0; i <= 1; i++)
+		{
+			for (j = (WORD)(x - 1); j <= (WORD)(x + 1); j++)
+			{
+				if (*(source + (DWORD)i * columns + j) != 0) wcounts++;
+			}
+		}
+
+		if (wcounts >= wDegree * 5 / 8)	// but does not mater, as we have border of 2 now
+		{
+			*(target + x) = 0xff;
+		}
+		else { *(target + x) = 0; }
+	}
+
+	// bottom line
+	for (x = 1; x < columns - 1; x++)
+	{
+		if (*(source + (DWORD)(rows - 1) * columns + x) != 0)
+		{
+			*(target + (DWORD)(rows - 1) * columns + x) = 0xff;
+			continue;
+		}
+		wcounts = 0;
+		for (i = (WORD)(rows - 2); i <= (WORD)(rows - 1); i++)
+		{
+			for (j = (WORD)(x - 1); j <= (WORD)(x + 1); j++)
+			{
+				if (*(source + (DWORD)i * columns + j) != 0) wcounts++;
+			}
+		}
+
+		if (wcounts > wDegree * 5 / 8)
+		{
+			*(target + (DWORD)(rows - 1) * columns + x) = 0xff;
+		}
+		else
+		{
+			*(target + (DWORD)(rows - 1) * columns + x) = 0;
+		}
+	}
+
+	// left line
+	for (y = 1; y < rows - 1; y++)
+	{
+		if (*(source + (DWORD)y * columns) != 0)
+		{
+			*(target + (DWORD)y * columns) = 0xff;
+			continue;
+		}
+		wcounts = 0;
+		for (i = (WORD)(y - 1); i <= (WORD)(y + 1); i++)
+		{
+			for (j = 0; j <= (WORD)1; j++)
+			{
+				if (*(source + (DWORD)i * columns + j) != 0) wcounts++;
+			}
+		}
+		if (wcounts >= wDegree * 5 / 8)
+		{
+			*(target + (DWORD)y * columns) = 0xff;
+		}
+		else
+		{
+			*(target + (DWORD)y * columns) = 0;
+		}
+	}
+
+	// right line
+	for (y = 1; y < rows - 1; y++)
+	{
+		if (*(source + (DWORD)y * columns + columns - 1) != 0)
+		{
+			*(target + (DWORD)y * columns + columns - 1) = 0xff;
+			continue;
+		}
+		wcounts = 0;
+		for (i = (WORD)(y - 1); i <= (WORD)(y + 1); i++)
+		{
+			for (j = (WORD)(columns - 2); j <= (WORD)(columns - 1); j++)
+			{
+				if (*(source + (DWORD)i * columns + j) != 0) wcounts++;
+			}
+		}
+		if (wcounts >= wDegree * 5 / 8)
+		{
+			*(target + (DWORD)y * columns + columns - 1) = 0xff;
+		}
+		else
+		{
+			*(target + (DWORD)y * columns + columns - 1) = 0;
+		}
+	}
+
+	// four cornor points treated separately here
+	// top-left
+	if (*(source) != 0)
+	{
+		*target = 0xff;
+	}
+	else
+	{
+		wcounts = 0;
+		if (*(source + 1) != 0) wcounts++;
+		if (*(source + columns) != 0) wcounts++;
+		if (*(source + columns + 1) != 0) wcounts++;
+
+		//        if (wcounts >= wDegree*3/8)  // this is a bug here - interger division
+		if (wcounts * 8 >= wDegree * 3)
+		{
+			*target = 0xff;
+		}
+		else
+		{
+			*target = 0;
+		}
+	}
+
+	//top-right
+	if (*(source + columns - 1) != 0)
+	{
+		*(target + columns - 1) = 0xff;
+	}
+	else
+	{
+		wcounts = 0;
+		if (*(source + columns - 2) != 0) wcounts++;
+		if (*(source + columns * 2 - 1) != 0) wcounts++;
+		if (*(source + columns * 2 - 2) != 0) wcounts++;
+
+		//        if (wcounts >= wDegree*3/8)  // this is a bug here - interger division
+		if (wcounts * 8 >= wDegree * 3)
+		{
+			*(target + columns - 1) = 0xff;
+		}
+		else
+		{
+			*(target + columns - 1) = 0;
+		}
+	}
+
+	//bottom-left
+	if (*(source + (DWORD)columns * (rows - 1)) != 0)
+	{
+		*(target + (DWORD)columns * (rows - 1)) = 0xff;
+	}
+	else
+	{
+		wcounts = 0;
+		if (*(source + (DWORD)columns * (rows - 1) + 1) != 0) wcounts++;
+		if (*(source + (DWORD)columns * (rows - 2)) != 0) wcounts++;
+		if (*(source + (DWORD)columns * (rows - 2) + 1) != 0) wcounts++;
+
+		//        if (wcounts >= wDegree*3/8)  // this is a bug here - interger division
+		if (wcounts * 8 >= wDegree * 3)
+		{
+			*(target + (DWORD)columns * (rows - 1)) = 0xff;
+		}
+		else
+		{
+			*(target + (DWORD)columns * (rows - 1)) = 0;
+		}
+	}
+
+	//bottom-right
+	if (*(source + (DWORD)columns * rows - 1) != 0)
+	{
+		*(target + (DWORD)columns * rows - 1) = 0xff;
+	}
+	else
+	{
+		wcounts = 0;
+		if (*(source + (DWORD)columns * rows - 2) != 0) wcounts++;
+		if (*(source + (DWORD)columns * (rows - 1) - 2) != 0) wcounts++;
+		if (*(source + (DWORD)columns * (rows - 1) - 1) != 0) wcounts++;
+
+		//        if (wcounts >= wDegree*3/8)  // this is a bug here - interger division
+		if (wcounts * 8 >= wDegree * 3)
+		{
+			*(target + (DWORD)columns * rows - 1) = 0xff;
+		}
+		else
+		{
+			*(target + (DWORD)columns * rows - 1) = 0;
+		}
+	}
+
+	return;
+}
+

+ 29 - 0
OTSCPP/OTSImagePro/OTSMorphology.h

@@ -0,0 +1,29 @@
+#pragma once
+#include "afx.h"
+// morphology
+// LPBYTE source£º binary image pointer input£¬0, and 255
+// LPBYTE target:  image pointer output
+// WORD rows: image height
+// WORD clumns: image width
+// WORD wDegree: 1~8, eight direction selction.
+
+// erode image with a structure of verticle 3 element
+ void BErodeVertical3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
+// erode image with a left 45 degree structure of 3 element
+ void BErodeLeft45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
+// erode image with a structure of horizontal 3 element
+ void BErodeHorizontal3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
+// erode image with a right 45 degree structure of 3 element
+ void BErodeRight45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
+// dilate image with a structure of verticle 3 element
+ void BDilateVertical3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
+// dilate image with a left 45 degree structure of 3 element
+ void BDilateLeft45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
+// dilate image with a structure of horizontal 3 element
+ void BDilateHorizontal3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
+// dilate image with a right 45 degree structure of 3 element
+ void BDilateRight45Degree3(LPBYTE source, LPBYTE target, WORD rows, WORD columns);
+// erode image with a structure of verticle 8 element
+ void BErode3(LPBYTE source, LPBYTE target, WORD wDegree, WORD rows, WORD columns);
+// dilate image with a structure of verticle 8 element
+ void BDilate3(LPBYTE source, LPBYTE target, WORD wDegree, WORD rows, WORD columns);

+ 11 - 16
OTSIncAMeasureApp/0-OTSModel/Measure/5-OTSMining/SmplMeasureMining.cs

@@ -3,22 +3,15 @@ using System.Collections.Generic;
 
 using System.Drawing;
 using System.Linq;
-
 using System.Threading;
-
 using OTSCLRINTERFACE;
 using OTSDataType;
-
 using OTSModelSharp.ServiceCenter;
-
-using static OTSDataType.otsdataconst;
-
 namespace OTSModelSharp
 {
     class CSmplMeasureMining : CSmplMeasure
     {
 
-
         public CSmplMeasureMining(string a_strWorkingFolder, COTSSample a_pSample) : base(a_strWorkingFolder, a_pSample)
         {
             SetWorkingFolder(a_strWorkingFolder);
@@ -29,7 +22,7 @@ namespace OTSModelSharp
 
 
 
-        public override  bool FieldImageProcess(COTSFieldData curFldData, CBSEImgClr a_pBSEImg)
+        public override bool FieldImageProcess(COTSFieldData curFldData, CBSEImgClr a_pBSEImg)
        {
          
 
@@ -58,6 +51,7 @@ namespace OTSModelSharp
             var analysisparts = curFldData.GetListAnalysisParticles();
             //calculate particle image property such as feret diameter, DMAX etc and calculate the xray point position simultaneously.
             COTSXRayParam pXRayParam = m_Sample.GetMsrParams().GetXRayParam();
+            CDoubleRange ecdRange = m_Sample.GetMsrParams().GetImageProcessParam().GetIncAreaRange();
             var pimageParam = m_Sample.GetMsrParams().GetImageScanParam();
             int width = pimageParam.GetImageResolutionSize().cx;
             int height = pimageParam.GetImageResolutionSize().cy;
@@ -66,11 +60,10 @@ namespace OTSModelSharp
             CImageHandler imgHandle = new CImageHandler();
             if (xrayStep == 0)
             {
-                //log.Error("XrayStep=0,is not  set!");
-                //return false;
+               
                 foreach (var p in analysisparts)
                 {
-                    imgHandle.SplitRawParticleIntoGreyScaleParticle(p,  m_Sample.CalculatePixelSize(), a_pBSEImg);
+                    imgHandle.SplitRawParticleIntoGreyScaleParticle(p,new CDoubleRangeClr(ecdRange.GetStart(),ecdRange.GetEnd()),  m_Sample.CalculatePixelSize(), a_pBSEImg);
                 }
             }
             else 
@@ -82,9 +75,6 @@ namespace OTSModelSharp
 
             }
             
-
-         
-
             if (pXRayParam.GetUsingXray() == true)
             {
                 log.Info("Begin to collect particle's xray data!");
@@ -105,7 +95,7 @@ namespace OTSModelSharp
             }
             else 
             {
-                MergeSubParticleByTheXrayClassification(curFldData, m_Sample.CalculatePixelSize());
+                ConvertSubParticleToFieldParticle(curFldData, m_Sample.CalculatePixelSize());
             }
            
 
@@ -317,7 +307,12 @@ namespace OTSModelSharp
                 var subParts = rawPart.GetSubParticles();
                 foreach (var subPart in subParts)
                 {
-                   
+                    subPart.SetAnalysisId(finalParts.Count);
+                    subPart.SetParticleId(finalParts.Count);
+                    subPart.SetFieldId(rawPart.GetFieldId());
+                    double pixelarea = subPart.GetPixelArea();
+                    double actualArea = pixelarea * pixelSize;
+                    subPart.SetActualArea(actualArea);
                     finalParts.Add(subPart);
 
                 }

+ 7 - 5
OTSIncAMeasureApp/ServiceCenter/CImageHandler.cs

@@ -196,6 +196,7 @@ namespace OTSModelSharp.ServiceCenter
 
             List<COTSParticleClr> parts = new List<COTSParticleClr>();
             List<COTSParticleClr> specialGreyparts = new List<COTSParticleClr>();
+            var ecdrange = a_pImgProcessParam.GetIncAreaRange();
             if (!RemoveBGAndGetParts(a_pImgIn, a_pImgProcessParam, a_pixelSize, ref parts))
             {
                 return;
@@ -251,7 +252,7 @@ namespace OTSModelSharp.ServiceCenter
             foreach (var p in parts)
             {
                 OTSCLRINTERFACE.ImageProForClr imgpro = new OTSCLRINTERFACE.ImageProForClr();
-                imgpro.SplitRawParticleIntoGreyScaleParticle(p, a_pixelSize, a_pImgIn);
+                imgpro.SplitRawParticleIntoGreyScaleParticle(p,new CDoubleRangeClr(ecdrange.GetStart(),ecdrange.GetEnd()),  a_pixelSize, a_pImgIn);
                 var subparts = p.GetSubParticles();
                 foreach (var subp in subparts)
                 {
@@ -282,6 +283,7 @@ namespace OTSModelSharp.ServiceCenter
 
             List<COTSParticleClr> parts = new List<COTSParticleClr>();
             List<COTSParticleClr> specialGreyparts = new List<COTSParticleClr>();
+            var ecdrange = a_pImgProcessParam.GetIncAreaRange();
             if (!RemoveBGAndGetParts(a_pImgIn, a_pImgProcessParam, a_pixelSize, ref parts))
             {
                 return;
@@ -338,7 +340,7 @@ namespace OTSModelSharp.ServiceCenter
             foreach (var p in parts)
             {
                 OTSCLRINTERFACE.ImageProForClr imgpro = new OTSCLRINTERFACE.ImageProForClr();
-                imgpro.SplitRawParticleIntoGreyScaleParticle(p, a_pixelSize, a_pImgIn);
+                imgpro.SplitRawParticleIntoGreyScaleParticle(p,new CDoubleRangeClr(ecdrange.GetStart(),ecdrange.GetEnd()), a_pixelSize, a_pImgIn);
                 var subparts = p.GetSubParticles();
                 foreach (var subp in subparts)
                 {
@@ -488,10 +490,10 @@ namespace OTSModelSharp.ServiceCenter
 
             return true;
         }
-        public bool SplitRawParticleIntoGreyScaleParticle(COTSParticleClr part,  double a_pixelSize, CBSEImgClr fieldImage)
+        public bool SplitRawParticleIntoGreyScaleParticle(COTSParticleClr part,CDoubleRangeClr ecdRange,  double a_pixelSize, CBSEImgClr fieldImage)
         {
             ImageProForClr imgpro = new ImageProForClr();
-            imgpro.SplitRawParticleIntoGreyScaleParticle(part, a_pixelSize, fieldImage);
+            imgpro.SplitRawParticleIntoGreyScaleParticle(part,ecdRange, a_pixelSize, fieldImage);
 
             return true;
         }
@@ -559,7 +561,7 @@ namespace OTSModelSharp.ServiceCenter
                 }
                 fldclrs.Add(fldclr);
             }
-            OTSCLRINTERFACE.ImageProForClr imgpro = new OTSCLRINTERFACE.ImageProForClr();
+            ImageProForClr imgpro = new ImageProForClr();
 
             imgpro.MergeBigBoundaryParticles(fldclrs, pixelSize, scanFieldSize, ResolutionSize, mergedParts);
             return true;