通过内部颜色过滤OpenCV轮廓

问题描述 投票:0回答:1

我有一个问题,就是如何根据颜色过滤一些轮廓。我想删除所有黑色像素的等高线,只保留白色像素的等高线(见下图)。

创建等高线列表的代码。我使用了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);

然后,使用这些等高线,我已经建立了封闭的路径,并在屏幕上显示它们。

一个输入图像。

Input image

目前我的结果。

current result

我需要的是: 只填充等高线,其中有白色内容。

enter image description here

我试着将所有等高线放大到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;
}

如果您能提供任何想法或解决方案,我将非常感激,非常感谢您!

c++ objective-c opencv drawing contour
1个回答
1
投票

希望有一件事是清楚的,图像中的对象应该是白色的,而背景是黑色的,当你通过使用 THRESH_BINARY_INV.

所以我们基本上是想找到白线而不是黑线。我不提供代码,因为我在python中工作,但我将列出它可以如何完成。

  1. 创建一个与输入图像大小相同的黑色数组。让我们称它为 mask.
  2. 找到轮廓后,把它们画在 mask 与白色即255,同时提供了。thickness=-1. 这意味着我们基本上是在填充轮廓。
  3. 现在我们需要去除轮廓的边界,这样就只剩下轮廓内的部分了。这可以通过再次将轮廓画在 mask这次用厚度为1的黑色。
  4. 执行 bitwise_and 图像和蒙版之间。只有轮廓内有白色的区域才会被留下。

现在你只需要看看输出是否完全是黑色的。如果不是,那就意味着你不需要填充那个轮廓,因为它里面有东西。

编辑

哦,我不知道你的图像会有600个轮廓,是的,这将需要大量的时间,我不知道为什么我没有想到使用。hierarchy 前。

你可以使用 RETR_TREE 本身和层次结构值是 [next, previous, first_child, parent]. 所以我们只需要检查一下 first_child=-1那就意味着里面没有轮廓,你可以填充它。


0
投票

我已经把模式改为 RETR_CCOMP 并增加一个区域过滤,由 层次结构[轮廓指数][3] != -1 意思是,没有父母),我的问题就解决了。谢谢你

© www.soinside.com 2019 - 2024. All rights reserved.