zoukankan      html  css  js  c++  java
  • Opencv 几何变换<9>

    一、resize()

    该函数可以改变图像尺寸,原型:

    void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR );

    src:输入,原图像,即待改变大小的图像;

    dst:输出,改变大小之后的图像,这个图像和原图像具有相同的内容,只是大小和原图像不一样而已;

    dsize:输出图像的大小。如果这个参数不为0,那么就代表将原图像缩放到这个Size(width,height)指定的大小;如果这个参数为0,那么原图像缩放之后的大小就要通过下面的公式来计算:

    dsize = Size(round(fx*src.cols), round(fy*src.rows))

    其中,fx和fy就是下面要说的两个参数,是图像width方向和height方向的缩放比例。

    fx:width方向的缩放比例,如果它是0,那么它就会按照(double)dsize.width/src.cols来计算;

    fy:height方向的缩放比例,如果它是0,那么它就会按照(double)dsize.height/src.rows来计算;

    interpolation:这个是指定插值的方式,图像缩放之后,肯定像素要进行重新计算的,就靠这个参数来指定重新计算像素的方式,有以下几种:


    INTER_NEAREST - 最邻近插值
    INTER_LINEAR - 双线性插值,如果最后一个参数你不指定,默认使用这种方法
    INTER_AREA - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
    INTER_CUBIC - 4x4像素邻域内的双立方插值
    INTER_LANCZOS4 - 8x8像素邻域内的Lanczos插值

     

    使用注意事项:

    1. dsize和fx/fy不能同时为0,要么你就指定好dsize的值,让fx和fy空置直接使用默认值,就像

    resize(img, imgDst, Size(30,30));

    要么你就让dsize为0,指定好fx和fy的值,比如fx=fy=0.5,那么就相当于把原图两个方向缩小一倍!

    2. 至于最后的插值方法,正常情况下使用默认的双线性插值就够用了。

    几种常用方法的效率是:最邻近插值>双线性插值>双立方插值>Lanczos插值;

    但是效率和效果成反比,所以根据自己的情况酌情使用。

    以上是来自别人博客抄袭过来的,如果想随意修改图片的大小,可以建立以Trankbar;

     1 using namespace cv;
     2 Mat sizeChange;
     3 Mat src;
     4 int g_nfxSize = 10;
     5 double g_nfxMax = 20;
     6 void onChange(int, void*);
     7 void main()
     8 {
     9  src = imread("E:\项目\OPENCV\GeomatricTransFormation\1.jpg", 1);
    10  imshow("原图", src);
    11  namedWindow("修改图片");
    12  createTrackbar("缩放", "修改图片", &g_nfxSize, g_nfxMax, onChange);
    13  onChange(g_nfxSize, 0);
    14  //imshow("修改图片", sizeChange);
    15  waitKey();
    16 }
    17 void onChange(int, void*parmas)
    18 {
    19  double g_nfxSizeValue;
    20  g_nfxSizeValue = (double)g_nfxSize *0.1;
    21  resize(src, sizeChange, Size(0, 0), g_nfxSizeValue, g_nfxSizeValue, INTER_LINEAR);
    22  imshow("修改图片", sizeChange);
    23 }

    二、 图像平移

     

    图像平移:用0填充之前留下的空缺!

    Mat imgTranslate(Mat& src, int x_off, int y_off);
    Mat imgTranslate1(Mat& src, int x_off, int y_off);
    void main()
    {
        Mat srcImage = imread("E:\欣奕华\项目\OPENCV\GeomatricTransFormation\2.jpg", 1);
        imshow("原图", srcImage);
        int k = srcImage.channels();
        Mat dstImage;
        dstImage = imgTranslate(srcImage,500,500);
        imshow("平移图", dstImage);
        waitKey(0);
    }
    //平移1
    //平移注意X,Y代表行还是列,以及移动时别超出了图像的范围!!!!!
    Mat imgTranslate(Mat& src, int x_off, int y_off)
    {
        int rows = src.rows;
        int cols = src.cols;
    
        Mat dst = Mat::zeros(rows+ y_off,cols+ x_off, CV_8UC3);
    
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                int x = j + x_off;
                int y = i + y_off;
                if (x >= 0 && y >= 0 && x <= (cols+ x_off) && y <= (rows + y_off))
                {
                    dst.at<Vec3b>(y, x) = src.at<Vec3b>(i, j);
                }
            }
        }
        return dst;
    }
    //平移2
    Mat imgTranslate1(Mat& src, int x_off, int y_off)
    {
        int rows = src.rows+ y_off;
        int cols = src.cols+ x_off;
    
        Mat dst = Mat::zeros(rows, cols, CV_8UC3);
    
        for (int i = 0; i < src.rows; i++)
        {
            for (int j = 0; j < src.cols; j++)
            {
                int x = j + x_off;
                int y = i + y_off;
                if (x >= 0 && y >= 0 && x <= cols && y <= rows)
                {
                    for (int k = 0; k < src.channels(); k++)
                    {
                        dst.at<Vec3b>(y, x)[k] = src.at<Vec3b>(i, j)[k];
                    }
                }
            }
        }
        return dst;
    }

     三、仿射变换

          仿射变换又称仿射变换,是指在几何中,一个向量空间进行一次线性变换并进行线性平移的过程,常见包括三种:旋转,平移,缩放。其实就是两幅图之间映射,找到这种映射关系是关键;

    M 是2 X 3 矩阵;

    Mat affinTranslate(Mat& src)
    {
        Point2f srcTrangle[3];
        Point2f dstTrangle[3];
    
        Mat warpMat(2, 3, CV_32FC1);
        Mat dst;
        dst.create(src.size(), src.type());
        srcTrangle[0] = Point2f(0, 0);
        srcTrangle[1] = Point2f(static_cast<float>(src.rows-1), 0);
        srcTrangle[2] = Point2f(0,static_cast<float>( src.cols-1));
    
        dstTrangle[0] = Point2f(static_cast<float>(src.rows - 1)*0.01, static_cast<float>(src.cols - 1)*0);
        dstTrangle[1] = Point2f(static_cast<float>(src.rows - 1)*0.9, static_cast<float>(src.cols - 1)*0);
        dstTrangle[2] = Point2f(static_cast<float>(src.rows - 1)*0, static_cast<float>(src.cols - 1)*0.9);
    
        warpMat = getAffineTransform(srcTrangle, dstTrangle);
        cout << warpMat<<endl;
    
        warpAffine(src, dst, warpMat, dst.size());
        //imshow("AffineImage",dst);
        return dst;
    }
    
    Mat rotateTranslate(Mat& src)
    {
        Mat rotateMat = Mat(2, 3, CV_32FC1);
        Mat dst;
        dst.create(src.size(), src.type());
        Point center = Point(src.rows / 2, src.cols / 2);
        double scale = 0.5;
        double angle = 30;
    
        rotateMat = getRotationMatrix2D(center, angle, scale);
        warpAffine(src, dst, rotateMat,dst.size());
        cout << rotateMat;
        return dst;
    }

     以上方法,可以创建trankbar,通过修改参数,可以更为直观的观察现象!!!!

    此节的内容得出效果有点类似于重映射,将在下一节再进行学习。

  • 相关阅读:
    滴滴 cubeui 教程
    继往开来的 sass 3 代编译器:ruby sass、nodesass、dartsass
    研究大佬用 Vue 写的倒计时组件,学到了不少东西
    狠人!标星 3.4 万的项目说删就删,几行代码搞崩数万个开源项目
    本人EE知识体系导航 Embedded menu
    PMP之思维――我的PMP备考之旅
    总有些瞬间,能温暖整个曾经
    不是一辈子的人,不说一辈子的话
    QImage对一般图像的处理
    从零开始系统深入学习android(已完成部分的目录带链接)
  • 原文地址:https://www.cnblogs.com/xingyuanzier/p/11654924.html
Copyright © 2011-2022 走看看