c++ - 为什么 cv::findContours 返回这么多轮廓?
问题描述
我读过这篇文章,但即使在使用cv::threshold
创建一个真正的二值图像之后,我仍然得到大约 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();
解决方案
如果你检查你的二值图像,你会看到有很多独立的轮廓:
所以你首先需要通过腐蚀和膨胀来清理它们,如下代码:
你会得到这个结果:
比原版更干净。
这是所有的代码:
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,然后 DONE
cv::threshold(gray, gray, 80, 255, cv::THRESH_BINARY);
只需使用 THRESHOLD并检查结果。
相同的输出只是改变阈值:
推荐阅读
- php - Paypal Payflow 透明重定向错误代码:PL001
- mongodb - 如何在开玩笑测试中正确关闭猫鼬连接
- testing - 集成测试,通配符忽略标签
- mongodb - 如何以公里为单位计算 LineString 距离?
- laravel-5 - 将 v-html 属性与 vue-i18n 标签中的标记结合起来
- c# - 从 .NET 控制器到 Java REST 服务的 HTTP POST 文件
- python - 如何在不使用 numpy 数组的情况下从 python 字典中访问“行”的元素
- multithreading - 如何在 Java 中进行异步线程执行?
- java - 手动调用 javax.swing.Timer 的 actionPerformed
- python-3.x - 使用 python 3.6 从 genfromtxt numpy date “TypeError: must be str, not bytes” 中从文件与 Internet 导入