我已经阅读了this个帖子,但是即使使用cv::threshold
创建了一个真正的binarry图像,我仍然得到了约500个轮廓。我在做什么错了?
cv::findContours
不会只返回13个轮廓,因为有13个清晰的斑点吗?
Mat img = imread("img.jpg", CV_LOAD_IMAGE_GRAYSCALE);
Mat img_thresh;
threshold(img, img_thresh, 0, 255, CV_THRESH_BINARY);
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
cv::findContours(img_thresh, contours, hierarchy, RetrievalModes::RETR_TREE, ContourApproximationModes::CHAIN_APPROX_SIMPLE);
RNG rng(12345);
Mat drawing = Mat::zeros(img_thresh.size(), CV_8UC3);
for (int i = 0; i< contours.size(); i++)
{
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
}
imshow("drawing", drawing);
waitKey();
UPDATE1
使用cv::RETR_EXTERNAL
代替cv::RETR_TREE
,但仍然返回比应有的轮廓更多的轮廓。
答案 0 :(得分:0)
如果检查二进制图像,您会发现有很多独立的轮廓:
因此,您首先需要通过腐蚀和扩张清理它们,如下所示:
您将得到以下结果:
比原始的清洁。
所有代码:
cv::namedWindow("result", cv::WINDOW_FREERATIO);
cv::Mat img = cv::imread(R"(rUYLL.png)");
// to gray
cv::Mat gray;
cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
cv::threshold(gray, gray, 0, 255, cv::THRESH_BINARY);
cv::erode(gray, gray, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)));
cv::dilate(gray, gray, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)));
std::vector<std::vector<cv::Point> > contours;
cv::findContours(gray, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
cv::drawContours(img, contours, -1, cv::Scalar(0, 255, 0), 2, 8);
cv::imshow("result", img);
cv::waitKey();
它是输出:
希望有帮助!
一种最简单的方法,也可以考虑是否适合您,只需将下限阈值从 0 增大到 80 并完成
cv::threshold(gray, gray, 80, 255, cv::THRESH_BINARY);
只需按阈值播放,然后查看结果。
只需更改阈值即可获得相同的输出: