Заливка OpenCV с маской - программирование
Подтвердить что ты не робот

Заливка OpenCV с маской

Документация для функции заливки OpenCV гласит:

Функция использует и обновляет маску, поэтому вы берете на себя ответственность за инициализация содержимого маски. Наполнение потоком не может пройти через ненулевое пикселей в маске. Например, можно использовать выход реберного детектора в качестве маски, чтобы остановить заполнение по краям. Можно использовать один и тот же маска в нескольких вызовах функции, чтобы убедиться, что заполненная область не перекрывается.

Как функция обновляет маску? Устанавливает ли все пиксели в потоке заливки какое-то ненулевое значение?

4b9b3361

Ответ 1

Все нулевые пиксели в том же подключенном компоненте, что и начальная точка маски, заменяются указанным вами значением. Это значение должно быть добавлено к параметру flags, сдвинутому влево на 8 бит:

uchar fillValue = 128;
cv::floodFill(img, mask, seed, cv::Scalar(255) ,0, cv::Scalar(), cv::Scalar(), 4 | cv::FLOODFILL_MASK_ONLY | (fillValue << 8));

Далее следует простой, но, возможно, просветительский пример. Создание изображения следующим образом:

//Create simple input image
cv::Point seed(4,4);
cv::Mat img = cv::Mat::zeros(100,100,CV_8UC1);
cv::circle(img, seed, 20, cv::Scalar(128),3);

Результаты на этом изображении:

Original image

Затем, создав маску и наполнив ее заполнением:

//Create a mask from edges in the original image
cv::Mat mask;
cv::Canny(img, mask, 100, 200);
cv::copyMakeBorder(mask, mask, 1, 1, 1, 1, cv::BORDER_REPLICATE);

//Fill mask with value 128
uchar fillValue = 128;
cv::floodFill(img, mask, seed, cv::Scalar(255) ,0, cv::Scalar(), cv::Scalar(), 4 | cv::FLOODFILL_MASK_ONLY | (fillValue << 8));

Дает этот результат:

Flood-filled mask

Белые пиксели в маске являются результатом обнаружения края, в то время как серые пиксели являются результатом заливки заливки.

UPDATE: В ответ на комментарий значение флага 4 указывает пиксельную окрестность, с помощью которой можно сравнить разницу значений цвета. Из документации:

Нижние биты содержат значение связи, 4 (по умолчанию) или 8, используемые в функции. Связь определяет, какие соседи пикселя считаются.

Когда флаг cv::FLOODFILL_MASK_ONLY не передается, и изображение и маска обновляются, но заполнение заливки останавливается при любых ненулевых значениях маски.

Ответ 2

И версия python

im = cv2.imread("seagull.jpg")
h,w,chn = im.shape
seed = (w/2,h/2)

mask = np.zeros((h+2,w+2),np.uint8)

floodflags = 4
floodflags |= cv2.FLOODFILL_MASK_ONLY
floodflags |= (255 << 8)

num,im,mask,rect = cv2.floodFill(im, mask, seed, (255,0,0), (10,)*3, (10,)*3, floodflags)

cv2.imwrite("seagull_flood.png", mask)

(Изображение из чайки из Викимедиа: https://commons.wikimedia.org/wiki/Commons:Quality_images#/media/File:Gull_portrait_ca_usa.jpg)

Результат: result