Вы можете использовать перспективное преобразование:
![output](https://i.stack.imgur.com/3YrpN.png)
Вам нужно будет изменить этот сценарий, чтобы он использовал ваши изображения вместо генерации однотонных изображений:
import cv2
import numpy as np
# Generate some images
images = []
w, h = 600,700
# Corners of images to be pasted onto background
pts2 = np.float32([[0,0],[w,0],[0,w],[w,w]])
for i in range(5):
img = np.zeros((w,w,3), np.uint8)
img[:,:,:] = i*42, 255, 255
img = cv2.cvtColor(img, cv2.COLOR_HSV2BGR)
images.append(img)
# Create a background
bg = np.zeros((w,h,3), np.uint8)
# Define where to paste the images
top, bottom, dx, width, middle, left_buffer = 100, 500, 100, 200, 300, 50
# Create a mask
mask = np.zeros((w,w), np.uint8)
mask[:] = 255
bg_zeros = np.zeros_like(bg)
# Paste the images onto the background
for i in range(5):
# Get the image
img = images[i]
# Compute where to paste the image
left = left_buffer+dx*i
right = left_buffer+dx*i + width
mid = int((left + right)/2)
pts1 = np.float32([[mid, top], [right, middle],
[left, middle], [mid, bottom]])
# Warp the image
M = cv2.getPerspectiveTransform(pts2,pts1)
dst = cv2.warpPerspective(img,M,(h,w))
# Warp the mask and mask out the background
cmask = cv2.warpPerspective(mask, M, (h,w))
bg = cv2.bitwise_and(bg,bg,mask = 255-cmask)
# Add the image to the background
bg += dst
cv2.imshow('bg', bg)
cv2.waitKey()
cv2.destroyAllWindows()