如何合并OpenCV estimateAffinePartial2D得到的多个仿射变换矩阵?
合并OpenCV estimateAffinePartial2D得到的仿射变换矩阵
问题核心
你的问题出在错误使用元素相乘(np.multiply),仿射变换矩阵的合并必须用矩阵乘法,且补全3x3矩阵的方式也不对。
正确的矩阵补全与合并步骤
estimateAffinePartial2D返回的2x3仿射矩阵是齐次坐标下3x3矩阵的前两行,正确补全方式是添加[0, 0, 1]作为第三行,而非全1行,这样才能准确表示仿射变换的齐次形式。
合并逻辑
若有变换矩阵m1(frame0→frame1)、m2(frame1→frame2),则frame0→frame2的变换矩阵为m2 * m1(注意顺序:后续变换在前,先执行的变换在后)。
代码示例
import numpy as np from math import cos, sin, pi # 将2x3仿射矩阵转换为3x3齐次矩阵 def affine_2x3_to_3x3(affine_mat): return np.vstack([affine_mat, [0, 0, 1]]) # 构造测试用2x3变换矩阵 m1 = np.array([[cos(pi/4), -sin(pi/4), 100], [sin(pi/4), cos(pi/4), 100]]) m2 = np.array([[cos(pi/2), -sin(pi/2), 50], [sin(pi/2), cos(pi/2), 50]]) # 转换为3x3齐次矩阵 m1_3x3 = affine_2x3_to_3x3(m1) m2_3x3 = affine_2x3_to_3x3(m2) # 矩阵乘法合并变换(顺序:m2在前,对应先执行m1再执行m2) combined_3x3 = np.matmul(m2_3x3, m1_3x3) # 转换回2x3格式(适配OpenCV多数函数的输入要求) combined_2x3 = combined_3x3[:2, :] print("合并后的2x3变换矩阵:") print(combined_2x3)
错误原因解析
- 补全矩阵错误:你添加的
[1,1,1]不符合齐次仿射矩阵的规则,第三行必须是[0,0,1]才能保证平移、旋转、缩放的变换逻辑正确。 - 误用元素相乘:
np.multiply是逐元素相乘,而仿射变换的复合是线性变换的叠加,必须用矩阵乘法(np.matmul或@运算符)才能得到正确结果。
Android OpenCV实现提示
在Android中可通过Core.gemm()函数完成矩阵乘法:
- 先将每个2x3的
Mat补全为3x3Mat,第三行设为0,0,1 - 依次调用
Core.gemm()执行矩阵乘法,注意变换顺序 - 最终取结果的前两行作为合并后的2x3变换矩阵
内容的提问来源于stack exchange,提问作者cliffroot
相关产品推荐
相关产品推荐

