尝试理解仿射变换 (Chángshì lǐjiě fǎngshè biànhuàn)

2024-04-27 13:42:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我在OpenCV中使用仿射变换,很难直观地理解它的工作原理,更具体地说,就是如何指定映射矩阵的参数,以便得到特定的期望结果。

要设置这个问题,我使用的过程是首先定义一个扭曲矩阵,然后进行转换。

在OpenCV中,这两个例程是(我正在使用Bradski&Kaehler的优秀著作OpenCV中的一个示例):

cvGetAffineTransorm(srcTri, dstTri, warp_matrix);
cvWarpAffine(src, dst, warp_mat);

要定义扭曲矩阵,srcTridstTri定义为:

CvPoint2D32f srcTri[3], dstTri[3];

srcTri[3]填充如下:

srcTri[0].x = 0;
srcTri[0].y = 0;
srcTri[1].x = src->width - 1;
srcTri[1].y = 0;
srcTri[2].x = 0;
srcTri[2].y = src->height -1;

这基本上是图像的左上点、右上点和左下点作为矩阵的起点。这部分对我来说很有意义。

但是dstTri[3]的值很混乱,至少,当我改变一个点时,我没有得到我期望的结果。

例如,如果我对dstTri[3]使用以下命令:

dstTri[0].x = 0;
dstTri[0].y = 0;
dstTri[1].x = src->width - 1;
dstTri[1].y = 0;
dstTri[2].x = 0;
dstTri[2].y = 100;

src和dst点之间的唯一区别似乎是左下角点向右移动了100像素。直觉上,我觉得图像的底部应该向右移动100像素,但事实并非如此。

另外,如果我对dstTri[3]使用与对srcTri[3]使用完全相同的值,我会认为转换将生成完全相同的图像——但它不会。

显然,我不明白这里发生了什么。那么,从srcTri[]dstTri[]的映射代表什么呢?


Tags: 图像src参数定义过程矩阵像素width
1条回答
网友
1楼 · 发布于 2024-04-27 13:42:35

以下是仿射变换的数学解释: 这是一个大小为3x3的矩阵,它将愚弄的变换应用于二维向量:X轴上的缩放、缩放、旋转、倾斜、X轴上的平移和y轴上。 这是6个变换,因此在3x3矩阵中有6个元素。最下面一行总是[0 0 1]。 为什么?因为最下面一行表示x轴和y轴上的透视变换,而仿射变换不包括透视变换。 (如果要应用透视扭曲,请使用单应:也是3x3矩阵)

你在仿射矩阵中插入的6个值和它所做的6个变换之间的关系是什么?让我们看看这个3x3矩阵

e*Zx*cos(a), -q1*sin(a)  ,  dx,
e*q2*sin(a),     Z y*cos(a),  dy,
0       ,            0  ,   1
  1. dx和
  2. dy元素在x轴和y轴上平移(只需将图片左右、上下移动)。
  3. Zx是应用于X轴图像的相对比例(缩放)。
  4. y轴的Zy与上相同
  5. a是图像的旋转角度。这很棘手,因为当你想用“a”旋转时,你必须在矩阵的4个不同位置插入sin(),cos()。
  6. “q”是skew参数。很少使用。它会导致图像在侧面倾斜(q1导致y轴影响x轴,q2导致x轴影响y轴)
  7. 另外:“e”参数实际上不是一个转换。它可以有值1,-1。如果是1,则什么也不会发生,但如果是-1,则图像水平翻转。也可以使用它垂直翻转图像,但很少使用这种类型的转换。

非常重要的一点!!!!!

上面的解释是数学上的。它假设您将矩阵乘以右侧的列向量。据我所知,Matlab使用反向乘法(从左开始的行向量),所以您需要对这个矩阵进行转置。我很确定openCV使用的是正则乘法,但您需要检查它。 只需输入平移矩阵(x偏移10像素,y偏移1)。

1,0,10
0,1,1
0,0,1

如果你看到一个正常的移动比一切都好,但如果屎出现比转置矩阵:

1,0,0
0,1,0
10,1,1

相关问题 更多 >