opencv: Создание двоичной маски из изображения

#python #opencv #image-processing #cv2 #scikit-image

#python #opencv #image-processing #cv2 #scikit-image

Вопрос:

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

У меня есть эта картинка, и я хочу сделать из нее двоичную маску. Основной (самый большой) прямоугольник должен быть белым, а другие части изображения должны быть черными. Подобный этому:

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

Чтобы решить эту проблему, я хочу найти контур основного прямоугольника. Мой план состоит в том, чтобы найти все внешние контуры. Затем получите контур с наибольшей площадью. Во-первых, я попытался найти все контуры и отобразить их в виде двоичного изображения. Моя попытка:

 import numpy as np  import cv2 import matplotlib.pyplot as plt from skimage import data, io  im = cv2.imread('train_1.jpg', 0) contours, hierarchy = cv2.findContours(im.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) out = np.zeros_like(im) cv2.drawContours(out, contours, -1, 255, 10) io.imshow(out) plt.show()  

But even this simple code didn’t find any contours. What’s wrong with it? And how to get the contour with the highest area? Maybe I should apply Canny algorithm here? Please, help me.

Ответ №1:

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

 import cv2 import numpy as np  image = cv2.imread("jigsaw.jpg")  image = cv2.resize(image, (image.shape[1] // 4, image.shape[0] // 4)) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (5, 5), 0)  thresh = cv2.adaptiveThreshold(blur, 255, 1, 1, 11, 2)  contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  max_area = 0 best_cnt = None for counter in contours:  area = cv2.contourArea(counter)  if area gt; 1000:  if area gt; max_area:  max_area = area  best_cnt = counter  mask = np.zeros((gray.shape), np.uint8)  cv2.drawContours(mask, [best_cnt], 0, 255, -1) cv2.drawContours(mask, [best_cnt], 0, 0, 2)  cv2.imwrite('mask_jigsaw.jpg', mask)  cv2.imshow("Image Mask", mask) cv2.waitKey(0)  

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

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

Комментарии:

1. Спасибо! У меня есть вопрос. Почему вы сделали размытое изображение? Я удалил эту строку и получил то же изображение, что и вы.

2. Это дает вам более плавное изображение