【OpenCV】-仿射变换

1、认识仿射变换

仿射变换(Affine Map)又称仿射映射,是指在几何中,一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间的过程。保持二维图形之间的相对位置保持不变,平行线依然是平行线,且直线上的点的位置顺序不变。

一个任意的仿射变换都可以表示为乘以一个矩阵接着再加上一个向量的形式。三种常见的变换形式:

  • 旋转:ratation(线性变换)
  • 平移:translation(向量加)
  • 缩放:scale(线性变换)

通常使用2 x 3的矩阵来表示仿射变换:

【OpenCV】-仿射变换

【OpenCV】-仿射变换

; 2、仿射变换的求法

说明:仿射变换表示的就是两幅图片之间的一种联系,关于这种联系的信息大致可以分为以下两种场景:

  • 已知X和T,而且已知它们是有联系的,接下来的跟着就是求出矩阵M。
  • 已知M和X,想要求得T。只要应用算式T=M*X即可。

【OpenCV】-仿射变换

如上,点1、2、3(在Image 1中形成一个三角形)与Image 2中的三个点是一一映射的关系,且它们仍然形成三角形,但形状已经和之前的不一样的,可以通过这样的两组三点求出仿射变换,然后把这种变换应用到图像中去。

3、进行仿射变换:warpAffine()函数

warpAffine()函数的作用依据下面的公式对图像做仿射变换:
d s t ( x , y ) = s r c ( M 11 X + M 12 Y + M 13 , M 21 X + M 22 Y + M 23 ) dst(x,y)=src(M11X+M12Y+M13,M21X+M22Y+M23)d s t (x ,y )=src (M 11 X +M 12 Y +M 13 ,M 21 X +M 22 Y +M 23 )

void warpAffine(InputArray src,OutputArray dst,InputArray M,Size dsize,int flags=INTER_LINEAR,intborderMOde=BODER_CONSTANT,const Scalar& borderValue=Scalar())
  • 第一个参数:输入图像
  • 第二个参数:输出图像,函数调用后的运算结果存在这里,需要和源图片有一样的尺寸和类型
  • 第三个参数:2 x 3的变换矩阵,求得的仿射变换
  • 第四个参数:表示输出图像的尺寸
    【OpenCV】-仿射变换
  • 第六个参数:边界像素模式
  • 第七个参数:在恒定的边界情况下取值,默认值Scalar(),即0

4、计算二维旋转变换矩阵:getRotationMatrix2D()函数

说明:getRotationMatrix2D()函数用于计算二维旋转变换矩阵。变换会将旋转中心映射到它自身

Mat getRotationMatrix2D(Point2f center,double angle,double scale)
  • 第一个参数:表示源图像的旋转中心
  • 第二个参数:旋转角度。角度为正值表示向逆时针旋转(坐标原点是左上角)
  • 第三个参数:缩放系统

5、示例程序:

#include
#include
#include
#include
using namespace std;
using namespace cv;
#define WINDOW_NAME1 "【原始图窗口】"
#define WINDOW_NAME2 "【经过Warp后的窗口】"
#define WINDOW_NAME3 "【经过Warp和Rotate后的窗口】"
int main()
{
    system("color 2F");

    Point2f srcTriangle[3];
    Point2f dstTriangle[3];

    Mat rotMat(2, 3, CV_32FC1);
    Mat warpMat(2, 3, CV_32FC1);
    Mat srcImage, dstImage_warp, dstImage_warp_rotate;

    srcImage = imread("E:\\Pec\\lan.jpg",1);

    dstImage_warp = Mat::zeros(srcImage.rows, srcImage.cols, srcImage.type());

    srcTriangle[0] = Point2f(50, 50);
    srcTriangle[1] = Point2f(200, 50);
    srcTriangle[2] = Point2f(50, 200);
    dstTriangle[0] = Point2f(100, 100);
    dstTriangle[1] = Point2f(200, 50);
    dstTriangle[2] = Point2f(100, 250);

    warpMat = getAffineTransform(srcTriangle, dstTriangle);

    warpAffine(srcImage, dstImage_warp, warpMat, dstImage_warp.size());

    Point center = Point(dstImage_warp.cols / 2, dstImage_warp.rows / 2);
    double angle = -30.0;
    double scale = 0.8;

    rotMat = getRotationMatrix2D(center, angle, scale);

    warpAffine(dstImage_warp, dstImage_warp_rotate, rotMat, dstImage_warp.size());
    imshow(WINDOW_NAME1, srcImage);
    imshow(WINDOW_NAME2, dstImage_warp);
    imshow(WINDOW_NAME3, dstImage_warp_rotate);
    waitKey(0);
    return 0;

}

【OpenCV】-仿射变换

Original: https://blog.csdn.net/qq_44859533/article/details/126168178
Author: 我菜就爱学
Title: 【OpenCV】-仿射变换

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/720128/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球