c++ - 通过内部颜色过滤 OpenCV 轮廓
问题描述
我在按颜色过滤某些轮廓时遇到问题。我想删除所有内部有黑色像素的轮廓,只保留带有白色像素的轮廓(见下图)。
创建轮廓列表的代码。我使用了 RETR_TREE 轮廓检索模式和 CHAIN_APPROX_SIMPLE 点选择来避免轮廓内的很多点。
cv::cvtColor(src_img, gray_img, cv::COLOR_BGR2GRAY);
cv::threshold(gray_img, bin_img, minRGB, maxRGB, cv::THRESH_BINARY_INV);
std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(bin_img, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
然后,使用这些轮廓,我构建了封闭路径并将它们显示在屏幕上。
输入图像:
当前我的结果:
我需要的。仅填充具有白色内容的轮廓。
我尝试将所有轮廓缩放到内部 1 个像素,并检查所有像素是否都等于暗,但它并没有像我预期的那样工作。请参阅下面的代码。
double scaleX = (double(src_img.cols) - 2) / double(src_img.cols);
double scaleY = (double(src_img.rows) - 2) / double(src_img.rows);
for (int i = 0; i < contours.size(); i++) {
std::vector<cv::Point> contour = contours[i];
cv::Moments M = cv::moments(contour);
int cx = int(M.m10 / M.m00);
int cy = int(M.m01 / M.m00);
std::vector<cv::Point> scaledContour(contour.size());
for (int j = 0; j < contour.size(); j++) {
cv::Point point = contour[j];
point = cv::Point(point.x - cx, point.y - cy);
point = cv::Point(point.x * scaleX, point.y * scaleY);
point = cv::Point(point.x + cx, point.y + cy);
scaledContour[j] = point;
}
contours[i] = scaledContour;
}
如果您有任何想法或解决方案,我将非常感激,非常感谢!
解决方案
希望有一点很清楚,当您使用THRESH_BINARY_INV
.
所以我们本质上是在寻找白线而不是黑线。当我在 python 中工作时,我没有提供代码,但我会列出它是如何完成的。
- 创建一个输入图像大小的黑色数组。让我们称之为
mask
。 - 找到轮廓后,用白色即 255 绘制它们
mask
,同时提供thickness=-1
. 这意味着我们基本上是在填充轮廓。 - 现在我们需要删除轮廓的边界,所以剩下的唯一部分是轮廓内的部分。这可以通过再次在 上绘制轮廓来实现
mask
,这次使用厚度为 1 的黑色。 bitwise_and
在图像和蒙版之间执行。只有轮廓内有白色的区域会被留下。
现在你只需要看看输出是否完全是黑色的。如果不是,则意味着您不需要填充该轮廓,因为它里面包含一些东西。
编辑
哦,我没有意识到你的图像会有 600 个轮廓,是的,这需要很多时间,我不知道为什么我以前没有想过使用hierarchy
。
您可以使用RETR_TREE
自身,层次结构值为[next, previous, first_child, parent]
. 所以我们只需要检查 的值first_child=-1
,这意味着里面没有轮廓,你可以填充它。
推荐阅读
- java - 多模块项目中的 Spring Scheduled Services
- javascript - 反应,使状态适用于循环中的单个元素
- javascript - 如何制作自定义验证错误消息?
- c# - 如果您在同一文件夹中有多个项目或多个 .cs 文件,如何编译 dotnet 项目
- ubuntu - 在 Jetson TX2 上构建 TensorFlow
- api - PHP函数sell()的Binance api不起作用
- php - 使用 excel 从数据库从 col 2 开始插入数据库
- mysql - MYSQL 如果表退出运行某事,否则运行另一件事
- javascript - 如何使用打字稿提高反应项目的性能
- javascript - 在 vue-chart.js 中使用循环渲染标签和数据