仿射变换VS透视变换

时间:2024-03-15 16:18:11

序言

       在图像处理中,对图像进行二维变换有仿射变换(Affine Transformation),透视变换(Perspective Transformation)(应该还有其他变换,但是我用到的比较多的是这两种变换)。

一、仿射变换

1、概念

       仿射变换(Affine Transformation)是空间直角坐标系的变换,从一个二维坐标变换到另一个二维坐标,仿射变换是一个线性变换,他保持了图像的“平行性”和“平直性”,即图像中原来的直线和平行线,变换后仍然保持原来的直线和平行线,仿射变换比较常用的特殊变换有平移(Translation)、缩放(Scale)、翻转(Flip)、旋转(Rotation)和剪切(Shear)。

       仿射变换VS透视变换

图1.仿射变换

     2、仿射变换的变换公式推导

      

        在opencv提供的仿射变换中,变换的公式是一个2*3的矩阵,如下:

仿射变换VS透视变换仿射变换VS透视变换仿射变换VS透视变换

    A是仿射变换2*3矩阵,M是2*2矩阵,表示坐标轴的旋转和缩放,B是2*1矩阵,是坐标轴平移矩阵。

    坐标变换如下:

仿射变换VS透视变换仿射变换VS透视变换

    可以看出,A矩阵只有6个参数,所以只要知道3个点之间的仿射变换,就可以求出A矩阵。

   3、 仿射变换坐标系法推导

    仿射变换也可以看成坐标系的旋转和缩放以及平移:

仿射变换VS透视变换

        

        P点位置不变,坐标系由(Xt,Yt)变换到(Xs,Ys),相应的坐标有(Xtp,Ytp)变换成(Xsp,Ysp)。

其中(Xtp,Ytp)与(Xsp,Ysp)的关系如下:

        仿射变换VS透视变换


4、opencv仿射变换程序实现

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>

using namespace std;
using namespace cv;

void main()
{
 cv::Mat image = cv::imread("image.jpg");
 cv::namedWindow("source image");
 cv::imshow("source image",image);
 //3点的仿射变换
 cv::Point2f src_point[3];
 cv::Point2f dst_point[3];
 src_point[0] = cv::Point2f(0,0);
 src_point[1] = cv::Point2f(image.cols-1,0);
 src_point[2] = cv::Point2f(0,image.rows-1);

 dst_point[0] = cv::Point2f(image.cols*0.1,image.rows*0.13);
 dst_point[1] = cv::Point2f(image.cols*0.8,image.rows*0.32);
 dst_point[2] = cv::Point2f(image.cols*0.16,image.rows*0.7);

 cv::Mat warp_mat(cv::Size(2,3),CV_32F);
 warp_mat = cv::getAffineTransform(src_point,dst_point);
 cv::Mat warpimage= cv::Mat::zeros(image.rows,image.cols,image.type());
 cv::warpAffine(image,warpimage,warp_mat,warpimage.size());
 cv::namedWindow("dst image");
 cv::imshow("dst image",warpimage);
 cv::imwrite("warpimage1.jpg",warpimage);

 //对图像旋转后缩放的仿射变换
 cv::Point2f center = Point2f(image.cols/2,image.rows/2);
 double angle = 30;
 double scale = 0.8;
 warp_mat = getRotationMatrix2D(center,angle,scale);
 cv::warpAffine(image,warpimage,warp_mat,warpimage.size());

 cv::namedWindow("dst image2");
 cv::imshow("dst image2",warpimage);
 cv::imwrite("warpimage2.jpg",warpimage);
 cv::waitKey(0);
}

二、透视变换

 透视变换(Perspective Transformation)是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。

仿射变换VS透视变换

图2.透视变换

 

公式推导及应用详见http://blog.csdn.net/error/404.html?from=http%3a%2f%2fblog.csdn.net%2fu012380663%2farticle%2fdetails%2f43272851

三、二者的关系

从这两天的学习和应用中初步的总结下两者的异同吧

仿射变换:二维空间的变换 ; 线性变换 ;已知3对坐标点就可以求得变换矩阵

透视变换:三维空间的变换 ; 非线性变换 ;已知4对坐标点可以求得变换矩阵

 

上篇中w及w'的问题需要使用齐次坐标,即用三维向量(xy, w)表示二维向量,仿射变换中w从来不变,这样可以把它当作为1,但透视变换中通常齐次元素wc并不为1,所以为了映射回真实平面需要进行齐次除法,即每个元素都除以w

详见http://zh.wikipedia.org/wiki/%E5%8F%98%E6%8D%A2%E7%9F%A9%E9%98%B5

参考

http://zh.wikipedia.org/wiki/%E5%8F%98%E6%8D%A2%E7%9F%A9%E9%98%B5

http://blog.csdn.net/skeeee/article/details/23190797?utm_source=tuicool