在一些情况下,我们需要对图像的大小进行缩放以满足特定的需求。比如在训练一个图像分类的模型时候,深度卷积网络要求网络的输入大小是一致的,所以我们在把图像喂给模型之前要先进行缩放,在opencv中对应的方法是“cv:resize()”。
函数原型:
void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR )
- src 输入图像
- dst 经过缩放后的图像
- dsize 目标图像的大小,opencv中Size()里面是先width后height
- fx, fy 沿x轴和y轴的缩放系数
- interpolation 插值方式,主要有有最近邻、双线性、双三次、基于像素区域关系、兰索斯插值
-
最邻近插值
计算公式
-
双线性插值
计算公式
-
双三次
由相邻的4*4像素计算得出,公式类似于双线性 -
基于像素区域关系
共分三种情况,图像放大时类似于双线性插值,图像缩小(x轴、y轴同时缩小)又分两种情况,此情况下可以避免波纹出现。 -
兰索斯插值
由相邻的8*8像素计算得出,公式类似于双线性
实验
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
int main() {
string path = "./images/src.jpg";
Mat image = imread(path, -1);
int width = image.cols, height = image.rows;
printf("Resize操作前, width: %d height: %d", width, height);
int new_width = 500, new_height = 500;
Mat resized_1 = Mat(Size(new_width, new_height), image.type(), Scalar::all(0));
Mat resized_2 = resized_1.clone(), resized_3 = resized_1.clone(), resized_4 = resized_1.clone(),
resized_5 = resized_1.clone();
//最近邻
resize(image, resized_1, resized_2.size(), 0, 0, 0);
//双线性
resize(image, resized_2, resized_2.size(), 0, 0, 1);
//双三次
resize(image, resized_3, resized_2.size(), 0, 0, 2);
//基于像素区域关系
resize(image, resized_4, resized_2.size(), 0, 0, 3);
//兰索斯插值
resize(image, resized_5, resized_2.size(), 0, 0, 4);
imshow("src", image);
imshow("Resized_1", resized_1);
imshow("Resized_2", resized_2);
imshow("Resized_3", resized_3);
imshow("Resized_4", resized_4);
imshow("Resized_5", resized_5);
waitKey(0);
return 0;
}