如何在背景图像的特定位置插入前景对象?

How to insert in a specific position of the background image the foreground object?

我的目标是使用Python.[=15=将前景对象插入背景图像中的特定位置(例如,在中心部分、左下部分等) ]

获取前景(周围像素设置为零):

# Read the image
img = cv2.imread('/content/foreground.jpg')/255.0

foreground = img.copy()
foreground[foreground>=0.9]=0
plt.axis('off')
plt.imshow(foreground)
plt.show()

为此前景对象创建蒙版:

def getForegroundMask(foreground):
    mask_new = foreground.copy()[:,:,0]
    mask_new[mask_new>0] = 1
    return mask_new

mask_new = getForegroundMask(foreground)
plt.imshow(mask_new)
plt.axis('off')
plt.show()

获取背景:

background = cv2.imread('/content/background.png')/255.0

plt.imshow(background)
plt.axis('off')
plt.show()

将对象与背景合成:

def compose(foreground, mask, background):
    # resize background
    background = transform.resize(background, foreground.shape[:2])
    
    # Subtract the foreground area from the background
    background = background*(1 - mask.reshape(foreground.shape[0], foreground.shape[1], 1))
    
    # Finally, add the foreground
    composed_image = background + foreground
    
    return composed_image

结果,前景对象占据了背景图像的完整大小,但我想要的是自定义并将此对象插入不同的部分和不同的大小。我该怎么做?

为此,您可以使用切片。假设您想将前景放在背景的 (x, y) 坐标处。

h, w = foreground.shape[:2]

# Subtract the foreground area from the background
background[y:y+h, x:x+w] *= (1 - mask.reshape(foreground.shape[0], foreground.shape[1], 1))

background[y:y+h, x:x+w] += foreground

return background

这里,确保 y+hx+w 不超过背景尺寸。

直截了当少于 25 行。我们没有使用 matplotlib 库。

#!/usr/bin/python3.9.2
 
import cv2
import numpy as np

img1 = cv2.imread('ralph.jpg')
overlay_img1 = np.ones(img1.shape,np.uint8)*255

img2 = cv2.imread('mainlogo.png')
rows,cols,channels = img2.shape
overlay_img1[450:rows+450, 450:cols+450 ] = img2

img2gray = cv2.cvtColor(overlay_img1,cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(img2gray,220,55,cv2.THRESH_BINARY_INV)
mask_inv = cv2.bitwise_not(mask)
temp1 = cv2.bitwise_and(img1,img1,mask = mask_inv)
temp2 = cv2.bitwise_and(overlay_img1,overlay_img1, mask = mask)

result = cv2.add(temp1,temp2)
cv2.imshow("Result",result)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出叠加: