试图理解仿射变换。

9
我正在使用OpenCV进行仿射变换,但我在理解其工作原理方面有些困难,尤其是如何指定映射矩阵的参数以获得特定的预期结果。为了提出问题,我首先定义一个变换矩阵,然后进行变换。在OpenCV中,这两个例程分别是(我使用Bradski&Kaehler的优秀书籍OpenCV中的示例):
cvGetAffineTransorm(srcTri, dstTri, warp_matrix);
cvWarpAffine(src, dst, warp_mat);

为了定义warp矩阵,需要定义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;

似乎源点和目标点之间唯一的区别是左下角的点向右移动了100像素。直觉上,我认为图像的底部应该向右移动100像素,但事实并非如此。
此外,如果我对dstTri [3]使用完全相同的值,就像我对srcTri [3]使用的那样,我会认为变换会产生完全相同的图像——但事实并非如此。
显然,我不理解这里发生了什么。那么,从srcTri []dstTri []的映射表示什么?
1个回答

17
这里是对仿射变换的数学解释:这是一个3x3的矩阵,它对2D向量施加以下变换:在X轴和Y轴上进行缩放、旋转、倾斜和平移。这些是6个变换,因此你的3x3矩阵有六个元素。底行始终为[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. Zy 对于 Y 轴也是同样的相对缩放比例。
  5. a 是图像旋转的角度。这很棘手,因为当你想旋转 'a' 时,你必须在矩阵中插入 sin() 和 cos() 在四个不同的地方。
  6. 'q' 是错切参数。它很少使用。它会导致您的图像侧倾(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

但是假设相机不移动,那么对角线元素应该为1。如果不是,那么透视投影会变得糟糕吗? - Abc
1
不好意思,您有点误解了。我已经准确地解释了每个参数的含义。即使相机没有移动,它仍然可以进行缩放、旋转等操作,这会影响对角线元素。此外,背景本身也可能会移动。如果背景静止而相机既不移动也不缩放,则通常不会进行任何变换(单位矩阵)。但是,场景中的物体(背景)可能会引入运动,即使相机静止。 - DanielHsH
但是,如果相机移动或场景中的物体发生变化,那么单应矩阵将受到影响,透视视图也会失真。不是吗? - Abc
假设这是投影矩阵。如何判断它是否正确? [1.037699338195111 0.012504316 6.247920532705828; -0.006003826 1.040320255 -1.055644865257303; 7.86E-06 1.22E-05 1] - Abc
请查看我的回答,链接在这里:https://dev59.com/12Up5IYBdhLWcg3w6qyq#14965352 - DanielHsH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接