OpenCV图像缩放cv::resize各种插值⽅式的⽐较
1. resize函数说明
OpenCV提供了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(ls), round(ws))
其中,fx和fy就是下⾯要说的两个参数,是图像width⽅向和height⽅向的缩放⽐例。
fx:width⽅向的缩放⽐例,如果它是0,那么它就会按照(double)dsize.ls来计算;
fy:height⽅向的缩放⽐例,如果它是0,那么它就会按照(double)dsize.ws来计算;
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插值
使⽤注意事项:
dsize和fx/fy不能同时为0,要么你就指定好dsize的值,让fx和fy空置直接使⽤默认值,就像
resize(img, imgDst, Size(30,30));
要么你就让dsize为0,指定好fx和fy的值,⽐如fx=fy=0.5,那么就相当于把原图两个⽅向缩⼩⼀倍!
OpenCV官⽅说明:注意红⾊⽅框那句话:
To shrink an image, it will generally look best with cv::INTER_AREA interpolation, whereas to enlarge an image,
it will generally look best with cv::INTER_CUBIC (slow) or cv::INTER_LINEAR (faster but still looks OK).
2.各种插值⽅式的⽐较
OpenCV的cv::resize函数⽀持多种插值⽅式,这⾥主要⽐较下⾯四个常⽤的插值⽅式。
2.1 INTER_NEAREST(最近邻插值)
最近邻插值是最简单的插值⽅法,选取离⽬标点最近的点作为新的插⼊点,计算公式表⽰如下:
插值后的边缘效果:由于是以最近的点作为新的插⼊点,因此边缘不会出现缓慢的渐慢过度区域,这也
导致放⼤的图像容易出现锯齿的现象
2.2 INTER_CUBIC  (三次样条插值)
插值后的边缘效果:可以有效避免出现锯齿的现象
2.3 INTER_LINEAR(线性插值)
线性插值是以距离为权重的⼀种插值⽅式。
resize函数c++
插值后的边缘效果:可以有效避免出现锯齿的现象
2.4 INTER_AREA  (区域插值)
区域插值共分三种情况,图像放⼤时类似于双线性插值,图像缩⼩(x轴、y轴同时缩⼩)⼜分两种情况,此情况下可以避免波纹出现。因此对图像进⾏缩⼩时,为了避免出现波纹现象,推荐采⽤区域插值⽅法。
OpenGL说明⽂档有这么解释:To shrink an image, it will generally look best with #INTER_AREA interpolation, whereas to enlarge an image, it will generally look best with #INTER_CUBIC (slow) or #INTER_LINEAR (faster but still looks OK).
如果要缩⼩图像,通常推荐使⽤INTER_AREA插值效果最好,⽽要放⼤图像,通常使⽤INTER_CUBIC(速度较慢,但效果最好),或者使⽤
INTER_LINEAR(速度较快,效果还可以)。
插值后的边缘效果:
测试代码:
1 #include <chrono>
2 #include <opencv2/opencv.hpp>
3#define  millisecond 1000000
4#define DEBUG_PRINT(...)  printf( __VA_ARGS__); printf("\n")
5#define DEBUG_TIME(time_) auto time_ =std::chrono::high_resolution_clock::now()
6#define RUN_TIME(time_)  (double)(time_).count()/millisecond
7using namespace std;
8
9
10int main()
11 {
12string image_path = "D:\\imageEnhance\\hdrnet\\1.jpg";
13    cv::Mat image = cv::imread(image_path);
14    cv::Mat image2X_INTER_NEAREST;
15    cv::Mat image2X_INTER_LINEAR;
16    cv::Mat image2X_INTER_AREA;
17    cv::Mat image2X_INTER_CUBIC;
18double scale = 3.0;
19
20    cv::Mat initMat;
21    cv::resize(image, initMat, cv::Size(), scale, scale, cv::INTER_NEAREST);
22
23
24    DEBUG_PRINT("image size[%d,%d],scale=%3.1f", ls, scale);
25    DEBUG_TIME(T0);
26    cv::resize(image, image2X_INTER_NEAREST, cv::Size(), scale, scale, cv::INTER_NEAREST);//最近邻插值
27    DEBUG_TIME(T1);
28    cv::resize(image, image2X_INTER_LINEAR, cv::Size(), scale, scale, cv::INTER_LINEAR); //线性插值(默认)
29    DEBUG_TIME(T2);
30    cv::resize(image, image2X_INTER_AREA, cv::Size(), scale, scale, cv::INTER_AREA);    //区域插值,图像放⼤时类似于线性插值,图像缩⼩时可以避免波纹出现。
31    DEBUG_TIME(T3);
32    cv::resize(image, image2X_INTER_CUBIC, cv::Size(), scale, scale, cv::INTER_CUBIC);  //三次样条插值
33    DEBUG_TIME(T4);
34
35    DEBUG_PRINT("INTER_NEAREST:%3.3fms", RUN_TIME(T1 - T0));
36    DEBUG_PRINT("INTER_LINEAR :%3.3fms", RUN_TIME(T2 - T1));
37    DEBUG_PRINT("INTER_AREA  :%3.3fms", RUN_TIME(T3 - T2));
38    DEBUG_PRINT("INTER_CUBIC  :%3.3fms", RUN_TIME(T4 - T3));
39
40return0;
41 }
运⾏结果:
image size[2912,4368],scale=3.0
INTER_NEAREST:211.946ms
INTER_LINEAR :510.467ms
INTER_AREA  :541.749ms
INTER_CUBIC  :213.416ms
3. 总结
测试结果表明:
速度⽐较:INTER_NEAREST(最近邻插值)>INTER_CUBIC  (三次样条插值)>INTER_LINEAR(线性插值)>INTER_AREA  (区域插值)
对图像进⾏缩⼩时,为了避免出现波纹现象,推荐采⽤INTER_AREA 区域插值⽅法。
OpenCV推荐:如果要缩⼩图像,通常推荐使⽤#INTER_AREA插值效果最好,⽽要放⼤图像,通常使⽤INTER_CUBIC(速度较慢,但效果最好),或者使⽤INTER_LINEAR(速度较快特殊说明:鄙⼈在测试的时候,发现使⽤INTER_CUBIC⽅法,并不慢啊啊啊,⽐INTER_LINEAR还快!!!!这个就⽐较尴尬了!我猜是OpenCV有对INTER_CUBIC插值⽅法进⾏

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。