zoukankan      html  css  js  c++  java
  • opencv学习笔记7 重映射和仿射变换

    一。重映射

    void remap(InputArray src, OutputArraydst, InputArray map1, InputArray map2, int interpolation, intborderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())

    • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可,且需为单通道8位或者浮点型图像。
    • 第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放函数调用后的输出结果,需和源图片有一样的尺寸和类型。
    • 第三个参数,InputArray类型的map1,它有两种可能的表示对象。
    • 表示点(x,y)的第一个映射。
    • 表示CV_16SC2 , CV_32FC1 或CV_32FC2类型的X值。
    • 第四个参数,InputArray类型的map2,同样,它也有两种可能的表示对象,而且他是根据map1来确定表示那种对象。
    • 若map1表示点(x,y)时。这个参数不代表任何值。
    • 表示CV_16UC1 , CV_32FC1类型的Y值(第二个值)。
    • 第五个参数,int类型的interpolation,插值方式,之前的resize( )函数中有讲到,需要注意,resize( )函数中提到的INTER_AREA插值方式在这里是不支持的,所以可选的插值方式如下:
    • INTER_NEAREST - 最近邻插值
    • INTER_LINEAR – 双线性插值(默认值)
    • INTER_CUBIC – 双三次样条插值(逾4×4像素邻域内的双三次插值)
    • INTER_LANCZOS4 -Lanczos插值(逾8×8像素邻域的Lanczos插值)
    • 第六个参数,int类型的borderMode,边界模式,有默认值BORDER_CONSTANT,表示目标图像中“离群点(outliers)”的像素值不会被此函数修改。
    • 第七个参数,const Scalar&类型的borderValue,当有常数边界时使用的值,其有默认值Scalar( ),即默认值为0。
     1 #include<iostream>
     2 #include<vector>
     3 #include<opencv2/opencv.hpp>
     4 using namespace std;
     5 using namespace cv;
     6 int main()
     7 {
     8     Mat srcImage, dstImage;
     9     Mat map_x, map_y;
    10 
    11     //【1】载入原始图
    12     srcImage = imread("E:/test.jpg", 1);
    13     if (!srcImage.data) { printf("读取图片错误,请确定目录下是否有imread函数指定的图片存在~! 
    "); return false; }
    14     imshow("原始图", srcImage);
    15 
    16     //【2】创建和原始图一样的效果图,x重映射图,y重映射图
    17     dstImage.create(srcImage.size(), srcImage.type());
    18     map_x.create(srcImage.size(), CV_32FC1);
    19     map_y.create(srcImage.size(), CV_32FC1);
    20 
    21     //【3】双层循环,遍历每一个像素点,改变map_x & map_y的值
    22     for (int j = 0; j < srcImage.rows; j++)
    23     {
    24         for (int i = 0; i < srcImage.cols; i++)
    25         {
    26             //改变map_x & map_y的值. 
    27             map_x.at<float>(j, i) = static_cast<float>(srcImage.cols-i); //关于x轴对称
    28             map_y.at<float>(j, i) = static_cast<float>(j); //y轴不变
    29         }
    30     }
    31 
    32     //【4】进行重映射操作
    33     remap(srcImage, dstImage, map_x, map_y, CV_INTER_LINEAR, BORDER_CONSTANT, Scalar(0, 0, 0));
    34 
    35     //【5】显示效果图
    36     imshow("【程序窗口】", dstImage);
    37     waitKey();
    38 
    39     return 0;
    40 }

     二。仿射变换

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

    1.getAffineTransform(求平移矩阵)

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

    参数1:Point2f类型的数组,源图像的三个点位置

    参数2:Point2f类型的数组,目标图像的三个点位置

     通过指定3个点的偏移确定图像的变换矩阵。

    2.getRotationMatrix2D(求旋转、缩放矩阵)

    Mat getRotationMatrix2D(Point2fcenter, double angle, double scale)

    3.warpAffine(进行仿射变换)

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

     1 #include "opencv2/highgui/highgui.hpp"
     2 #include "opencv2/imgproc/imgproc.hpp"
     3 #include <iostream>
     4 
     5 using namespace cv;
     6 using namespace std;
     7 
     8 int main()
     9 {
    10 
    11     Point2f srcTriangle[3];  //计算平移矩阵的三个点
    12     Point2f dstTriangle[3];
    13 
    14     Mat rotMat(2, 3, CV_32FC1); //旋转矩阵
    15     Mat warpMat(2, 3, CV_32FC1); //平移矩阵
    16     Mat srcImage, dstImage_warp, dstImage_rotate;
    17 
    18     srcImage = imread("F:/opencv/lena.jpg", 1);
    19 
    23     srcTriangle[0] = Point2f(0, 0); //左上角点
    24     srcTriangle[1] = Point2f(static_cast<float>(srcImage.cols - 1), 0); //右上角点
    25     srcTriangle[2] = Point2f(0, static_cast<float>(srcImage.rows - 1)); //左下角点
    26 
    27     dstTriangle[0] = Point2f(static_cast<float>(srcImage.cols*0.0), static_cast<float>(srcImage.rows*0.3)); //对应变换的点
    28     dstTriangle[1] = Point2f(static_cast<float>(srcImage.cols*0.5), static_cast<float>(srcImage.rows*0.5));
    29     dstTriangle[2] = Point2f(static_cast<float>(srcImage.cols*0.2), static_cast<float>(srcImage.rows*0.6));
    30     warpMat=getAffineTransform(srcTriangle, dstTriangle);  //计算平移矩阵
    31     warpAffine(srcImage, dstImage_warp, warpMat, dstImage_warp.size()); //进行仿射变换
    32 
    33     Point center = Point(dstImage_warp.cols / 2, dstImage_warp.rows / 2); //得到旋转中心点
    34     double angle = -90;  //旋转角度,+ 逆时针 -顺时针
    35     double scale = 0.5;  //缩放比例
    36     rotMat = getRotationMatrix2D(center, angle, scale); //计算旋转矩阵
    37     warpAffine(srcImage, dstImage_rotate, rotMat, srcImage.size()); //进行仿射变换
    38 
    39     imshow("源图像", srcImage);
    40     imshow("平移变换的图像", dstImage_warp);
    41     imshow("旋转,缩放的图像", dstImage_rotate);
    42     waitKey(0);
    43 
    44     return 0;
    45 }

  • 相关阅读:
    构建之法阅读笔记01
    学习进度13
    学习进度12
    个人冲刺十
    个人冲刺九
    个人冲刺八
    学习进度11
    个人冲刺七
    个人冲刺六
    [HDU 1232 ]畅通工程
  • 原文地址:https://www.cnblogs.com/sclu/p/11513010.html
Copyright © 2011-2022 走看看