Как я могу объединить эти два изображения с Python Numpy и OpenCV? - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть два двоичных изображения.Первый такой:

enter image description here

, а последний такой:

enter image description here

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

Мой код работает так, но это неправильный ответ:

enter image description here

Вопрос такой, и я хочу получить окончательное изображение, которое я рисую в изображении с final image:

enter image description here

Как мне решить эту задачу?

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Я думаю, что вы хотите это:

#!/usr/local/bin/python3

from PIL import Image,ImageDraw, ImageColor, ImageChops

# Load images
im1 = Image.open('im1.jpg')
im2 = Image.open('im2.jpg')

# Flood fill white edges of image 2 with black
seed  = (0, 0)
black = ImageColor.getrgb("black")
ImageDraw.floodfill(im2, seed, black, thresh=127)

# Now select lighter pixel of image1 and image2 at each pixel location and save it
result = ImageChops.lighter(im1, im2)
result.save('result.png')

enter image description here


Если вы предпочитаете OpenCV , это может выглядетькак это:

#!/usr/local/bin/python3

import cv2

# Load images
im1 = cv2.imread('im1.jpg', cv2.IMREAD_GRAYSCALE)
im2 = cv2.imread('im2.jpg', cv2.IMREAD_GRAYSCALE)

# Threshold, because JPEG is dodgy!
ret, im1 = cv2.threshold(im1, 127, 255, cv2.THRESH_BINARY)
ret, im2 = cv2.threshold(im2, 127, 255, cv2.THRESH_BINARY)

# Flood fill white edges of image 2 with black
h, w = im2.shape[:2]
mask = np.zeros((h+2, w+2), np.uint8)
cv2.floodFill(im2, mask, (0,0), 0)

# Now select lighter of image1 and image2 and save it
result = np.maximum(im1, im2)
cv2.imwrite('result.png', result)
0 голосов
/ 25 сентября 2018

Предполагая, что img1 - это ваш первый массив (крупный сплошной шарик), а img2 - второй (меньший шарик с дырками), вам нужен метод для определения и удаления внешней области второго изображения.Алгоритм заливки является хорошим кандидатом.Он реализован в opencv как cv2.floodFill.

Самое простое, что можно сделать, это заполнить внешний край, а затем просто сложить результаты вместе:

mask = np.zeros((img2.shape[0] + 2, img2.shape[1] + 2), dtype=np.uint8)
cv2.floodFill(img2, mask, (0, 0), 0, 0)
result = img1 + img2

Вот игрушечный пример, который показывает мини-изображения, топологически эквивалентные вашим оригиналам:

img1 = np.full((9, 9), 255, dtype=np.uint8)
img1[1:-1, 1:-1] = 0
img2 = np.full((9, 9), 255, dtype=np.uint8)
img2[2:-2, 2:-2] = 0
img2[3, 3] = img2[5, 5] = 255

Изображения выглядят так:

fig, (ax1, ax2) = plt.subplots(1, 2)
ax1.imshow(img1)
ax2.imshow(img2)

start

После заливки изображения выглядят следующим образом:

enter image description here

Добавление полученных изображений вместе выглядит следующим образом:

enter image description here

Имейте в виду, что floodFill работает на месте, поэтому вы можете сделать копию img2, прежде чем идти по этому пути.

...