图像变换

OpenCV4提供了函数来实现图像形状的变换,包括图像的尺寸变换、图像翻转以及图像旋转

图像连接vconcat()

OpenCV4针对图像左右连接和上下连接两种方式提供了两个不同的函数

vconcat()函数用于实现图像或者矩阵数据的上下连接

该函数可以连接存放在数组变量中的多个Mat类型的数据,也可以直接连接两个Mat类型数据

vconcat()函数原型(1):

void vconcat(const Mat* src,
             size_t nsrc,
             OutputArray dst
             )
  • src:Mat矩阵类型的数组
  • nsrc:数组中Mat类型数据的数目
  • dst:连接后的Mat类矩阵

该函数对存放在数组矩阵中的Mat类型数据进行纵向连接,第一个参数是存放多个Mat类型数据的数组

要求数组中所有的Mat类型具有相同的列数并且具有相同的数据类型和通道数。

第二个参数是数组中含有的Mat类型数据的数目

最后一个参数是拼接后输出的结果

结果的宽度与第一个Mat数据类型相同,高度为数组所有Mat类型数据的高度的总和

并且与第一个Mat类型数据具有相同的数据类型和通道数

vconcat函数()原型(2):

void vconcat(InputArray src1,
             InputArray src2,
             OutputArray dst
             )
  • src1:第一个需要连接的Mat类矩阵
  • src2:第二个需要连接的Mat类矩阵,与第一个参数具有相同的宽度、数据类型和通道数
  • dst:连接后的Mat类矩阵

该函数直接对两个Mat类型的数据进行竖向连接。前两个参数分别是需要连接的两个Mat类型变量

两者需要具有相同的宽度、数据类型及通道数,第三个参数是连接后输出结果,第一个参数在上,第二个参数在下

hconcat()函数用于实现图像或者矩阵数据的左右连接,与vconcat()函数类似

该函数既可以连接存放在数据变量中的多个Mat类型数据,又可以直接连接两个Mat类型数据

hconcat()函数原型(1):

void hconcat(const Mat* src,
             size_t nsrc,
             OutputArray dst
             )
  • src:Mat矩阵类型的数组
  • nsrc:数组中Mat类型数据的数目
  • dst:连接后的Mat类矩阵

该函数要求第一个参数数组中所有Mat类型变量具有相同的高度、数据类型和通道数

hconcat()函数原型(2):

void hconcat(InputArray src1,
             InputArray src2,
             OutputArray dst
             )
  • src1:第一个需要连接的Mat类矩阵
  • src2:第二个需要连接的Mat类矩阵,与第一个参数具有相同的宽度、数据类型和通道数
  • dst:连接后的Mat类矩阵

两个Mat类型需要具有相同的宽度、数据类型及通道数

示例:

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
    //矩阵数组的横竖连接
    Mat matArray[] = { Mat(1,2,CV_32FC1,Scalar(1)),
                       Mat(1,2,CV_32FC1,Scalar(2)) };
    Mat vout,hour;
    vconcat(matArray,2,vout);
    cout << "图像数组竖向连接:" << endl << vout << endl;
    hconcat(matArray,2,hour);
    cout << "图像数组横向连接:" << endl << hour << endl;

    //读取4个子图像,00表示左上角、01表示右上角、10表示左下角、11表示右下角

    Mat img00 = imread("E:\\CLion\\opencv_xin\\SG\\SG_0.jpg");
    Mat img01 = imread("E:\\CLion\\opencv_xin\\SG\\SG_1.jpg");
    Mat img10 = imread("E:\\CLion\\opencv_xin\\SG\\SG_2.jpg");
    Mat img11 = imread("E:\\CLion\\opencv_xin\\SG\\SG_3.jpg");

    if (img00.empty() || img01.empty() || img10.empty() || img11.empty())
    {
        cout << "Error" << endl;
        return -1;
    }
    //显示4个子图像
    imshow("img00",img00);
    imshow("img01",img01);
    imshow("img10",img10);
    imshow("img11",img11);

    //图像连接
    Mat img,img0,img1;
    //图像横向连接
    hconcat(img00,img01,img0);
    hconcat(img10,img11,img1);
    //横向连接结果再进行竖向连接
    vconcat(img0,img1,img);
    //显示连接图像结果
    namedWindow("img0",WINDOW_NORMAL);
    namedWindow("img1",WINDOW_NORMAL);
    namedWindow("img",WINDOW_NORMAL);
    imshow("img0",img0);
    imshow("img1",img1);
    imshow("img",img);
    waitKey(0);
    return 0;
}

图像尺寸变换resize()

图像的尺寸变换实际是就是改变图像的长和宽,实现图像的缩放

OpenCV提供了resize()函数用于将图像修改成指定尺寸

resize()函数原型:

void resize(InputArray src,
            OutputArray dst,
            Size dsize,
            double fx = 0,
            double fy = 0,
            int interpolation = INTER_LINEAR
            )
  • src:输入图像
  • dst:输出图像,图像的数据类型与src相同
  • dsize:输出图像的尺寸
  • fx:水平轴的比例因子,如果将水平轴变为原来的两倍,则赋值为2
  • fy:垂直轴的比例因子,如果将垂直轴变为原来的两倍,则赋值为2
  • interpolation:插值方法的标志

该函数主要用来对图像尺寸进行缩放,前两个参数分别是输入图像和尺寸缩放之后的输出图像

dsize和fx(fy)同时可以调整输出图像的参数,因此两类参数在实际使用的时候只需要使用一类

当根据两个参数计算出来的输出图像尺寸不一致时,以dsize设置的图像尺寸为准

最后一个参数是选择图像插值的标志,在图像缩放相同的尺寸时,选择不同的插值方法会具有不同的效果

一般来说,如果要缩小图像,那么通常使用INTER_AREA标志会有较好的效果

放大图像的话,使用INTER_CUBICINTER_LINEAR标志通常会有较好的效果

前者计算速度较慢,后者较快,前者效果较好,当两者差距不大

插值方法标志

标志参数 简记 作用
INTER_NEAREST 0 最近邻插值法
INTER_LINEAR 1 双线性插值法
INTER_CUBIC 2 双三次插值
INTER_AREA 3 使用像素区域关系重新采样,首选用于图像缩小
INTER_LANCZOS4 4 Lanczos插值法
INTER_LINEAR_EXACT 5 为精确双线性插值法
INTER_MAX 7 用掩码进行插值

示例:

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
    Mat gray = imread("E:\\CLion\\opencv_xin\\SG\\SG_1.jpg");
    if (gray.empty()) {
        cout << "Error" << endl;
        return -1;
    }

    Mat smallImg,bigImg0,bigImg1,bigImg2,s;
    resize(gray ,smallImg,Size(15,15),0,0,INTER_AREA); //先将图像缩小
    resize(smallImg,bigImg0,Size(30,30),0,0,INTER_NEAREST); //最近邻插值法
    resize(smallImg,bigImg1,Size(30,30),0,0,INTER_LINEAR); //双线性插值法
    resize(smallImg,bigImg2,Size(30,30),0,0,INTER_CUBIC); //双三次插值
    namedWindow("smallImg",WINDOW_NORMAL); //图像尺寸太小,一定要设置可以调节窗口大小标志
    imshow("smallImg",smallImg);
    namedWindow("bigImg0",WINDOW_NORMAL);
    imshow("bigImg0",bigImg0);
    namedWindow("bigImg1",WINDOW_NORMAL);
    imshow("bigImg1",bigImg0);
    namedWindow("bigImg2",WINDOW_NORMAL);
    imshow("bigImg2",bigImg0);
    waitKey(0);
    return 0;
}

图像翻转变换flip()

OpenCV4提供了flip()函数用于图像的翻转

flip()函数原型:

void flip(InputArray src,
          OutputArray dst,
          int flipCode
          )
  • src:输入图像
  • dst:输出图像,与src具有相同的大小、数据类型及通道数
  • flipCode:翻转方式标志,数值大于0表示绕y轴进行翻转;数值等于0,表示绕x轴进行翻转;数值小于0,表示绕两个轴翻转

示例:

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
    Mat img = imread("E:\\CLion\\opencv_xin\\SG\\SG_1.jpg");
    if (img.empty()) {
        cout << "Error" << endl;
        return -1;
    }
    Mat img_x,img_y,img_xy;
    flip(img,img_x,0); //以x轴对称
    flip(img,img_y,1); //以y轴对称
    flip(img,img_xy,-1); //先以x轴对称,再以y轴对称
    imshow("img",img);
    imshow("img_x",img_x);
    imshow("img_y",img_y);
    imshow("img_xy",img_xy);
    waitKey(0);
    return 0;
}

results matching ""

    No results matching ""