Игнорировать подключенный компонент внутри другого

Я пытаюсь отделить фон (зеленое поле и светло-зеленое полотенце) от объектов, используя 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() );
}

нижний правый угол будет выглядеть так:

введите описание изображения здесь

Но мне нужно игнорировать контуры, которые содержат только синие точки, чтобы получить что-то вроде:

введите описание изображения здесь

поэтому я должен комбинировать красный с синими каналами, чтобы получить его, но пока не знаю как. Любой совет будет принят во внимание.

Благодарю.

0

Решение

Вы можете сделать это с помощью заливка, при условии, что вы знаете точку внутри фигуры, которую хотите заполнить.

Результат, начиная с вашего «Красного канала»:

введите описание изображения здесь

Код:

#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)можно просто XOR две маски:

введите описание изображения здесь

Код:

#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;
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]