我有两张图像和一个掩码,所有的尺寸都一样,都是Numpy数组。
我想把它们合并成这样的输出。
def merge(lena, rocket, mask):
'''Mask init and cropping'''
mask = np.zeros(lena.shape[:2], dtype='uint8')
cv2.fillConvexPoly(mask, circle, 255) # might be polygon
'''Bitwise operations'''
lena = cv2.bitwise_or(lena, lena, mask=mask)
mask_inv = cv2.bitwise_not(mask) # mask inverting
rocket = cv2.bitwise_or(rocket, rocket, mask=mask_inv)
output = cv2.bitwise_or(rocket, lena)
return output
这段代码给了我这样的结果。
应用 cv2.GaussianBlur(mask, (51,51), 0)
以不同的方式扭曲叠加图像的颜色。其他的SO问题也涉及到类似的问题,但并没有完全解决这种类型的模糊合成。
mask = np.zeros(lena.shape[:2], dtype='uint8')
mask = cv2.GaussianBlur(mask, (51,51), 0)
mask = mask[..., np.newaxis]
cv2.fillConvexPoly(mask, circle, 1)
output = mask * lena + (1 - mask) * rocket
mask = np.zeros(generated.shape[:2])
polygon = np.array(polygon, np.int32) # 2d array of x,y coords
cv2.fillConvexPoly(mask, polygon, 1)
mask = cv2.GaussianBlur(mask, (51, 51), 0)
mask = mask.astype('float32')
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
foreground = cv2.multiply(lena, mask, dtype=cv2.CV_8U)
background = cv2.multiply(rocket, (1 - mask), dtype=cv2.CV_8U)
output = cv2.add(foreground, background)
请教如何模糊蒙版,正确的与前景合并,然后叠加在背景图上?
这里是如何在PythonOpenCV中做到这一点。你的第二个方法很接近。
输入图像。
import cv2
import numpy as np
# Read images
image1 = cv2.imread('lena_wide.jpg')
image2 = cv2.imread('rocket.jpg')
circle = cv2.imread('white_circle.jpg', cv2.IMREAD_GRAYSCALE)
# linear blur mask
mask = cv2.blur(circle, (30,30))
# alternate using Gaussian blur
#mask = cv2.GaussianBlur(circle, (0,0), sigmaX=10, sigmaY=10)
# stretch mask to full dynamic range
mask = cv2.normalize(mask, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
# convert mask to float in range 0 to 1
maskf = (mask/255).astype(np.float64)
maskf = cv2.merge([maskf,maskf,maskf])
# apply mask to image1 and inverted mask to image2
result = maskf*image1 + (1-maskf)*image2
result = result.clip(0,255).astype(np.uint8)
# save results
cv2.imwrite('white_circle_ramped.jpg', mask)
cv2.imwrite('lena_wide_rocked_composited.png', result)
# show results
cv2.imshow("mask", mask)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
斜面遮罩图像。
结果:
ADDITION:
这是一个主要使用Numpy的另一种方法。
import cv2
import numpy as np
# Read images
image1 = cv2.imread('lena_wide.jpg')
image2 = cv2.imread('rocket.jpg')
circle = cv2.imread('white_circle2.jpg', cv2.IMREAD_GRAYSCALE)
# linear blur mask
mask = cv2.blur(circle, (30,30))
# alternate using Gaussian blur
#mask = cv2.GaussianBlur(circle, (0,0), sigmaX=10, sigmaY=10)
# stretch mask to full dynamic range
mask = cv2.normalize(mask, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
# convert mask to 3 channels
mask = cv2.merge([mask,mask,mask])
# apply mask to image1 and inverted mask to image2
image1_masked = np.multiply(image1, mask/255).clip(0,255).astype(np.uint8)
image2_masked = np.multiply(image2, 1-mask/255).clip(0,255).astype(np.uint8)
# add the two masked images together
result = np.add(image1_masked, image2_masked)
# save results
cv2.imwrite('white_circle_ramped2.jpg', mask)
cv2.imwrite('lena_wide_rocked_composited2.png', result)
# show results
cv2.imshow("mask", mask)
cv2.imshow("image1_masked", image1_masked)
cv2.imshow("image2_masked", image2_masked)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
你需要在混合前对蒙版进行重新归一化。
def blend_merge(lena, rocket, mask):
mask = cv2.GaussianBlur(mask, (51, 51), 0)
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
mask = mask.astype('float32') / 255
foreground = cv2.multiply(lena, mask, dtype=cv2.CV_8U)
background = cv2.multiply(rocket, (1 - mask), dtype=cv2.CV_8U)
output = cv2.add(foreground, background)
return output
一个完整的例子是 此处.