opencv学习笔记22-opencv图形变换(旋转、缩放、仿射、投影)

一、函数:

a.getRotationMatrix2D函数:

(1)函数原型:

  • CV_EXPORTS_W Mat getRotationMatrix2D(Point2f center, double angle, double scale);

(2) 函数作用:

  • 计算一个2D旋转的仿射变换矩阵。这个矩阵可以用于图像处理中的旋转操作,将图像中的每个点绕指定的中心点按照给定的角度进行旋转,并且可以应用一个缩放因子。

(3)参数说明:

  • Point2f center:旋转中心的坐标,以(x, y)的形式表示。
  • double angle:旋转角度,以度为单位。正值表示逆时针旋转。
  • double scale:各向同性缩放因子。

 (4)旋转矩阵的计算公式:

  • 旋转矩阵具体形式为:

(5) 补充说明:

  • 这个变换矩阵将旋转中心映射到自身。如果目标不是这样,需要调整平移量。这个函数可以用来获取一个2D旋转变换的矩阵,该矩阵可以用于图像的仿射变换,例如在warpAffinetransform函数中使用。

b.warpAffine 函数:

(1)函数原型:

CV_EXPORTS_W void warpAffine( InputArray src, OutputArray dst, InputArray M, 
        Size dsize, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, 
        const Scalar& borderValue = Scalar()); 

(2)函数作用:

  • warpAffine 根据提供的仿射变换矩阵 M 对输入图像 src 进行变换,生成输出图像 dst

(3) 参数说明:

  • src:输入图像,即要进行变换的原始图像。
  • dst:输出图像,其大小由 dsize 指定,并且与 src 具有相同的数据类型。
  • M2x3 仿射变换矩阵,定义了图像点之间的线性变换关系。
  • dsize:输出图像的大小,即 dst 的宽度和高度。
  • flags:插值方法的标志,可以是 INTER_LINEAR(双线性插值)、INTER_NEAREST(最近邻插值)等,以及可选的 WARP_INVERSE_MAP 标志,表示 M 是逆变换矩阵。
  • borderMode:边界外推方法,用于处理图像边缘的像素。BORDER_CONSTANT(常数边界)是默认选项,其他选项包括 BORDER_REFLECTBORDER_WRAP 等。
  • borderValue:当 borderMode 设置为 BORDER_CONSTANT 时使用的边界值,默认为0。

(4) 变换公式:

  • 如果设置了 WARP_INVERSE_MAP 标志,则直接使用 M 矩阵进行变换。否则,首先使用 invertAffineTransform 函数对 M 进行求逆,然后将逆矩阵用于变换公式。

(5) 补充说明:

  • warpAffine 函数常用于图像校正、图像配准、图像变换等场景。
  • 该函数不能在原地(in-place)操作,即输入图像 src 和输出图像 dst 不能是同一个图像。

(6) 相关函数:

  • warpPerspective(用于透视变换)、resize(用于改变图像大小)、remap(用于一般映射)、getRectSubPix(用于获取图像的子像素点)、transform(用于对图像点应用线性变换)。

c.getAffineTransform 函数:

(1)函数原型:

 CV_EXPORTS Mat getAffineTransform( const Point2f src[], const Point2f dst[] );

 (2)函数作用:

  • 根据源图像中的三个点和它们在目标图像中对应的三个点,计算一个仿射变换矩阵。

 (3) 参数说明:

  • src:源图像中三个顶点的坐标数组,每个顶点的坐标用 Point2f 表示,即包含 x 和 y 两个浮点数。
  • dst:目标图像中与 src 中顶点对应的三个顶点的坐标数组。

(4)变换公式:

 (5) 补充说明:

  • 函数返回一个 2x3 的仿射变换矩阵 map_matrix,这个矩阵可以用于 warpAffinetransform 函数来实际应用变换。

  • getAffineTransform 函数常用于图像配准、图像校正、图像变换等场景,特别是在已知源图像和目标图像之间三个对应点的情况下。

 (6) 相关函数:

  • warpAffine:使用仿射变换矩阵对图像进行变换。
  • transform:将变换应用到图像的点集或向量上。
d.getPerspectiveTransform 函数: 

(1)函数原型:

CV_EXPORTS_W Mat getPerspectiveTransform(InputArray src, InputArray dst,
 int solveMethod = DECOMP_LU);

  (2)函数作用:

  • 用于计算一个3x3的透视变换矩阵,它可以将图像中的一个四边形顶点集映射到另一个四边形顶点集。透视变换可以模拟相机视角的变化,用于图像校正等。

  (3) 参数说明:

  • src:源图像中四边形顶点的坐标数组。
  • dst:目标图像中与src中顶点对应的四边形顶点的坐标数组。
  • solveMethod:传递给cv::solve方法的选项,用于解决线性系统,DECOMP_LU是默认的分解方法。

(4) 变换公式:

               

 (5)公共点(getAffineTransform )

  • 两个函数都接受坐标数组作为输入,这些坐标定义了源图像和目标图像之间的对应关系。
  • 它们都返回一个变换矩阵,可以用于warpAffinewarpPerspective函数来实际应用变换。
  • 它们都可以用于图像变换,但getPerspectiveTransform适用于更复杂的视角变换,而getAffineTransform适用于保持平行线的变换。

(6) 注意事项

  • 这些函数不能在原地(in-place)操作,即输入坐标和输出坐标不能相同。
  • 透视变换和仿射变换都是线性变换,但透视变换可以模拟更复杂的视角效果。
 e.warpPerspective 函数:

(1)函数原型:

CV_EXPORTS_W void warpPerspective( InputArray src, OutputArray dst,
                 InputArray M, Size dsize, int flags = INTER_LINEAR, 
int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar());

(2)函数作用:

  • warpPerspective 根据提供的3x3透视变换矩阵 M 对输入图像 src 进行变换,生成输出图像 dst。 

(3) 参数说明:

  • src:输入图像,即要进行变换的原始图像。
  • dst:输出图像,其大小由 dsize 指定,并且与 src 具有相同的数据类型。
  • M:3x3 透视变换矩阵,定义了图像点之间的变换关系。
  • dsize:输出图像的大小,即 dst 的宽度和高度。
  • flags:插值方法的标志,可以是 INTER_LINEAR(双线性插值)或 INTER_NEAREST(最近邻插值),以及可选的 WARP_INVERSE_MAP 标志,表示 M 是逆变换矩阵。
  • borderMode:边界外推方法,可以是 BORDER_CONSTANT(常数边界)或 BORDER_REPLICATE(复制边界)等。
  • borderValue:当 borderMode 设置为 BORDER_CONSTANT 时使用的边界值,默认为0。

 (4)变换公式:

  • 当设置了 WARP_INVERSE_MAP 标志时使用上述公式。否则,首先使用 invert 函数对 M 进行求逆,然后将逆矩阵用于变换公式。 

(5) 补充说明:

  • warpPerspective 函数常用于图像校正(如校正透视失真)、图像拼接、3D场景建模等。

  • 该函数不能在原地(in-place)操作,即输入图像 src 和输出图像 dst 不能是同一个图像。

(6) 相关函数:

  • warpAffine(用于仿射变换)、resize(用于改变图像大小)、remap(用于一般映射)、getRectSubPix(用于获取图像的子像素点)、perspectiveTransform(用于对点集应用透视变换)。

二、示例代码:

#include <opencv2/core/utils/logger.hpp>
#include <opencv2/opencv.hpp>           
#include <opencv2/videoio.hpp>       
#include <opencv2/objdetect.hpp>        
#include <opencv2/highgui/highgui_c.h>  
#include <iostream>                     

using namespace cv;                    
using namespace std;      

int main() 
{
    utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT); 
    // 读取图片
    Mat srcMat = imread("C:\\Users\\86173\\Desktop\\TI\\Q版阿离.png");
    // 判断图片是否读取成功
    if (srcMat.empty()) return 0; // 如果图片未读取成功,结束程序

    // 初始化旋转角度以及缩放尺度
    auto angle = -10.0; // 定义旋转角度为-10度(逆时针)
    float scale = 0.5; // 定义缩放因子为0.5

    //设置旋转中心为图像中心(计算图像中心点坐标)
    Point2f center(srcMat.cols * 0.5, srcMat.rows * 0.5);

    //创建2x3的仿射变换矩阵(获得旋转缩放变换矩阵)
    const Mat affine= getRotationMatrix2D(center, angle, scale); 

    // 定义存放旋转缩放结果的图像容器
    Mat spin_Scale; // 用于存放旋转缩放后的图像

    // 对原图像利用warpAffine函数进行仿射变换(旋转和缩放)
    warpAffine(srcMat, spin_Scale, affine, srcMat.size()); 

    // 定义仿射变换矩阵
    Mat affine_image; // 用于存放仿射变换后的图像
    // 变换前的三个点坐标
    const Point2f src_pt[] = {
        Point2f(200,200), // 第一个点的坐标
        Point2f(250,200), // 第二个点的坐标
        Point2f(200,100)  // 第三个点的坐标
    };
    // 变换后的三个点坐标
    const Point2f warp_pt[] = {
        Point2f(300,100), // 第一个点变换后的坐标
        Point2f(300,50),  // 第二个点变换后的坐标
        Point2f(200,100)  // 第三个点变换后的坐标
    };
    //根据三个点,使用getAffineTransform计算仿射矩阵
    const Mat affine_matrix = getAffineTransform(src_pt, warp_pt); 
    //对原图像利用warpAffine函数进行仿射变换
    warpAffine(srcMat, affine_image, affine_matrix, srcMat.size()); 


    // 定义透视变换矩阵
    Mat perspective_image; // 用于存放透视变换后的图像
    // 变换前的四个点坐标
    Point2f pts1[] = {
        Point2f(150,150), // 第一个点的坐标
        Point2f(150,300), // 第二个点的坐标
        Point2f(350,300), // 第三个点的坐标
        Point2f(350,150)  // 第四个点的坐标
    };
    // 变换后的四个点坐标
    Point2f pts2[] = {
        Point2f(200,150), // 第一个点变换后的坐标
        Point2f(200,300), // 第二个点变换后的坐标
        Point2f(340,270), // 第三个点变换后的坐标
        Point2f(340,180)  // 第四个点变换后的坐标
    };
    // 根据四个点, 使用getPerspectiveTransform计算透视变换矩阵
    Mat perspective_matrix = cv::getPerspectiveTransform(pts1, pts2);
    // 对原图像利用warpPerspective函数进行透视变换
    warpPerspective(srcMat, perspective_image, perspective_matrix, srcMat.size());


    // 显示所有结果
    imshow("原图像", srcMat); // 显示原图像
    imshow("旋转缩放", spin_Scale); // 显示旋转缩放后的图像
    imshow("仿射变换", affine_image); // 显示仿射变换后的图像
    imshow("透视变换", perspective_image); // 显示透视变换后的图像

     waitKey(0); // 等待任意按键继续
     destroyAllWindows(); // 关闭所有OpenCV创建的窗口
     return 0;
}

三、运行结果:

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值