Python中如何将图像叠加到背景图的指定四边形坐标位置?
Hey there! Great question—since you're working with an arbitrary quadrilateral (not a parallelogram), the Affine transform won't cut it here. Affine transforms only preserve parallel lines and can only map 3 points to 3 points, which limits you to shapes like rectangles or sheared parallelograms. For a 4-point quadrilateral, you need a Perspective Transform (also called a Homography), which is exactly designed for warping images to fit any four-cornered shape.
Here's a step-by-step implementation using PIL and NumPy (plus OpenCV for easy homography calculation—don't worry, it's straightforward):
Step 1: Import Required Libraries
from PIL import Image import numpy as np # We'll use OpenCV to calculate the perspective transform matrix easily import cv2
Step 2: Load Your Images
# Replace with your actual image paths background_img = Image.open("background.jpg") foreground_img = Image.open("foreground.png")
Step 3: Define Your Coordinates
Use the quadrilateral coordinates you provided, and map them to the four corners of your foreground image:
# Target quadrilateral on the background (your coordinates) target_quad = np.array([ [37., 119.], # TOP LEFT [615., 65.], # TOP RIGHT [648., 416.], # BOTTOM RIGHT [70., 470.] # BOTTOM LEFT ], dtype=np.float32) # Source points: the four corners of your foreground image fg_width, fg_height = foreground_img.size source_points = np.array([ [0, 0], # TOP LEFT [fg_width, 0], # TOP RIGHT [fg_width, fg_height], # BOTTOM RIGHT [0, fg_height] # BOTTOM LEFT ], dtype=np.float32)
Step 4: Calculate the Perspective Transform & Warp the Foreground
# Compute the homography matrix (maps source points to target quadrilateral) homography_matrix, _ = cv2.findHomography(source_points, target_quad) # Convert the foreground image to a NumPy array for OpenCV processing foreground_np = np.array(foreground_img) # Warp the foreground to fit the target quadrilateral # The output size matches the background image dimensions warped_foreground_np = cv2.warpPerspective( foreground_np, homography_matrix, (background_img.width, background_img.height) ) # Convert the warped image back to a PIL Image warped_foreground = Image.fromarray(warped_foreground_np)
Step 5: Composite the Warped Image onto the Background
If your foreground has a transparent alpha channel, the paste method will respect it automatically when you pass the image as the mask:
# Paste the warped foreground onto the background background_img.paste(warped_foreground, (0, 0), warped_foreground) # Save or display the final result background_img.save("final_result.jpg") background_img.show()
Key Notes:
- Coordinate Order: Make sure your source and target points follow the same sequence (e.g., top-left → top-right → bottom-right → bottom-left). Mismatched order will cause distorted warping.
- No OpenCV?: If you don't want to use OpenCV, you can manually calculate the perspective transform matrix using linear algebra, but it's far more code-heavy. OpenCV's
findHomographyis the simplest way to get the correct matrix. - Transparency: If your foreground doesn't have an alpha channel, you might need to add one or create a custom mask to blend it smoothly with the background.
内容的提问来源于stack exchange,提问作者Morgan Roberts

