如何合并平移与旋转仿射矩阵,实现单次warpAffine操作?
Great question! Combining these two affine transformations into one is totally doable, and it’ll cut down on redundant computation by only running cv2.warpAffine once. Let’s walk through how to pull this off, with clear math context and code examples.
Quick Background: Affine Transforms in OpenCV
OpenCV uses 2x3 affine matrices for transformations, but these are shorthand for 3x3 homogeneous coordinate matrices. The extra row lets us handle translations (which can’t be represented with 2x2 matrices alone).
For any point (x, y), we represent it as a homogeneous vector (x, y, 1), then multiply by the 3x3 matrix to get the transformed point.
Step 1: Convert Your Existing Matrices to Homogeneous Form
First, we’ll expand your 2x3 translation and rotation matrices into full 3x3 matrices:
import numpy as np import cv2 # Your original parameters img = ... # Replace with your input image y_size, x_size = img.shape[:2] # Original translation matrix M_shift = np.float32([[1, 0, 20], [0, 1, 10]]) # Original rotation matrix center_of_rot = (500, 500) angle = 1.23 scale = 1.0 M_rot = cv2.getRotationMatrix2D(center_of_rot, angle, scale) # Convert to 3x3 homogeneous matrices M_shift_homo = np.vstack([M_shift, [0, 0, 1]]) M_rot_homo = np.vstack([M_rot, [0, 0, 1]])
Step 2: Multiply the Matrices (Order Is Critical!)
Since you’re applying translation first, then rotation, the combined transformation matrix is the product of the rotation matrix and the translation matrix (matrix multiplication order is reversed from the order of operations).
Here’s why: If P is your original point:
- Translate to get
P1 = M_shift(P) - Rotate to get
P2 = M_rot(P1) = M_rot(M_shift(P)) = (M_rot × M_shift)(P)
So we multiply the matrices like this:
# Compute combined homogeneous matrix M_combined_homo = M_rot_homo @ M_shift_homo # Convert back to OpenCV's 2x3 format M_combined = M_combined_homo[:2, :]
Step 3: Run a Single WarpAffine
Now use the combined matrix to perform your transformation in one step:
transformed = cv2.warpAffine(img, M_combined, (y_size, x_size), flags=cv2.INTER_LANCZOS4)
Double-Check the Result
To confirm this works, you can compare the transformed image to your original rotated image—they should be identical (minus tiny floating-point errors that won’t be visible to the eye).
内容的提问来源于stack exchange,提问作者Mihail

