1,resize函数最为直接
2,pyrDown和pyrUp函数,即为图像金字塔相关的两个函数,对图像进行向上向下采样操作
一、前言
图像金字塔最初用于机器视觉和图像压缩,一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图像集合。其通过梯次向下采样获得,直到达到某个终止条件才停止采样。
金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率的近似。
我们将一层一层的图像比喻成金字塔,层级越高,则图像越小,分辨率越低。
当图像向金字塔的上层移动时,尺寸和分辨率就降低。OpenCV中,从金字塔中上一级图像生成下一级图像的可以用PryDown。而通过PryUp将现有的图像在每个维度都放大两遍。
图像金字塔中的向上和向下采样分别通过OpenCV函数 pyrUp 和 pyrDown 实现。
概括起来就是:
对图像向上采样:pyrUp函数(放大图像)
对图像向下采样:pyrDown函数(缩小图像)
这里的向下与向上采样,是对图像的尺寸而言的(和金字塔的方向相反),向上就是图像尺寸加倍,向下就是图像尺寸减半。而如果我们按上图中演示的金字塔方向来理解,金字塔向上图像其实在缩小,这样刚好是反过来了。
二、pyrDown函数
void pyrDown( InputArray src, OutputArray dst,const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );
下面是源码中对各个参数的解释:
@param src input image.
@param dst output image. It has the specified size and the same type as src .
@param dstsize size of the output image.
默认情况下,输出图像的大小计算为Size((src.cols + 1)/ 2,(src.rows + 1)/ 2),在任何情况下都应该满足
|dstsize.width * 2 - src.cols | <2
|dstsize.height * 2 - src.rows| < 2
@param borderType Pixel extrapolation method, see cv::BorderTypes (only BORDER_DEFAULT is supported)
注意这个地方是仅仅支持BORDER_DEFAULT ,所以这个地方填默认即可
对于大小为w×h的图像I,高斯金字塔Gj 由I的几个分辨率减小的高斯图像Ii(i是下标,下同) 组成。
其中,i={0,1,...,j}代表金字塔的级数。 图像Ii 的大小为(w/2i)×(h/2i)。[2i表示2的i次方]
图像Ii 由两步得到。1,高斯平滑处理;用高斯函数生成的核进行滤波;
2,下采样;对前一级图像进行隔行隔列采样得到;
该函数执行高斯金字塔结构的下采样步骤。
首先,它将源图像与内核进行卷积:
\ f [\ frac {1} {256} \ begin {bmatrix} 1&4&6&4&1 \\ 4&16&24&16&4 \\ 6&24&36&24&6 \\ 4 &16&24&16&4 \\ 1&4&6&4&1 \ end {bmatrix} \ f]然后,它通过拒绝偶数行和列来对图像进行降采样。
三、pyrUp函数
void pyrUp( InputArray src, OutputArray dst,const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );
默认情况下,输出图像的大小计算为大小(src.cols \ * 2,(src.rows \ * 2)
该函数执行高斯金字塔结构的上采样步骤,实际上被用来构建拉普拉斯金字塔。
首先,它通过上采样源图像,偶数行、列注入零,然后将结果与的内核进行卷积,该内核是pyrDown使用的内核乘以4而来。
四、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插值
所以,要把一个图像的长宽同步缩小一半,有以下两种写法:
resize(dst, dst1, Size(dst.cols * 0.5, dst.rows * 0.5),0, 0, INTER_LINEAR);
resize(dst, dst2, Size(0,0), 0.5, 0.5, INTER_LINEAR);
要缩小图像,通常用CV_INTER_AREA插值看起来最好,而对于放大图像时,CV_INTER_CUBIC(速度慢)或CV_INTER_LINEAR(更快,看起来也还不错)。五、实例
resize(tempImage, g_dstImage1, Size(tempImage.cols / 2, tempImage.rows / 2), 0, 0, INTER_AREA);
resize(tempImage, g_dstImage2, Size(tempImage.cols * 2, tempImage.rows * 2), 0, 0, INTER_LINEAR);
pyrUp(tempImage, g_dstImage3, Size(tempImage.cols * 2, tempImage.rows * 2));
pyrDown(tempImage, g_dstImage4, Size(tempImage.cols / 2, tempImage.rows / 2));
imshow("【效果图一resize缩小】", g_dstImage1);
imshow("【效果图二resize放大】", g_dstImage2);
imshow("【效果图一向上采样】", g_dstImage3);
imshow("【效果图二向下采样】", g_dstImage4);
参考文献:
https://blog.youkuaiyun.com/oliverkingli/article/details/54311091
https://blog.youkuaiyun.com/woainishifu/article/details/53260546