То, как я это делаю, пока работает хорошо, но я остаюсь открытым для любого другого лучшего решения!Вот мое:
def foreground_background_into1(background, foreground, with_smooth=True, thickness=3, mask=[]):
'''will add the foreground image to the background image to create a new image, with smooth intersection
-foreground image: this image must be either black where there is no mask, or the mask parameter must be specified in
the mask parameter
-background image: image on which we will add the mask
-mask: binary mask if foreground image does not already contain this information
Note: not tested with mask'''
#make a copy for the smooth part
img = foreground.copy()
#create binary mask (as needed to multiply with the backgound) from foreground image if not existing (replacing all value
#bigger than 0 to 1)
if len(mask)==0:
_,mask = cv2.threshold(foreground,1,1,cv2.THRESH_BINARY)
#verification
if foreground.shape!=background.shape:
raise Warning("the foreground is not of same shape as background, we will convert it")
foreground = imresize(foreground, size=background.shape)
#if mask has one channel add two others
if len(mask.shape)==2:
mask = skimage.color.gray2rgb(mask)
#add foreground to background
foreground = foreground.astype(float)
background = background.astype(float)
mask = mask.astype(float)
foreground = cv2.multiply(mask, foreground)
background = cv2.multiply(1 - mask, background) #is the initial background with black where the mask of forground
outImage = cv2.add(foreground, background)
result = outImage.astype(np.uint8)
if with_smooth:
#find contour
foreground_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(foreground_gray,1,255,0)
_, contours, __ = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#create intersection_mask
intersection_mask = cv2.drawContours(np.zeros(foreground.shape, np.uint8),
contours,-1,(0,255,0),thickness)
#inpaint the contour in the first final image
intersection_mask = cv2.cvtColor(intersection_mask, cv2.COLOR_BGR2GRAY)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1,1))
intersection_mask = cv2.dilate(intersection_mask, kernel, iterations=1)
result = cv2.inpaint(result,intersection_mask,1,cv2.INPAINT_TELEA)
return(result)
Я в основном добавляю маску к фоновому изображению, а затем сглаживаю часть пересечения, окрашивая с помощью openCV контур маски.