图像的仿射变换

1、旋转(保持原图的尺寸大小)
这里写图片描述
这里写图片描述

#include <iostream>  
#include <opencv2\core\core.hpp>  
#include <opencv2\highgui\highgui.hpp>  
#include <opencv2\imgproc\imgproc.hpp>  

using namespace std;
using namespace cv;

int main()
{
    Mat srcImage, dstImage;
    srcImage = imread("1.jpg");
    if (!srcImage.data)
    {
        cout << "读入图片有误!" << endl;
        return -1;
    }
    imshow("原图像", srcImage);//读入原图
    //dstImage.create(srcImage.size(), srcImage.type());
    double degree=50;//旋转角度可修改或者自行输入
    //cout << "请输入旋转角度:";
    //cin >> degree;
    double a = sin(degree * CV_PI / 180);//sin(弧度)的值
    double b = cos(degree * CV_PI / 180);//cos(弧度)的值
    int width = srcImage.cols;
    int height = srcImage.rows;
    //旋转之后新图像的大小
    int rotate_width = int(height * fabs(a) + width * fabs(b));
    int rotate_height = int(width * fabs(a) + height * fabs(b));
    Point center = Point(srcImage.cols / 2, srcImage.rows / 2);//旋转中心不变
    //求旋转矩阵如下
    Mat map_matrix = getRotationMatrix2D(center, degree, 1.0);
    //旋转数组map_matrix 
    // [ m0  m1  m2 ] ===>  [ A11  A12   b1 ]
    // [ m3  m4  m5 ] ===>  [ A21  A22   b2 ]  
    //在旋转中坐标原点是左上角的点,X轴沿着水平方向向右,Y轴沿着竖直方向向下,旋转后坐标原点也应该偏移改变
    map_matrix.at<double>(0, 2) += (rotate_width - width) / 2;     // 修改坐标偏移,修改m2
    map_matrix.at<double>(1, 2) += (rotate_height - height) / 2;   // 修改坐标偏移,修改m5
    warpAffine(srcImage, dstImage, map_matrix, Size(rotate_width, rotate_height), CV_INTER_CUBIC);
    Mat resizeimage;
    resize(dstImage, resizeimage, Size(600, 600), (0, 0), (0, 0), INTER_LINEAR);//图像缩放便于查看
    imshow("rotateimage", resizeimage);
    waitKey();
    return 0;
}

(1)函数 getRotationMatrix2D(Point2fcenter, double angle,
double scale)
第一个參数,Point2f类型的center。表示源图像的旋转中心。
第二个參数,double类型的angle。旋转角度。角度为正值表示向逆时针旋转(坐标原点是左上角)。
第三个參数,double类型的scale,缩放系数。
(2)函数 warpAffine(InputArray src,OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR,
intborderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
第一个參数,InputArray类型的src。输入图像。即源图像。填Mat类的对象就可以。
第二个參数,OutputArray类型的dst,函数调用后的运算结果存在这里,需和源图片有一样的尺寸和类型。
第三个參数,InputArray类型的M。2×3的变换矩阵。
第四个參数,Size类型的dsize,表示输出图像的尺寸。
第五个參数,int类型的flags,插值方法的标识符。
此參数有默认值INTER_LINEAR(线性插值),可选的插值方式例如以下:
INTER_NEAREST - 近期邻插值
INTER_LINEAR - 线性插值(默认值)
INTER_AREA - 区域插值
INTER_CUBIC –三次样条插值
INTER_LANCZOS4 -Lanczos插值
CV_WARP_FILL_OUTLIERS - 填充全部输出图像的象素。假设部分象素落在输入图像的边界外,那么它们的值设定为 fillval.
CV_WARP_INVERSE_MAP –表示M为输出图像到输入图像的反变换。即 。因此能够直接用来做象素插值。否则, warpAffine函数从M矩阵得到反变换。
第六个參数。int类型的borderMode,边界像素模式,默认值为BORDER_CONSTANT。
第七个參数,const Scalar&类型的borderValue,在恒定的边界情况下取的值,默认值为Scalar(),即0。
注:另外提一点,我们的WarpAffine函数与一个叫做cvGetQuadrangleSubPix( )的函数类似,可是不全然同样。 WarpAffine要求输入和输出图像具有同样的数据类型,有更大的资源开销(因此对小图像不太合适)并且输出图像的部分能够保留不变。
2、旋转(不再继续维持原图大小,保持窗口大小不变,可能会存在图像不能完全显现)

#include<iostream>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main()
{
    Mat originalimage,dstimage;
    originalimage = imread("1.jpg");
    double degree = 50;
    Point center = Point(originalimage.cols / 2, originalimage.rows / 2);//旋转中心不变
    Mat map_matrix = getRotationMatrix2D(center, degree, 1.0);
    //设置原图变换顶点
    //Point2f AffinePoints0[3] = { Point2f(120, 50), Point2f(100, 390), Point2f(400, 50) };
    //设置目标图像变换顶点
    //Point2f AffinePoints1[3] = { Point2f(200, 100), Point2f(200, 330), Point2f(500, 50) };
    //计算变换矩阵
    //Mat Trans = getAffineTransform(AffinePoints0, AffinePoints1);
    //矩阵仿射变换
    warpAffine(originalimage,dstimage , map_matrix, Size(originalimage.cols, originalimage.rows));
    //分别显示变换先后图像进行对比
    imshow("src", originalimage);
    imshow("dst", dstimage);
    waitKey(0);
    return 0;
}

3、透视变换

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
    Mat originalimage = imread("1.jpg");
    Mat dstimage;
    if (!originalimage.data)
    {
        cout << "读取图片错误\n" << endl;
    }
    dstimage = Mat::zeros(originalimage.rows, originalimage.cols, originalimage.type());
    //投影变换四个点的映射关系  
    Point2f srcQuadrilateral[4];
    Point2f dstQuadrilateral[4];
    //定义一些Mat变量  
    Mat PerMat(3, 3, CV_32F);  //透视变换矩阵  
    //设置源图像和目标图像上的四组点以计算透视变换  
    srcQuadrilateral[0] = Point2f(0, 0);  //原始图像的左上点  
    srcQuadrilateral[1] = Point2f(originalimage.cols, 0); //原始图像的右上点  
    srcQuadrilateral[2] = Point2f(0, originalimage.rows); //原始图像的左下点  
    srcQuadrilateral[3] = Point2f(originalimage.cols, originalimage.rows); //原始图像的右下点  

    dstQuadrilateral[0] = Point2f((originalimage.cols*0.0), (originalimage.rows*0.3));
    dstQuadrilateral[1] = Point2f((originalimage.cols*0.5), (originalimage.rows*0.0));
    dstQuadrilateral[2] = Point2f((originalimage.cols*0.5), (originalimage.rows*1.0));
    dstQuadrilateral[3] = Point2f((originalimage.cols*1.0), (originalimage.rows*0.5));
    //求得透视变换矩阵并计算的透视变换  
    PerMat = getPerspectiveTransform(srcQuadrilateral, dstQuadrilateral);
    //Output perspective transformation matrix  
    Mat PerMat2;
    PerMat.convertTo(PerMat2, CV_32F);//32位浮点型
    cout << "perspective transformation matrix:\n" << PerMat2 << endl;
    warpPerspective(originalimage, dstimage, PerMat, dstimage.size());
    imshow("trans", dstimage);
    waitKey();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值