Если я правильно вас понимаю, вы хотите заменить белый ROI на черном изображении на исходное изображение. Вот простой подход:
Получение двоичного изображения. Загрузка изображения, оттенки серого, Размытие по Гауссу , затем Порог Оцу
Извлечь ROI и заменить. Найти контуры с помощью cv2.findContours
, затем отфильтровать с помощью аппроксимации контура с помощью cv2.arcLength
и cv2.approxPolyDP
. Предполагая, что область является прямоугольником, если результат аппроксимации контура равен 4
, то мы нашли желаемую область. Кроме того, мы фильтруем, используя cv2.contourArea
, чтобы гарантировать, что мы не включаем шум. Наконец, мы получаем координаты ограничивающего прямоугольника с помощью cv2.boundingRect
и извлекаем область интереса с помощью среза Numpy. Наконец, мы заменим ROI в исходное изображение.
Обнаруженная область для извлечения / замены выделена зеленым цветом
Извлеченный ROI
Результат
Код
import cv2
# Load images, grayscale, Gaussian blur, Otsu's threshold
original = cv2.imread('1.jpg')
image = cv2.imread('2.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# Find contours, filter using contour approximation + area, then extract
# ROI using Numpy slicing and replace into original image
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.015 * peri, True)
area = cv2.contourArea(c)
if len(approx) == 4 and area > 1000:
x,y,w,h = cv2.boundingRect(c)
ROI = image[y:y+h,x:x+w]
original[y:y+h, x:x+w] = ROI
cv2.imshow('thresh', thresh)
cv2.imshow('ROI', ROI)
cv2.imshow('original', original)
cv2.waitKey()