如何生成归一化图像旋转矩阵并复用至不同图像?
问题分析
你直接用归一化中心(0.4, 0.7)调用cv2.getRotationMatrix2D生成的矩阵是错误的——这个函数的center参数要求是像素坐标,而非归一化比例。此时OpenCV会把(0.4, 0.7)当成图像上的像素点位置,生成的是围绕这个极小像素点的旋转矩阵,并非你需要的“归一化变换矩阵”。
要实现“存储独立于图像尺寸的变换信息,再适配到具体图像”的需求,有两种可行方式:
方案一:存储变换参数(推荐)
直接存储归一化的变换参数(中心比例、角度、缩放),而非矩阵。当拿到具体图像时,用参数生成适配尺寸的矩阵,这是最简洁且不易出错的方式。
示例代码:
import cv2 # 存储归一化的变换参数(独立于图像尺寸) norm_center = (0.4, 0.7) angle = 39 scale = 1.0 # 拿到具体图像时,生成适配的矩阵 image = cv2.imread(filepath) h, w = image.shape[:2] pixel_center = (norm_center[0] * w, norm_center[1] * h) matrix = cv2.getRotationMatrix2D(pixel_center, angle, scale) # 应用变换 image2 = cv2.warpAffine(image, matrix, dsize=(w, h)) cv2.imwrite("/home/ken/rotated_new.jpg", image2)
方案二:存储归一化矩阵并转换
如果你一定要存储矩阵,需要先基于**归一化坐标系(假设图像尺寸为1x1)**生成正确的变换矩阵,再通过坐标系转换得到适配实际图像的矩阵。
实现denormalize_matrix函数:
import cv2 import numpy as np def denormalize_matrix(norm_matrix, image_shape): h, w = image_shape[:2] # 将2x3的仿射矩阵扩展为3x3的齐次矩阵 norm_homo = np.vstack([norm_matrix, [0, 0, 1]]) # 构造坐标系转换的齐次矩阵:像素→归一化→变换→像素 T_scale_in = np.array([[1/w, 0, 0], [0, 1/h, 0], [0, 0, 1]]) T_scale_out = np.array([[w, 0, 0], [0, h, 0], [0, 0, 1]]) # 计算最终的像素坐标系变换矩阵 pixel_homo = T_scale_out @ norm_homo @ T_scale_in # 转回2x3的仿射矩阵 return pixel_homo[:2, :] # 生成并存储归一化矩阵(基于1x1图像) norm_center = (0.4, 0.7) angle = 39 norm_matrix = cv2.getRotationMatrix2D(norm_center, angle, 1.0) # 拿到具体图像时转换矩阵 image = cv2.imread(filepath) matrix = denormalize_matrix(norm_matrix, image.shape) # 应用变换 image2 = cv2.warpAffine(image, matrix, dsize=(image.shape[1], image.shape[0])) cv2.imwrite("/home/ken/rotated_new.jpg", image2)
注意:
这种方式对于非正方形图像,旋转后的图像会出现拉伸(因为归一化坐标系是1x1正方形,实际图像是长方形,相当于先把图像缩放到正方形旋转再拉伸回去)。如果需要无拉伸的旋转效果(和直接用像素中心生成的矩阵一致),方案一更合适。
内容的提问来源于stack exchange,提问作者crowmagnumb
相关产品推荐
相关产品推荐

