图像变换
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_CUBIC和INTER_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;
}