如何将这两张图片与 python numpy 和 opencv 合并?
how can I merge this two image with python numpy and opencv?
我有两个二进制图像。第一个是这样的:
最后一个是这样的:
它们的曲线大小不同。我想把第二个包含在黑色区域的两个白色区域添加到第一个的黑色区域。
我的代码是这样运行的,但这是一个错误的答案:
问题是这样的,我想得到我用 the final 图片:
我怎样才能完成这个任务?
假设 img1
是您的第一个数组(较大的实心斑点)而 img2
是第二个(带有孔的较小斑点),您需要一种方法来识别和删除第二个的外部区域图片。 flood fill algorithm is a good candidate. It is implemented in opencv as 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)
填充后的图片是这样的:
将生成的图像相加如下所示:
请记住,floodFill
就地运行,因此您可能需要在继续执行此操作之前复制 img2
。
我想你想要这个:
#!/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')
如果你更喜欢 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)
我有两个二进制图像。第一个是这样的:
最后一个是这样的:
它们的曲线大小不同。我想把第二个包含在黑色区域的两个白色区域添加到第一个的黑色区域。
我的代码是这样运行的,但这是一个错误的答案:
问题是这样的,我想得到我用 the final 图片:
我怎样才能完成这个任务?
假设 img1
是您的第一个数组(较大的实心斑点)而 img2
是第二个(带有孔的较小斑点),您需要一种方法来识别和删除第二个的外部区域图片。 flood fill algorithm is a good candidate. It is implemented in opencv as 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)
填充后的图片是这样的:
将生成的图像相加如下所示:
请记住,floodFill
就地运行,因此您可能需要在继续执行此操作之前复制 img2
。
我想你想要这个:
#!/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')
如果你更喜欢 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)