0

我正在尝试使用 OpenCV 将背景(绿色区域和浅绿色毛巾)与对象分开,因此我手动分割了以下图像: 在此处输入图像描述

通过将对象边框以红色和蓝色着色,连接的组件不应被考虑,如您在图像的右下角看到的: 在此处输入图像描述

在对 254 通道 R 和 B 进行阈值处理后,我得到以下信息:

  1. 红色通道

通道红色

  1. 蓝色频道 蓝色频道

如果我使用完成红色通道的所有轮廓

findContours( bordersRed, contoursRedChannel, hierarchyRedChannel, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );
for (int index = 0; index < contoursRedChannel.size(); index ++)
    {
        drawContours( bordersRed, contoursRedChannel, index, colorForMask, CV_FILLED, 8, hierarchyRedChannel, 0, cv::Point() );
    }

右下角将是:

在此处输入图像描述

但我需要的是忽略只包含蓝点的轮廓,以便获得类似:

在此处输入图像描述

所以我必须将红色和蓝色通道结合起来才能得到它,但还不知道怎么做。任何意见,将不胜感激。

谢谢。

4

1 回答 1

1

您可以使用floodFill来做到这一点,假设您知道要填充的形状内的一个点。

结果从您的“通道红色”开始:

在此处输入图像描述

代码:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

int main()
{
    // Your image
    Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);

    // Assume you know a point inside the shape
    Point seed(930, 370); 

    // Apply floodfill
    floodFill(img, seed, Scalar(255));

    // Show image
    imshow("Result", img);
    waitKey();

    return 0;
}

更新

用 填充两个蒙版中的轮廓后drawContours(... CV_FILLED),您可以简单地对这两个蒙版进行异或运算

在此处输入图像描述

代码:

#include <opencv2\opencv.hpp>
#include <vector>
#include <algorithm>

using namespace std;
using namespace cv;

int main()
{
    // Load the two mask
    Mat1b channel_red_mask = imread("channel_red.png", IMREAD_GRAYSCALE);
    Mat1b channel_blue_mask = imread("channel_blue.png", IMREAD_GRAYSCALE);

    // Use just the bottom right part
    Rect roi(Point(800, 270), Point(channel_red_mask.cols, channel_red_mask.rows));
    channel_red_mask = channel_red_mask(roi).clone();
    channel_blue_mask = channel_blue_mask(roi).clone();


    // Fill all contours, in both masks
    {
        vector<vector<Point>> contours;
        findContours(channel_red_mask.clone(), contours, RETR_LIST, CHAIN_APPROX_SIMPLE);
        for (int i = 0; i < contours.size(); ++i)
        {
            drawContours(channel_red_mask, contours, i, Scalar(255), CV_FILLED);
        }
    }
    {
        vector<vector<Point>> contours;
        findContours(channel_blue_mask.clone(), contours, RETR_LIST, CHAIN_APPROX_SIMPLE);
        for (int i = 0; i < contours.size(); ++i)
        {
            drawContours(channel_blue_mask, contours, i, Scalar(255), CV_FILLED);
        }
    }

    // XOR the masks
    Mat1b xored = channel_red_mask ^ channel_blue_mask;

    imshow("XOR", xored);
    waitKey();

    return 0;
}
于 2015-11-19T16:06:59.947 回答