我想,你唯一的问题是不尊重坐标之一的平等!?
开始了:
// Custom sorter.
bool sortContour(std::vector<cv::Point> a, std::vector<cv::Point> b)
{
cv::Rect rectA = cv::boundingRect(a);
cv::Rect rectB = cv::boundingRect(b);
if (rectA.y == rectB.y)
return (rectA.x < rectB.x);
return (rectA.y < rectB.y);
}
int main()
{
// Load image.
cv::Mat image = cv::imread("contours.jpg", cv::IMREAD_GRAYSCALE);
// There are some artifacts in the JPG...
cv::threshold(image, image, 128, 255, cv::THRESH_BINARY);
// Find contours.
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(image, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
// Output unsorted contours.
cv::Mat imageUnsorted = image.clone();
for (int i = 0; i < contours.size(); i++)
{
cv::Rect rect = cv::boundingRect(contours[i]);
cv::putText(imageUnsorted, std::to_string(i), cv::Point(rect.x - 10, rect.y - 10), cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(255));
}
cv::imwrite("unsorted.png", imageUnsorted);
// Sort using custom sorter.
std::sort(contours.begin(), contours.end(), sortContour);
// Output sorted contours.
cv::Mat imageSorted = image.clone();
for (int i = 0; i < contours.size(); i++)
{
cv::Rect rect = cv::boundingRect(contours[i]);
cv::putText(imageSorted, std::to_string(i), cv::Point(rect.x - 10, rect.y - 10), cv::FONT_HERSHEY_COMPLEX, 0.5, cv::Scalar(255));
}
cv::imwrite("sorted.png", imageSorted);
}
未排序的轮廓:
排序后的轮廓:
正如你所看到的,人们也可以颠倒原来的顺序,因为cv::findContours
只是朝相反的方向前进。 ;-)
一个重要的警告:如果扫描(或者您获取调查的方式)哪怕稍微逆时针旋转,此例程都会失败。因此,应事先检查整个扫描(或...)的角度。