Selaa lähdekoodia

add minimum simulate value while identify spectrum data particles.

gsp 2 vuotta sitten
vanhempi
commit
36f3377b22

+ 17 - 8
OTSCPP/OTSClassifyEngine/CurveCompareEngine.cpp

@@ -63,19 +63,28 @@ bool CurveCompareEngine::Classify(COTSParticlePtr particle, CPosXrayPtr xray)
 	
 	auto stditm = m_Engine->GetMatchingSTD( xray, dSim);
 
-	//if (dSim > 0.05)
-	
-	if (stditm != nullptr)
+	if (dSim > 0.8)
 	{
-		particle->SetType(OTS_PARTICLE_TYPE::IDENTIFIED);
-		particle->SetClassifyId(stditm->GetID());
-		particle->TypeName(stditm->GetName().GetBuffer());
-		particle->TypeColor(std::to_string(stditm->GetColor()));
-	}else
+		if (stditm != nullptr)
+		{
+			particle->SetType(OTS_PARTICLE_TYPE::IDENTIFIED);
+			particle->SetClassifyId(stditm->GetID());
+			particle->TypeName(stditm->GetName().GetBuffer());
+			particle->TypeColor(std::to_string(stditm->GetColor()));
+		}
+		else
+		{
+			particle->SetType(OTS_PARTICLE_TYPE::NOT_IDENTIFIED);
+			particle->TypeName("Not Identified");
+		}
+	}
+	else
 	{
 		particle->SetType(OTS_PARTICLE_TYPE::NOT_IDENTIFIED);
 		particle->TypeName("Not Identified");
 	}
+	
+	
 
 	return true;
 }

+ 2 - 2
OTSCPP/OTSClrInterface/CommonClr/OTSParticleClr.h

@@ -192,12 +192,12 @@ namespace OTSCLRINTERFACE {
 		}
 		String^ GetSubParticlesName()
 		{
-			return gcnew String(m_Particle->get()->GetSubParticlesName().c_str());
+			return gcnew String(m_Particle->get()->GetConnectedParticlesSequentialString().c_str());
 		}
 		void SetSubParticlesName(String^ val)
 		{
 			std::string val1 = marshal_as<std::string>(val);
-			return m_Particle->get()->SetSubParticlesName(val1);
+			return m_Particle->get()->SetConnectedParticlesSequentialString(val1);
 		}
 
 		String^ GetGrpName()

+ 5 - 0
OTSCPP/OTSClrInterface/ImageProClr/ImageProForClr.h

@@ -39,6 +39,11 @@ namespace OTSCLRINTERFACE
 			  bool ret = COTSImageProcess::SplitRawParticleIntoGreyScaleParticle(particle->GetOTSParticlePtr(), ecdRange->GetCDoubleRangePtr(), a_PixelSize, fieldImg->GetBSEImgPtr());
 			  return ret;
 		  }
+		  bool SplitRawParticleIntoWaterShedParticle(COTSParticleClr^ particle, CDoubleRangeClr^ ecdRange, double a_PixelSize, CBSEImgClr^ fieldImg)
+		  {
+			  bool ret = COTSImageProcess::SplitRawParticleIntoWaterShedParticle(particle->GetOTSParticlePtr(),  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)
 		  {

+ 21 - 2
OTSCPP/OTSData/BSEImg.cpp

@@ -153,8 +153,7 @@ namespace OTSDATA {
 	// set image data
 	void CBSEImg::SetImageData(BYTE* a_pnImageData,int imgwidth,int imgheight)
 	{
-		// input check
-		//AMICS_ASSERT(a_pnImageData);
+	
 		if (!a_pnImageData)
 		{
 			return;
@@ -167,6 +166,26 @@ namespace OTSDATA {
 			// copy image data over
 			memcpy(m_pnImageData, a_pnImageData, sizeof(BYTE) * imgwidth * imgheight);
 		
+	}
+	void CBSEImg::SetImageDataPointer(BYTE* a_pnImageData, int imgwidth, int imgheight)
+	{
+		if (!a_pnImageData)
+		{
+			return;
+		}
+
+		// initialize image data
+	
+		if (m_pnImageData)
+		{
+			delete[]m_pnImageData;
+			m_pnImageData = NULL;
+		}
+		m_rectImage = new CRect(0, 0, imgwidth, imgheight);
+
+		// copy image data over
+		m_pnImageData = a_pnImageData;
+	
 	}
 
 	// initial chart data

+ 1 - 0
OTSCPP/OTSData/BSEImg.h

@@ -36,6 +36,7 @@ namespace OTSDATA {
 		void InitImageData(int imgwidth, int imgheight);
 		BYTE* GetImageDataPointer() const { return m_pnImageData; }
 		void SetImageData(BYTE* a_pnImageData,int imgwidth,int imgheight);
+		void SetImageDataPointer(BYTE* a_pnImageData, int imgwidth, int imgheight);
 
 		// BSE chart  
 		// NOTE: to use chart data, call SetChartData method first!

+ 2 - 2
OTSCPP/OTSData/OTSParticle.cpp

@@ -11,7 +11,7 @@ namespace OTSDATA {
 	COTSParticle::COTSParticle()													// constructor
 	{
 		Init();
-		headerParticle = NULL;
+		//headerParticle = NULL;
 	}
 
 	COTSParticle::COTSParticle(const COTSParticle& a_oSource)								// copy constructor
@@ -545,7 +545,7 @@ namespace OTSDATA {
 		m_Height = a_oSource.m_Height;
 		m_TypeName = a_oSource.m_TypeName;
 		m_TypeColor = a_oSource.m_TypeColor;
-		headerParticle = a_oSource.headerParticle;
+	
 		// feature
 		m_pFeature = COTSFeaturePtr(new COTSFeature(*a_oSource.m_pFeature.get()));
 	}

+ 3 - 4
OTSCPP/OTSData/OTSParticle.h

@@ -176,8 +176,8 @@ const double Pi = 3.14159;
 		std::string GetConductivity() const { return m_conductivity; }
 		void SetConductivity(std::string val) { m_conductivity = val; }
 
-		std::string GetSubParticlesName() const { return m_SubParticlesName; }
-		void SetSubParticlesName(std::string val) { m_SubParticlesName = val; }
+		std::string GetConnectedParticlesSequentialString() const { return m_connectedParticlesName; }
+		void SetConnectedParticlesSequentialString(std::string val) { m_connectedParticlesName = val; }
 
 		std::vector<std::shared_ptr<COTSParticle>> GetSubParticles() const { return m_subParticles; }
 		void SetSubParticles(std::vector<std::shared_ptr<COTSParticle>> val) { m_subParticles = val; }
@@ -189,7 +189,6 @@ const double Pi = 3.14159;
 
 		BOOL IsConnected(COTSParticle* a_p, int fldwidth, int fldheight, int direction);
 
-		COTSParticle* headerParticle;//used to merge particles ,if this particle has been merged then this pointer will point to the first particle of these merged particles else it's NULL.
 	    
 		int GetGroupId() { return (int)m_grpId; }
 		void SetGroupId(int a_grpId) { m_grpId = (IDENTIFIED_INC_GRP_ID)a_grpId; }
@@ -264,7 +263,7 @@ protected:
 		std::string m_density;
 		std::string m_conductivity;
 
-		std::string m_SubParticlesName;
+		std::string m_connectedParticlesName;
 
 		std::vector<std::shared_ptr<COTSParticle>> m_subParticles;
 		// tag id

+ 372 - 50
OTSCPP/OTSImagePro/OTSImageProcess.cpp

@@ -297,6 +297,115 @@ namespace OTSIMGPROC
 
 
 		}
+
+		void 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, 11);//get rid of the noise point.
+				//cv::bilateralFilter
+				cv::GaussianBlur(cvcopyImg, cvcopyImg, Size(5, 5), 2);
+				//inImg->SetImageData(cvcopyImg.data, width, height);
+				/*outImg = inImg;*/
+			
+		}
+		Mat GetMatDataFromBseImg(CBSEImgPtr inImg)
+		{
+			int rows, cols;
+			cols = inImg->GetWidth();
+			rows = inImg->GetHeight();
+			BYTE* pPixel = inImg->GetImageDataPointer();
+			Mat cvcopyImg = Mat(rows, cols, CV_8UC1, pPixel);
+			return cvcopyImg;
+		}
+		CBSEImgPtr GetBSEImgFromMat(Mat inImg)
+		{
+			CBSEImgPtr bse = CBSEImgPtr(new CBSEImg(CRect(0, 0, inImg.cols, inImg.rows)));
+		
+			BYTE* pPixel = inImg.data;
+		
+			bse->SetImageData(pPixel, inImg.cols, inImg.rows);
+
+
+			return bse;
+		}
+		/***********************************************************
+增强算法的原理在于先统计每个灰度值在整个图像中所占的比例
+然后以小于当前灰度值的所有灰度值在总像素中所占的比例,作为增益系数
+对每一个像素点进行调整。由于每一个值的增益系数都是小于它的所有值所占
+的比例和。所以就使得经过增强之后的图像亮的更亮,暗的更暗。
+************************************************************/
+		void ImageStretchByHistogram(const Mat& src, Mat& dst)
+		{
+			//判断传入参数是否正常
+			if (!(src.size().width == dst.size().width))
+			{
+				cout << "error" << endl;
+				return;
+			}
+			double p[256], p1[256], num[256];
+
+			memset(p, 0, sizeof(p));
+			memset(p1, 0, sizeof(p1));
+			memset(num, 0, sizeof(num));
+			int height = src.size().height;
+			int width = src.size().width;
+			long wMulh = height * width;
+
+			//统计每一个灰度值在整个图像中所占个数
+			for (int x = 0; x < width; x++)
+			{
+				for (int y = 0; y < height; y++)
+				{
+					uchar v = src.at<uchar>(y, x);
+					num[v]++;
+				}
+			}
+
+			//使用上一步的统计结果计算每一个灰度值所占总像素的比例
+			for (int i = 0; i < 256; i++)
+			{
+				p[i] = num[i] / wMulh;
+			}
+
+			//计算每一个灰度值,小于当前灰度值的所有灰度值在总像素中所占的比例
+			//p1[i]=sum(p[j]);	j<=i;
+			for (int i = 0; i < 256; i++)
+			{
+				for (int k = 0; k <= i; k++)
+					p1[i] += p[k];
+			}
+
+			//以小于当前灰度值的所有灰度值在总像素中所占的比例,作为增益系数对每一个像素点进行调整。
+			for (int y = 0; y < height; y++)
+			{
+				for (int x = 0; x < width; x++) {
+					uchar v = src.at<uchar>(y, x);
+					dst.at<uchar>(y, x) = p1[v] * 255 + 0.5;
+				}
+			}
+			return;
+		}
+		//调整图像对比度
+		Mat AdjustContrastY(const Mat& img)
+		{
+			Mat out = Mat::zeros(img.size(), CV_8UC1);
+			Mat workImg = img.clone();
+
+			//对图像进行对比度增强
+			ImageStretchByHistogram(workImg, out);
+
+			return Mat(out);
+		}
+
+
+
+
 	}
 
 	COTSImageProcess::COTSImageProcess()
@@ -1011,9 +1120,9 @@ namespace OTSIMGPROC
 
 		linearSmooth5(originChartData, firstSmoothChart, MAXBYTE);
 		linearSmooth5(firstSmoothChart, secondSmooth, MAXBYTE);
-		linearSmooth5(secondSmooth, secondSmooth, MAXBYTE);
-		linearSmooth5(secondSmooth, secondSmooth, MAXBYTE);
 		//linearSmooth5(secondSmooth, secondSmooth, MAXBYTE);
+		/*linearSmooth5(secondSmooth, secondSmooth, MAXBYTE);
+		linearSmooth5(secondSmooth, secondSmooth, MAXBYTE);*/
 		
 		//2. get down edge		
 		int nLengthEdge = MAXBYTE + 2;
@@ -1911,6 +2020,10 @@ namespace OTSIMGPROC
 		}
 		/*ImshowImage(onePartImg);
 		ImshowChartData(onePartImg);*/
+		/*auto imgData = GetMatDataFromBseImg(onePartImg);
+		imgData = AdjustContrastY(imgData);
+		auto adjustImg = GetBSEImgFromMat(imgData);
+		ImshowImage(adjustImg);*/
 		BlurImage(onePartImg);
 		std::vector<CIntRangePtr> rngs = CalcuGrayLevelRange(onePartImg);
 		
@@ -1972,6 +2085,194 @@ namespace OTSIMGPROC
 
 
 
+		return 0;
+	}
+	BOOL COTSImageProcess::SplitRawParticleIntoWaterShedParticle(COTSParticlePtr a_pOTSPart, double a_PixelSize, CBSEImgPtr fieldImg)
+	{
+		//--------- convert this particle data to image data,construct an image only with this particle.------
+		const int nExpand_Size = 3;
+		const int nWhiteColor = 0;
+		const int nThickness = 1;
+		// lineType Type of the line
+		const int nLineType = 8;
+		// get rectangle of the particle
+		CRect rect = a_pOTSPart->GetParticleRect();
+		if (a_pOTSPart->GetActualArea() < 5 * a_PixelSize)// the particle is too small that openCV can't calculate a width value 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;
+		}
+
+		// calculate the particle image data size, expand 3 pixel at the edge
+
+		CBSEImgPtr onePartImg = CBSEImgPtr(new CBSEImg(CRect(0, 0, fieldImg->GetWidth(), fieldImg->GetHeight())));
+		CBSEImgPtr rawOnePartImg = CBSEImgPtr(new CBSEImg(CRect(0, 0, fieldImg->GetWidth(), fieldImg->GetHeight())));
+		// get the segment list
+		/*for (int i = 0; i < fieldImg->GetWidth(); i++)
+		{
+			for (int j = 0; j < fieldImg->GetHeight(); j++)
+			{
+				rawOnePartImg->SetBSEValue(i, j, 255);
+			}
+		}*/
+
+		COTSSegmentsList listSegment = a_pOTSPart->GetFeature()->GetSegmentsList();
+		for (auto pSegment : listSegment)
+		{
+			for (int i = 0; i < pSegment->GetLength(); i++)
+			{
+				int x = pSegment->GetStart() + i;
+				int y = pSegment->GetHeight();
+				int bseValue = fieldImg->GetBSEValue(x, y);
+				onePartImg->SetBSEValue(x, y, bseValue);
+				rawOnePartImg->SetBSEValue(x, y, bseValue);
+			}
+		}
+		//ImshowImage(rawOnePartImg);
+		//ImshowChartData(onePartImg);
+		BlurImage(onePartImg);
+		Mat partMat = GetMatDataFromBseImg(onePartImg);
+
+		Canny(partMat, partMat, 10, 300,3);
+	/*	cv::imshow("ddd2", partMat);
+		cv::waitKey();*/
+		//查找轮廓  
+		vector<vector<Point>> contours;
+		vector<Vec4i> hierarchy;
+		findContours(partMat, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
+
+		//Mat imageContours = Mat::zeros(partMat.size(), CV_8UC1);  //轮廓     
+		Mat marks(partMat.size(), CV_32S);
+		marks = Scalar::all(0);
+		int index = 0;
+		int compCount =10;
+		for (; index >= 0; index = hierarchy[index][0], compCount++)
+		{
+			//对marks进行标记,对不同区域的轮廓进行编号,相当于设置注水点,有多少轮廓,就有多少注水点 
+	        //marks与imageContours差别就是在颜色的赋值上,marks是不同轮廓赋予不同的值,imageContours是轮廓赋值白色
+			//要绘制轮廓的图像; 所有输入的轮廓,每个轮廓被保存成一个point向量; index指定要绘制轮廓的编号,如果是负数,则绘制所有的轮廓;
+			//绘制轮廓所用的颜色; 绘制轮廓的线的粗细,如果是负数,则轮廓内部被填充; 
+			//绘制轮廓的线的连通性; 关于层级的可选参数,只有绘制部分轮廓时才会用到
+			
+			drawContours(marks, contours, index, Scalar::all(compCount+1 ), 1, 8, hierarchy); 
+			//drawContours(imageContours, contours, index, Scalar(255), 1, 8, hierarchy);
+		}
+		/*cv::imshow("ddd", marks);
+		cv::waitKey();*/
+		auto rawData = GetMatDataFromBseImg(rawOnePartImg);
+		/*cv::imshow("ddd3", rawData);
+		cv::waitKey();*/
+		Mat imageGray3;
+		cvtColor(rawData, imageGray3, CV_GRAY2RGB);//灰度转换 
+	
+		watershed(imageGray3, marks); //分水岭算法实现 
+		/*cv::imshow("ddd", marks);
+		cv::waitKey();*/
+
+		Mat PerspectiveImage = Mat::zeros(imageGray3.size(), CV_8UC1);
+		for (int i = 0; i < marks.rows; i++)  //maks是区域图
+		{
+			for (int j = 0; j < marks.cols; j++)
+			{
+				int index = marks.at<int>(i, j);
+				if (marks.at<int>(i, j) == -1)
+				{
+					PerspectiveImage.at<uchar>(i, j) = 0;
+				}
+				else
+				{
+					PerspectiveImage.at<uchar>(i, j) = index;
+				}
+			}
+		}
+		
+
+		onePartImg->SetImageData(PerspectiveImage.data,marks.cols,marks.rows);
+
+
+		std::vector<CIntRangePtr> rngs;
+		for (int i = 10; i< compCount; i++)
+		{
+			rngs.push_back(CIntRangePtr(new CIntRange(i, i)));
+
+		}
+
+		
+
+		CDoubleRangePtr ecdRange = CDoubleRangePtr(new CDoubleRange(0, 1000));
+
+		COTSFieldDataPtr partData = COTSFieldDataPtr(new COTSFieldData());
+		std::map<int, std::vector<COTSParticlePtr>> partAreaMap;
+		for (int i = 0; i < rngs.size(); i++)
+		{
+			partAreaMap.clear();
+
+			GetParticlesBySpecialGrayRange(onePartImg, rngs[i], ecdRange, a_PixelSize, partData);
+
+
+
+			for (auto p : partData->GetParticleList())//sorting and filtering
+			{
+				auto r1=a_pOTSPart->GetParticleRect();
+				auto pnt = p->GetParticleRect().CenterPoint();
+				if (pnt.x > r1.left && pnt.x<r1.left + r1.Width() && pnt.y>r1.top && pnt.y < r1.top + r1.Height())
+				{
+					partAreaMap[p->GetPixelArea()].push_back(p);
+				}
+				/*if (p->GetActualArea() > 50)
+				{*/
+				//partAreaMap[p->GetPixelArea()].push_back(p);
+				//}
+
+			}
+			if (partAreaMap.size() > 0)
+			{
+				auto theBiggestPart = partAreaMap.rbegin()->second[0];
+				theBiggestPart->CalXRayPos();
+				std::map<int, std::vector<COTSParticlePtr>>::reverse_iterator it;
+				auto partsegs = theBiggestPart->GetFeature()->GetSegmentsList();
+				it = partAreaMap.rbegin()++;
+				for (; it != partAreaMap.rend(); it++)
+				{
+					for (auto sameAreaP : it->second)
+					{
+						auto segs = sameAreaP->GetFeature()->GetSegmentsList();
+						for (auto s : segs)
+						{
+							partsegs.push_back(s);
+						}
+					}
+
+				}
+				theBiggestPart->GetFeature()->SetSegmentsList(partsegs, true);
+				theBiggestPart->CalCoverRect();
+				theBiggestPart->SetFieldId(a_pOTSPart->GetFieldId());
+				theBiggestPart->SetAnalysisId(a_pOTSPart->GetAnalysisId());
+				a_pOTSPart->AddSubParticle(theBiggestPart);
+
+
+			}
+
+
+			/*for (auto p : partData->GetParticleList())
+			{
+				a_pOTSPart->AddSubParticle(p);
+			}*/
+		}
+
+
+
+
 		return 0;
 	}
 	void COTSImageProcess::ImshowImage(CBSEImgPtr img)
@@ -2013,23 +2314,36 @@ 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, 11);//get rid of the noise point.
-		//cv::GaussianBlur(cvcopyImg, cvcopyImg, Size(3, 3), 3);
-		//inImg->SetImageData(cvcopyImg.data, width, height);
-		/*outImg = inImg;*/
-	}
+	
 
 	BOOL COTSImageProcess::MergeBigBoundaryParticles(COTSFieldDataList allFields,double pixelSize,int scanFieldSize, CSize ResolutionSize, COTSParticleList& mergedParts)
 	{
-		COTSSegmentsList boarderSegs;
+		class BorderPart
+		{
+			typedef std::shared_ptr<BorderPart>  CBorderPartPtr;
+			BorderPart(COTSParticlePtr p)
+			{
+				myPart = p;
+				headerParticle = NULL;
+			}
+		public:
+			COTSParticlePtr myPart;
+			COTSParticle* headerParticle;//used to merge particles ,if this particle has been merged then this pointer will point to the first particle of these merged particles or else it's NULL.
+		
+			
+			static std::vector<CBorderPartPtr> ConvertPartToBorderPart(COTSParticleList parts)
+			{
+				std::vector<CBorderPartPtr> borderParts;
+				for (auto p : parts)
+				{
+					borderParts.push_back(CBorderPartPtr(new BorderPart(p)));
+
+				}
+				return borderParts;
+			
+			}
+
+		};
 
 		auto FldMgr = new CFieldMgr(scanFieldSize, ResolutionSize);
 	
@@ -2043,36 +2357,38 @@ namespace OTSIMGPROC
 			auto leftFld = FldMgr->FindNeighborField(allFields, centerfld, SORTING_DIRECTION::LEFT);
 			if (leftFld != nullptr)
 			{
-				auto leftParts = centerfld->GetLeftBorderedBigParticles();
-				auto rightParts = leftFld->GetRightBorderedBigParticles();
+				auto lParts = centerfld->GetLeftBorderedBigParticles();
+				auto rParts = leftFld->GetRightBorderedBigParticles();
+				auto leftParts = BorderPart::ConvertPartToBorderPart(lParts);
+				auto rightParts = BorderPart::ConvertPartToBorderPart(rParts);
 
 				for (auto leftp : leftParts)
 				{
 					for (auto rightp : rightParts)
 					{
-						if (leftp->IsConnected(rightp.get(), centerfld->Width, centerfld->Height, (int)SORTING_DIRECTION::LEFT))
+						if (leftp->myPart->IsConnected(rightp->myPart.get(), centerfld->Width, centerfld->Height, (int)SORTING_DIRECTION::LEFT))
 						{
 							if (leftp->headerParticle != NULL)
 							{
 								if (rightp->headerParticle == NULL)
 								{
 									rightp->headerParticle = leftp->headerParticle;
-									mapMergeParticles[leftp->headerParticle].push_back(rightp);
+									mapMergeParticles[leftp->headerParticle].push_back(rightp->myPart);
 								}
 							}
 							else
 							{
 								if (rightp->headerParticle != NULL)
 								{
-									leftp->headerParticle = rightp.get();
+									leftp->headerParticle = rightp->myPart.get();
 
-									mapMergeParticles[rightp.get()].push_back(leftp);
+									mapMergeParticles[rightp->myPart.get()].push_back(leftp->myPart);
 								}
 								else
 								{
-									leftp->headerParticle = leftp.get();
-									rightp->headerParticle = leftp.get();
-									mapMergeParticles[leftp.get()].push_back(rightp);
+									leftp->headerParticle = leftp->myPart.get();
+									rightp->headerParticle = leftp->myPart.get();
+									mapMergeParticles[leftp->myPart.get()].push_back(rightp->myPart);
 								}
 
 							}
@@ -2086,14 +2402,16 @@ namespace OTSIMGPROC
 			auto upFld = FldMgr->FindNeighborField(allFields, centerfld, SORTING_DIRECTION::UP);
 			if (upFld != nullptr)
 			{
-				auto upParts = centerfld->GetTopBorderedBigParticles();
-				auto downParts = upFld->GetBottomBorderedBigParticles();
+				auto topBorderParts = centerfld->GetTopBorderedBigParticles();
+				auto bottomBorderParts = upFld->GetBottomBorderedBigParticles();
+				auto upParts = BorderPart::ConvertPartToBorderPart(topBorderParts);
+				auto downParts = BorderPart::ConvertPartToBorderPart(bottomBorderParts);
 
 				for (auto upprt : upParts)
 				{
 					for (auto downprt : downParts)
 					{
-						if (upprt->IsConnected(downprt.get(), centerfld->Width, centerfld->Height, (int)SORTING_DIRECTION::UP))
+						if (upprt->myPart->IsConnected(downprt->myPart.get(), centerfld->Width, centerfld->Height, (int)SORTING_DIRECTION::UP))
 						{
 
 							if (upprt->headerParticle != NULL)
@@ -2101,7 +2419,7 @@ namespace OTSIMGPROC
 								if (downprt->headerParticle == NULL)
 								{
 									downprt->headerParticle = upprt->headerParticle;
-									mapMergeParticles[upprt->headerParticle].push_back(downprt);
+									mapMergeParticles[upprt->headerParticle].push_back(downprt->myPart);
 								}
 
 							}
@@ -2110,13 +2428,13 @@ namespace OTSIMGPROC
 								if (downprt->headerParticle != NULL)
 								{
 									upprt->headerParticle = downprt->headerParticle;
-									mapMergeParticles[downprt.get()].push_back(upprt);
+									mapMergeParticles[downprt->myPart.get()].push_back(upprt->myPart);
 								}
 								else
 								{
-									upprt->headerParticle = upprt.get();
-									downprt->headerParticle = upprt.get();
-									mapMergeParticles[upprt.get()].push_back(downprt);
+									upprt->headerParticle = upprt->myPart.get();
+									downprt->headerParticle = upprt->myPart.get();
+									mapMergeParticles[upprt->myPart.get()].push_back(downprt->myPart);
 								}
 
 							}
@@ -2130,14 +2448,16 @@ namespace OTSIMGPROC
 			auto downFld = FldMgr->FindNeighborField(allFields, centerfld,SORTING_DIRECTION::DOWN);
 			if (downFld != nullptr)
 			{
-				auto downParts = centerfld->GetBottomBorderedBigParticles();
-				auto upParts = downFld->GetTopBorderedBigParticles();
+				auto bottomParts = centerfld->GetBottomBorderedBigParticles();
+				auto topParts = downFld->GetTopBorderedBigParticles();
+				auto downParts = BorderPart::ConvertPartToBorderPart(bottomParts);
+				auto upParts= BorderPart::ConvertPartToBorderPart(topParts);
 
 				for (auto downprt : downParts)
 				{
 					for (auto upprt : upParts)
 					{
-						if (downprt->IsConnected(upprt.get(), centerfld->Width, centerfld->Height, (int)SORTING_DIRECTION::DOWN))
+						if (downprt->myPart->IsConnected(upprt->myPart.get(), centerfld->Width, centerfld->Height, (int)SORTING_DIRECTION::DOWN))
 						{
 
 							if (downprt->headerParticle != NULL)
@@ -2145,7 +2465,7 @@ namespace OTSIMGPROC
 								if (upprt->headerParticle == NULL)
 								{
 									upprt->headerParticle = downprt->headerParticle;
-									mapMergeParticles[downprt->headerParticle].push_back(upprt);
+									mapMergeParticles[downprt->headerParticle].push_back(upprt->myPart);
 								}
 
 							}
@@ -2154,13 +2474,13 @@ namespace OTSIMGPROC
 								if (upprt->headerParticle != NULL)
 								{
 									downprt->headerParticle = upprt->headerParticle;
-									mapMergeParticles[upprt->headerParticle].push_back(downprt);
+									mapMergeParticles[upprt->headerParticle].push_back(downprt->myPart);
 								}
 								else
 								{
-									downprt->headerParticle = downprt.get();
-									upprt->headerParticle = downprt.get();
-									mapMergeParticles[downprt.get()].push_back(upprt);
+									downprt->headerParticle = downprt->myPart.get();
+									upprt->headerParticle = downprt->myPart.get();
+									mapMergeParticles[downprt->myPart.get()].push_back(upprt->myPart);
 								}
 
 							}
@@ -2174,14 +2494,16 @@ namespace OTSIMGPROC
 			auto rightFld = FldMgr->FindNeighborField(allFields, centerfld, SORTING_DIRECTION::RIGHT);
 			if (rightFld != nullptr)
 			{
-				auto rightParts = centerfld->GetRightBorderedBigParticles();
-				auto leftParts = rightFld->GetLeftBorderedBigParticles();
+				auto rParts = centerfld->GetRightBorderedBigParticles();
+				auto lParts = rightFld->GetLeftBorderedBigParticles();
+				auto rightParts = BorderPart::ConvertPartToBorderPart(rParts);
+				auto leftParts = BorderPart::ConvertPartToBorderPart(lParts);
 
 				for (auto rightprt : rightParts)
 				{
 					for (auto leftprt : leftParts)
 					{
-						if (rightprt->IsConnected(leftprt.get(), centerfld->Width, centerfld->Height, (int)SORTING_DIRECTION::RIGHT))
+						if (rightprt->myPart->IsConnected(leftprt->myPart.get(), centerfld->Width, centerfld->Height, (int)SORTING_DIRECTION::RIGHT))
 						{
 
 							if (rightprt->headerParticle != NULL)
@@ -2189,7 +2511,7 @@ namespace OTSIMGPROC
 								if (leftprt->headerParticle == NULL)
 								{
 									leftprt->headerParticle = rightprt->headerParticle;
-									mapMergeParticles[rightprt->headerParticle].push_back(leftprt);
+									mapMergeParticles[rightprt->headerParticle].push_back(leftprt->myPart);
 								}
 
 							}
@@ -2198,13 +2520,13 @@ namespace OTSIMGPROC
 								if (leftprt->headerParticle != NULL)
 								{
 									rightprt->headerParticle = leftprt->headerParticle;
-									mapMergeParticles[leftprt->headerParticle].push_back(rightprt);
+									mapMergeParticles[leftprt->headerParticle].push_back(rightprt->myPart);
 								}
 								else
 								{
-									rightprt->headerParticle = rightprt.get();
-									leftprt->headerParticle = rightprt.get();
-									mapMergeParticles[rightprt.get()].push_back(leftprt);
+									rightprt->headerParticle = rightprt->myPart.get();
+									leftprt->headerParticle = rightprt->myPart.get();
+									mapMergeParticles[rightprt->myPart.get()].push_back(leftprt->myPart);
 								}
 
 							}
@@ -2329,7 +2651,7 @@ namespace OTSIMGPROC
 			CPosXrayPtr xray(new CPosXray());
 			xray->SetElementQuantifyData(newCheList);
 			newPart->SetXrayInfo(xray);
-			newPart->SetSubParticlesName(partsStr);
+			newPart->SetConnectedParticlesSequentialString(partsStr);
 			newPart->SetActualArea(allPartArea);
 			partTagId++;
 			newPart->SetParticleId(partTagId);

+ 6 - 3
OTSCPP/OTSImagePro/OTSImageProcess.h

@@ -6,7 +6,7 @@
 
 namespace OTSIMGPROC {
 	using namespace OTSDATA;
-	
+
 	class __declspec(dllexport) COTSImageProcess
 	{
 	public:
@@ -20,6 +20,7 @@ namespace OTSIMGPROC {
 		static BOOL RemoveBGByFindContour(CBSEImgPtr m_pBSEImg, COTSImageProcessParamPtr a_pImageProcessParam, COTSFieldDataPtr m_pFieldData);
 		static BOOL RemoveBGByCVconnectivities(CBSEImgPtr m_pBSEImg, COTSImageProcessParamPtr a_pImageProcessParam, double a_pixelSize, COTSFieldDataPtr m_pFieldData);
 		static BOOL GetParticlesBySpecialGrayRange(CBSEImgPtr m_pBSEImg, CIntRangePtr a_grayRange, CDoubleRangePtr a_diameterRange, double a_pixelSize, COTSFieldDataPtr m_pFieldData);
+	
 
 		static CIntRangePtr CalBackground(CBSEImgPtr m_pBSEImg);
 		static std::vector<CIntRangePtr> CalcuGrayLevelRange(CBSEImgPtr m_pBSEImg);
@@ -28,9 +29,11 @@ namespace OTSIMGPROC {
 		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, CDoubleRangePtr ecdRange, double a_PixelSize, CBSEImgPtr fieldImg);
+		static BOOL SplitRawParticleIntoWaterShedParticle(COTSParticlePtr part,  double a_PixelSize, CBSEImgPtr fieldImg);
+
 		static BOOL MergeBigBoundaryParticles(COTSFieldDataList allFields, double pixelSize, int scanFieldSize, CSize ResolutionSize, COTSParticleList& mergedParts);
 		
-	protected:
+	private:
 		static BOOL GetParticles(long left, long top, long a_nWidth, long a_nHeight, const BYTE* a_pPixel, COTSParticleList& a_listParticles);
 		static BOOL GetOneParticleFromROI(long left, long top, long a_nWidth, long a_nHeight, const BYTE* a_pPixel, COTSParticleList& a_listParticles);
 		static BOOL GetSegmentList(long left, long top, long a_nWidth, long a_nHeight, const BYTE* a_pPixel, COTSSegmentsList& a_listSegments);
@@ -38,7 +41,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);
+		
 		
 		
 	};

+ 25 - 16
OTSIncAMeasureApp/ServiceCenter/CImageHandler.cs

@@ -251,26 +251,34 @@ namespace OTSModelSharp.ServiceCenter
 
             foreach (var p in parts)
             {
-                OTSCLRINTERFACE.ImageProForClr imgpro = new OTSCLRINTERFACE.ImageProForClr();
-                imgpro.SplitRawParticleIntoGreyScaleParticle(p,new CDoubleRangeClr(ecdrange.GetStart(),ecdrange.GetEnd()),  a_pixelSize, a_pImgIn);
-                var subparts = p.GetSubParticles();
-                foreach (var subp in subparts)
+                //OTSCLRINTERFACE.ImageProForClr imgpro = new OTSCLRINTERFACE.ImageProForClr();
+                //imgpro.SplitRawParticleIntoGreyScaleParticle(p,new CDoubleRangeClr(ecdrange.GetStart(),ecdrange.GetEnd()),  a_pixelSize, a_pImgIn);
+                //var subparts = p.GetSubParticles();
+                //foreach (var subp in subparts)
+                //{
+                //    int bseValue = (new Random()).Next(10, 255);
+                //    foreach (var s in subp.GetFeature().GetSegmentsList())
+                //    {
+
+                //        for (int i = s.GetStart(); i < s.GetStart() + s.GetLength(); i++)
+                //        {
+
+                //            a_pImgOut.SetBSEValue(i, s.GetHeight(), bseValue);
+                //        }
+                //    }
+
+
+                //}
+                foreach (var s in p.GetFeature().GetSegmentsList())
                 {
-                    int bseValue = (new Random()).Next(10, 255);
-                    foreach (var s in subp.GetFeature().GetSegmentsList())
+                    for (int i = s.GetStart(); i < s.GetStart() + s.GetLength(); i++)
                     {
-                       
-                        for (int i = s.GetStart(); i < s.GetStart() + s.GetLength(); i++)
-                        {
-                          
-                            a_pImgOut.SetBSEValue(i, s.GetHeight(), bseValue);
-                        }
+                        var bseValue = a_pImgIn.GetBSEValue(i, s.GetHeight());
+                        a_pImgOut.SetBSEValue(i, s.GetHeight(), bseValue);
                     }
+                }
 
 
-                }
-                
-            
             }
            
           
@@ -340,7 +348,8 @@ namespace OTSModelSharp.ServiceCenter
             foreach (var p in parts)
             {
                 OTSCLRINTERFACE.ImageProForClr imgpro = new OTSCLRINTERFACE.ImageProForClr();
-                imgpro.SplitRawParticleIntoGreyScaleParticle(p,new CDoubleRangeClr(ecdrange.GetStart(),ecdrange.GetEnd()), a_pixelSize, a_pImgIn);
+                imgpro.SplitRawParticleIntoGreyScaleParticle(p, new CDoubleRangeClr(ecdrange.GetStart(), ecdrange.GetEnd()), a_pixelSize, a_pImgIn);
+                //imgpro.SplitRawParticleIntoWaterShedParticle(p, new CDoubleRangeClr(ecdrange.GetStart(), ecdrange.GetEnd()), a_pixelSize, a_pImgIn);
                 var subparts = p.GetSubParticles();
                 foreach (var subp in subparts)
                 {