|
|
|
@ -178,7 +178,7 @@ void CirclesGridClusterFinder::findGrid(const std::vector<cv::Point2f> &points, |
|
|
|
|
if(outsideCorners.size() != outsideCornersCount) |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
getSortedCorners(hull2f, corners, outsideCorners, sortedCorners); |
|
|
|
|
getSortedCorners(hull2f, patternPoints, corners, outsideCorners, sortedCorners); |
|
|
|
|
if(sortedCorners.size() != cornersCount) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
@ -295,7 +295,18 @@ void CirclesGridClusterFinder::findOutsideCorners(const std::vector<cv::Point2f> |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CirclesGridClusterFinder::getSortedCorners(const std::vector<cv::Point2f> &hull2f, const std::vector<cv::Point2f> &corners, const std::vector<cv::Point2f> &outsideCorners, std::vector<cv::Point2f> &sortedCorners) |
|
|
|
|
namespace { |
|
|
|
|
double pointLineDistance(const cv::Point2f &p, const cv::Vec4f &line) |
|
|
|
|
{ |
|
|
|
|
Vec3f pa( line[0], line[1], 1 ); |
|
|
|
|
Vec3f pb( line[2], line[3], 1 ); |
|
|
|
|
Vec3f l = pa.cross(pb); |
|
|
|
|
return std::abs((p.x * l[0] + p.y * l[1] + l[2])) * 1.0 / |
|
|
|
|
std::sqrt(double(l[0] * l[0] + l[1] * l[1])); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CirclesGridClusterFinder::getSortedCorners(const std::vector<cv::Point2f> &hull2f, const std::vector<cv::Point2f> &patternPoints, const std::vector<cv::Point2f> &corners, const std::vector<cv::Point2f> &outsideCorners, std::vector<cv::Point2f> &sortedCorners) |
|
|
|
|
{ |
|
|
|
|
Point2f firstCorner; |
|
|
|
|
if(isAsymmetricGrid) |
|
|
|
@ -341,10 +352,26 @@ void CirclesGridClusterFinder::getSortedCorners(const std::vector<cv::Point2f> & |
|
|
|
|
|
|
|
|
|
if(!isAsymmetricGrid) |
|
|
|
|
{ |
|
|
|
|
double dist1 = norm(sortedCorners[0] - sortedCorners[1]); |
|
|
|
|
double dist2 = norm(sortedCorners[1] - sortedCorners[2]); |
|
|
|
|
double dist01 = norm(sortedCorners[0] - sortedCorners[1]); |
|
|
|
|
double dist12 = norm(sortedCorners[1] - sortedCorners[2]); |
|
|
|
|
// Use half the average distance between circles on the shorter side as threshold for determining whether a point lies on an edge.
|
|
|
|
|
double thresh = min(dist01, dist12) / min(patternSize.width, patternSize.height) / 2; |
|
|
|
|
|
|
|
|
|
size_t circleCount01 = 0; |
|
|
|
|
size_t circleCount12 = 0; |
|
|
|
|
Vec4f line01( sortedCorners[0].x, sortedCorners[0].y, sortedCorners[1].x, sortedCorners[1].y ); |
|
|
|
|
Vec4f line12( sortedCorners[1].x, sortedCorners[1].y, sortedCorners[2].x, sortedCorners[2].y ); |
|
|
|
|
// Count the circles along both edges.
|
|
|
|
|
for (size_t i = 0; i < patternPoints.size(); i++) |
|
|
|
|
{ |
|
|
|
|
if (pointLineDistance(patternPoints[i], line01) < thresh) |
|
|
|
|
circleCount01++; |
|
|
|
|
if (pointLineDistance(patternPoints[i], line12) < thresh) |
|
|
|
|
circleCount12++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if((dist1 > dist2 && patternSize.height > patternSize.width) || (dist1 < dist2 && patternSize.height < patternSize.width)) |
|
|
|
|
// Ensure that the edge from sortedCorners[0] to sortedCorners[1] is the one with more circles (i.e. it is interpreted as the pattern's width).
|
|
|
|
|
if ((circleCount01 > circleCount12 && patternSize.height > patternSize.width) || (circleCount01 < circleCount12 && patternSize.height < patternSize.width)) |
|
|
|
|
{ |
|
|
|
|
for(size_t i=0; i<sortedCorners.size()-1; i++) |
|
|
|
|
{ |
|
|
|
|