• 《opencv学习笔记》-- 仿射变换


    仿射变换代表的是两幅图像之间的映射关系

    仿射变换是指在几何中,一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间的过程。它保持了二维图形的“平直性”(即:直线经过变换之后依然是直线)和“平行性”(即:二维图形之间的相对位置关系保持不变,平行线依然是平行线,且直线上点的位置顺序不变)。

    一个任意的仿射变换都能表示为乘以一个矩阵(线性变换)接着再加上一个向量(平移)的形式   

    仿射变换三种常见的变换形式:

            旋转,rotation (线性变换)

            平移,translation(向量加)

            缩放,scale(线性变换)

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

     

    仿射变换的求法:

    使用场景:

    <1> 已知 X和T,而且我们知道他们是有联系的,求出矩阵 M

    <2> 已知 M和X,求 T。用算式T = M·X. 对于这种联系的信息可以用矩阵 M 清晰的表达 (即给出明确的2×3矩阵) 或者也可以用两幅图片点之间几何关系来表达。

    矩阵M 联系着两幅图片,就以 其表示两图中各三 点直接的联系为例。

     

    图中,点1, 2,3与image2中的点一 一映射。
    1. void warpAffine(InputArray src, OutputArray dst, InputArray M,
    2. Size dsize, int flags = INTER_LINEAR,
    3. int borderMode = BORDER_CONSTANT,
    4. const Scalar& borderValue = Scalar())

    对图像做放射变换。

    dst(x, y) = src(M11x + M12y + M13,   M21x + M22y + M23)

    参数1,InputArray类型的src,源图像,Mat类的对象。

    参数2,运算结果,需和源图片有一样的尺寸和类型。

    参数3,InputArray类型的M,2×3的变换矩阵。

    参数4,Size类型的dsize,表示输出图像的尺寸。

    参数5,int类型的flags,插值方法的标识符。参数有默认值INTER_LINEAR(线性插值),可选的插值方式如下:

            INTER_NEAREST            最近邻插值

            INTER_LINEAR                线性插值(默认值)

            INTER_AREA                    区域插值

            INTER_CUBIC                   三次样条插值

            INTER_LANCZOS4            Lanczos插值

            WARP_FILL_OUTLIERS   填充所有输出图像的象素。 如果部分象素落在输入图像的边

                                                        界外,那么它们的值设定为 fillval.

            WARP_INVERSE_MAP    表示M为输出图像到输入图像的反变换,即 因此可以直接用

                                                      来做象素插值。否则, warpAffine函数从M矩阵得到反变换。

    参数6,int类型的borderMode,边界像素模式,默认值为BORDER_CONSTANT。

    参数7,在恒定的边界情况下取的值,默认值为Scalar(),即0。

    计算二维旋转变换矩阵。变换会将旋转中心映射到它自身:

    Mat getRotationMatrix2D(Point2f center, double angle, double scale)

    参数1,表示源图像的旋转中心。

    参数2,旋转角度。角度为正值表示向逆时针旋转(坐标原点是左上角)。

    参数3,缩放系数。

    计算二维三角变换矩阵

    Mat getAffineTransform( InputArray src, InputArray dst );

    参数1,InputArray类型的src,原来三个点的坐标;

    参数2,OutputArray类型的dst,映射后三个点的坐标;

    1. //定义两组点,代表两个三角形
    2. Point2f srcTriangle[3];
    3. Point2f dstTriangle[3];
    4. //定义一些Mat变量
    5. Mat rotMat(2, 3, CV_32FC1);
    6. Mat warpMat(2, 3, CV_32FC1);
    7. Mat srcImage, dstImage_warp, dstImage_warp_rotate;
    8. //加载源图像并作一些初始化
    9. srcImage = imread("1.jpg", 1);
    10. dstImage_warp = Mat::zeros(srcImage.rows, srcImage.cols, srcImage.type());
    11. //设置源图像和目标图像上的三组点以计算仿射变换
    12. srcTriangle[0] = Point2f(0, 0);
    13. srcTriangle[1] = Point2f(static_cast<float>(srcImage.cols - 1), 0);
    14. srcTriangle[2] = Point2f(0, static_cast<float>(srcImage.rows - 1));
    15. dstTriangle[0] = Point2f(static_cast<float>(srcImage.cols*0.0),
    16. static_cast<float> (srcImage.rows*0.33));
    17. dstTriangle[1] = Point2f(static_cast<float>(srcImage.cols*0.65),
    18. static_cast<float>(srcImage.rows*0.35));
    19. dstTriangle[2] = Point2f(static_cast<float>(srcImage.cols*0.15),
    20. static_cast<float>(srcImage.rows*0.6));
    21. //求得仿射变换
    22. warpMat = getAffineTransform(srcTriangle, dstTriangle);
    23. //对源图像应用求得的仿射变换
    24. warpAffine(srcImage, dstImage_warp, warpMat, dstImage_warp.size());
    25. //对图像进行缩放后再旋转
    26. // 计算绕图像中点顺时针旋转50度缩放因子为0.6的旋转矩阵
    27. Point center = Point(dstImage_warp.cols / 2, dstImage_warp.rows / 2);
    28. double angle = -30.0;
    29. double scale = 0.8;
    30. // 通过上面的旋转细节信息求得旋转矩阵
    31. rotMat = getRotationMatrix2D(center, angle, scale);
    32. // 旋转已缩放后的图像
    33. warpAffine(dstImage_warp, dstImage_warp_rotate, rotMat, dstImage_warp.size());

  • 相关阅读:
    Spark SQL数据通用保存数据_大数据培训
    等差数列和特殊矩阵压缩公式
    猿创征文|运维工具介绍
    CTE(公共表表达式)和视图在查询时的性能影响
    【基于国产openEuler操作系统手动安装openLooKeng1.10.0单机版】
    云原生之K8S------Pod的基础概念
    0033【Edabit ★☆☆☆☆☆】【字符串表达式计算器】Miserable Parody of a Calculator
    正则表达式相关知识点
    亚马逊云科技-游戏孵化营 -学习心得
    关于信息安全软考的记录6
  • 原文地址:https://blog.csdn.net/qq_41653875/article/details/125985259