试图了解仿射变换 [英] trying to understand the Affine Transform

查看:71
本文介绍了试图了解仿射变换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用OpenCV中的仿射变换,无法直观了解它的工作原理,更具体地说,就是如何指定地图矩阵的参数,以便获得特定的期望结果. /p>

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

在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[]的映射代表什么呢?

解决方案

以下是仿射变换的数学解释: 这是一个尺寸为3x3的矩阵,将二维转换应用于以下转换:X轴上的比例,Y轴上的比例,旋转,倾斜,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"时,必须在矩阵的4个不同位置插入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

I am playing with the affine transform in OpenCV and I am having trouble getting an intuitive understanding of it workings, and more specifically, just how do I specify the parameters of the map matrix so I can get a specific desired result.

To setup the question, the procedure I am using is 1st to define a warp matrix, then do the transform.

In OpenCV the 2 routines are (I am using an example in the excellent book OpenCV by Bradski & Kaehler):

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

To define the warp matrix, srcTri and dstTri are defined as:

CvPoint2D32f srcTri[3], dstTri[3];

srcTri[3] is populated as follows:

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;

This is essentially the top left point, top right point, and bottom left point of the image for starting point of the matrix. This part makes sense to me.

But the values for dstTri[3] just are confusing, at least, when I vary a single point, I do not get the result I expect.

For example, if I then use the following for the 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;

It seems that the only difference between the src and the dst point is that the bottom left point is moved to the right by 100 pixels. Intuitively, I feel that the bottom part of the image should be shifted to the right by 100 pixels, but this is not so.

Also, if I use the exact same values for dstTri[3] that I use for srcTri[3], I would think that the transform would produce the exact same image--but it does not.

Clearly, I do not understand what is going on here. So, what does the mapping from the srcTri[] to the dstTri[] represent?

解决方案

Here is a mathematical explanation of affine transform: this is a matrix of size 3x3 that applies the foolowing transformations on 2D vector: Scale in X axis, scaleY, rotation, skew, translation in x axis and y. These are 6 transformations and thus you have six elements in your 3x3 matrix. The bottom row is always [0 0 1]. Why? because the bottom row represents the a perspective transformation in axis x and y, and affine transformation does not include perspective transform. (If you want to apply perspective warping use homography: also 3x3 matrix )

What is the relation between 6 values you insert into affine matrix and the 6 transformation it does? Let us look at this 3x3 matrix like

e*Zx*cos(a), -q1*sin(a)  ,  dx,
e*q2*sin(a),     Z y*cos(a),  dy,
0       ,            0  ,   1

  1. The dx and
  2. dy elements are translation in x and y axis (just move the picture left-right, up down).
  3. Zx is the relative scale(zoom) you apply to the image in X axis.
  4. Zy is the same as above for y axis
  5. a is the angle of rotation of the image. This is tricky since when you want to rotate by 'a' you have to insert sin(), cos() in 4 different places in the matrix.
  6. 'q' is the skew parameter. It is rarely used. It will cause your image to skew on the side (q1 causes y axis affects x axis and q2 causes x axis affect y axis)
  7. Bonus: 'e' parameter is actually not a transformation. It can have values 1,-1. If it is 1 than nothing happens, but if it is -1 than the image is flipped horizontally. You can use it also to flip the image vertically but, this type of transformation is rarely used.

Very important Note!!!!!

The above explanation is mathematical. It assumes you multiply the matrix by column vector from the right. As far as I remember, Matlab uses reverse multiplication (row vector from the left) so you will need to transpose this matrix. I am pretty sure that openCV uses regular multiplication but you need to check it. Just enter only translation matrix (x shifted by 10 pixels, y by 1).

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

If you see a normal shift than everything is OK, but If shit appears than transpose the matrix to:

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

这篇关于试图了解仿射变换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆