一、金字塔定义与分类
具有不同尺寸的大小的一组图像,我们称之为金字塔图像,我们把最大的放在底部,最小的放到最上面。有两种采样方式,一是向下采样,层级越高,图像越小,分辨率也越低,图像分辨率不断降低的过程称为向下取样
第二种是 向上采样,与向下采样相反
金字塔的分类:高斯金字塔(最主要的金字塔-向下采样)和拉普拉斯金字塔(从金字塔底层开始向上采样重建一个图像)
二、高斯金字塔
原理:首先将原图像作为对底层的图像(当成上图的level0),也就是金字塔中的第0层,然后在利用高斯模糊对图像进行平滑处理(卷积-卷积核是5*5的),然后再去掉偶数行和偶数列得到了上一层的图像,也就是level1。
opencv 官方推荐的卷积核如下:
总结一下采样的过程
(1)、对图像Image1进行高斯模糊,(2),删除偶数行和偶数列。高斯模糊的过程在第三节中已经详细讲过了,这里不多做赘述。
向下采样:
pyrDown( )函数的作用是向下采样并模糊一张图片,说白了就是缩小一张图片。
void pyrDown(
InputArray src,//输入图像,即源图像
OutputArray dst, //输出图像和源图片有一样的尺寸和类型。
const Size& dstsize=Size(), //输出图像的大小;有默认值Size(),即默认情况下,由Size Size((src.cols+1)/2, (src.rows+1)/2)来进行计算
int borderType=BORDER_DEFAULT)
单次采样如下:
多次采样:
代码显示:
int main(int args, char* arg)
{
Mat src, dest1, dest2, dest3, dest4;
// point
src = imread("C:\\Users\\19473\\Desktop\\opencv_images\\88.jpg");
if (!src.data)
{
printf("could not load image....\n");
}
imshow("原图", src);
pyrDown(src, dest1, Size(src.cols / 2, src.rows / 2));
pyrDown(dest1, dest2);
pyrDown(dest2, dest3);
imshow("下采样", dest1);
imshow("pyrDown2", dest2);
imshow("pyrDown3", dest3);
waitKey(0);
destroyAllWindows();
return 0;
}
向上采样:
向上采样是图像不断方法的过程,他是将两个方向上都放大为原来的2倍,新增的行和列都用0来填充,并使用于向下采样相同的卷积核乘以4,在与放大后的图像进行卷积运算以获得新增像素(之前填充为0 的新增行列的元素)的新增。如下所示,它在原始像素45, 123, 89, 149之间各新增了一行和一列值为0的像素。
注意:不管是向上还是向下采样都是无法互逆的,都是无法得到原始的图像的
算子解释:
pyrUp( )函数的作用是向上采样并模糊一张图像,说白了就是放大一张图片。
void pyrUp(
InputArray src, 输入图像
OutputArraydst, 输出图像,和源图片有一样的尺寸和类型
const Size& dstsize=Size(), 输出图像的大小;有默认值Size(),即默认情况下,由Size(src.cols*2,src.rows*2)来进行计算
int borderType=BORDER_DEFAULT )
先下再上采样结果和原图对比:
pyrUp(src, dst1, Size(src.cols * 2, src.rows * 2));
pyrUp(dst1, dst2);
imshow("上采样", dst1);
imshow("pyrUp2", dst2);
pyrDown(src, dest1);
pyrUp(dest1, dst1);
imshow("先下后上采样", dst1);
三、拉普拉斯金字塔--边缘图
拉普拉斯金字塔是对高斯金字塔的修正,主要用途是图像的融合,可以得到原图。拉普拉斯金字塔第i层的数学定义如下:
Li就是得到的残差图。从上式我们也可以理解为拉普拉斯金字塔是通过源图像-先缩小后放大的图得到的残差
// 拉普拉斯金字塔
Mat sub_image;
subtract(src, dst1, sub_image, Mat());
// 由于得到的sub_image 不很理想,所以我们可以用一个方法来显示的更加明显一些
// 归一化显示
normalize(sub_image, sub_image, 255, 0, NORM_MINMAX);
imshow("拉普拉斯金字塔图像", sub_image);
waitKey(0);
destroyAllWindows();
四、resize()函数
resize()调整图片(RGB)的大小,改变图片尺寸。
void resize(InputArray src,输入图像
OutputArray dst,输出图像
Size dsize, 输出图像的大小;若dsize=0,则dsize=Size(round(fx*src.cols),round(fy*src.rows))
double fx=0, 沿水平轴的缩放系数 fx=0,fx=double(dsize.width/src.cols)
double fy=0, 沿垂直轴的缩放系数 fy=0,fy=double(dsize.hight/src.rows)
int interpolation=INTER_LINEAR 用于指定插值方式,默认为INTER_LINEAR(线性插值)。
可选的插值方式如下:
INTER_NEAREST - 最近邻插值
INTER_LINEAR - 线性插值(默认值)
INTER_AREA - 区域插值(利用像素区域关系的重采样插值)
INTER_CUBIC –三次样条插值(超过4×4像素邻域内的双三次插值)
INTER_LANCZOS4 -Lanczos插值(超过8×8像素邻域的Lanczos插值)
几种常用方法的效率为:最邻近插值>双线性插值>双立方插值>Lanczos插值
)