|
@@ -161,9 +161,7 @@ namespace OTSIMGPROC
|
|
|
}
|
|
|
void GetMatricsParticlesFromRawParticle(COTSParticlePtr a_pOTSPart,int imageWidth,int imageHeight, double a_PixelSize, int xrayStep, COTSParticleList& matricsParts)
|
|
|
{
|
|
|
- const int nThickness = 1;
|
|
|
- // lineType Type of the line
|
|
|
- const int nLineType = 8;
|
|
|
+
|
|
|
auto originalSegs = a_pOTSPart->GetFeature()->GetSegmentsList();
|
|
|
std::map<int, COTSSegmentsList> segsOnTheSameHeight;
|
|
|
for (auto s : originalSegs)
|
|
@@ -171,72 +169,25 @@ namespace OTSIMGPROC
|
|
|
segsOnTheSameHeight[s->GetHeight()].push_back(s);
|
|
|
}
|
|
|
auto rect = a_pOTSPart->GetParticleRect();
|
|
|
- // calculate the particle image data size, expand 3 pixel at the edge
|
|
|
- Mat particleImage = Mat::zeros(imageHeight, imageWidth, CV_8U);
|
|
|
- // get the segment list
|
|
|
- COTSSegmentsList listSegment = a_pOTSPart->GetFeature()->GetSegmentsList();
|
|
|
- for (auto pSegment : listSegment)
|
|
|
- {
|
|
|
- int nStart = pSegment->GetStart() ;
|
|
|
- int nEnd = pSegment->GetStart() + pSegment->GetLength() ;
|
|
|
- int nHeight = pSegment->GetHeight() ;
|
|
|
- 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 ;
|
|
|
- }
|
|
|
- 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];
|
|
|
+
|
|
|
|
|
|
std::vector<CPoint> matrixPs;
|
|
|
|
|
|
CPoint theFirst = CPoint(rect.left + xrayStep / 2, rect.top + xrayStep / 2);
|
|
|
|
|
|
- int colnum = (double)rect.Width() / xrayStep + 0.5;
|
|
|
- int rownum = (double)rect.Height() / xrayStep + 0.5;
|
|
|
+ int colnum = ceil((double)rect.Width() / xrayStep + 0.5);
|
|
|
+ int rownum = ceil((double)rect.Height() / xrayStep + 0.5);
|
|
|
for (int i = 0; i < rownum; i++)
|
|
|
{
|
|
|
for (int j = 0; j < colnum; j++)
|
|
|
{
|
|
|
- double x = theFirst.x + j * xrayStep;
|
|
|
- double y = theFirst.y + i * xrayStep;
|
|
|
+ double x =(double) theFirst.x + (double)j * xrayStep;
|
|
|
+ double y = (double)theFirst.y + (double)i * xrayStep;
|
|
|
CPoint thePoint = CPoint(x, y);
|
|
|
Point cvP = Point(x, y);
|
|
|
- if (pointPolygonTest(listEdge, cvP, false) == 1)
|
|
|
- {
|
|
|
- matrixPs.push_back(thePoint);
|
|
|
- }
|
|
|
+
|
|
|
+ matrixPs.push_back(thePoint);
|
|
|
+
|
|
|
|
|
|
}
|
|
|
}
|
|
@@ -255,11 +206,13 @@ namespace OTSIMGPROC
|
|
|
seg->SetHeight(point.y - xrayStep / 2 + i);
|
|
|
|
|
|
auto originalSegs = segsOnTheSameHeight[seg->GetHeight()];
|
|
|
-
|
|
|
- for (auto rseg : originalSegs)//judge if the seg is in the original particle scope.
|
|
|
+ int currentH = seg->GetHeight();
|
|
|
+ int segStart = seg->GetStart();
|
|
|
+ int segEnd = seg->GetEnd();
|
|
|
+ for (int i = 0; i < originalSegs.size();i++)//judge if the seg is in the original particle scope.
|
|
|
{
|
|
|
- int segStart = seg->GetStart();
|
|
|
- int segEnd = seg->GetEnd();
|
|
|
+ auto rseg = originalSegs[i];
|
|
|
+
|
|
|
int rsegStart = rseg->GetStart();
|
|
|
int rsegEnd = rseg->GetEnd();
|
|
|
|
|
@@ -275,26 +228,34 @@ namespace OTSIMGPROC
|
|
|
}
|
|
|
else if (segStart>= rsegStart&& segEnd >= rsegEnd)// intersect in the head end.Modify the end of the seg .
|
|
|
{
|
|
|
-
|
|
|
- seg->SetEnd(rsegEnd);
|
|
|
- segs.push_back(seg);
|
|
|
- break;
|
|
|
+ COTSSegmentPtr newseg = COTSSegmentPtr(new COTSSegment());
|
|
|
+ newseg->SetStart(segStart);
|
|
|
+ newseg->SetEnd(rsegEnd);
|
|
|
+ newseg->SetHeight(currentH);
|
|
|
+ segs.push_back(newseg);
|
|
|
+
|
|
|
+ continue;
|
|
|
}
|
|
|
else if (segStart<= rsegStart&& segEnd >= rsegEnd)
|
|
|
{
|
|
|
- seg->SetStart(rsegStart);
|
|
|
-
|
|
|
- seg->SetEnd(rsegEnd);
|
|
|
- segs.push_back(seg);
|
|
|
- break;
|
|
|
+ COTSSegmentPtr newseg = COTSSegmentPtr(new COTSSegment());
|
|
|
+ newseg->SetStart(rsegStart);
|
|
|
+ newseg->SetEnd(rsegEnd);
|
|
|
+ newseg->SetHeight(currentH);
|
|
|
+
|
|
|
+ segs.push_back(newseg);
|
|
|
+ continue;
|
|
|
|
|
|
}
|
|
|
else if (segStart<= rsegStart&& rsegEnd >= segEnd)
|
|
|
{
|
|
|
- seg->SetStart(rsegStart);
|
|
|
- seg->SetEnd(segEnd);
|
|
|
- segs.push_back(seg);
|
|
|
- break;
|
|
|
+ COTSSegmentPtr newseg = COTSSegmentPtr(new COTSSegment());
|
|
|
+ newseg->SetStart(rsegStart);
|
|
|
+ newseg->SetEnd(segEnd);
|
|
|
+ newseg->SetHeight(currentH);
|
|
|
+
|
|
|
+ segs.push_back(newseg);
|
|
|
+ continue;
|
|
|
}
|
|
|
|
|
|
}
|