相关概念
图像金字塔
- 我们在图像处理中常常会调整图像大小,最常见的就是放大(zoom in)和缩小(zoom out),尽管几何变换也可以实现图像放大和缩小,但是这里我们介绍图像金字塔
- 一个图像金字塔式一系列的图像组成,最底下一张是图像尺寸最大,最上方的图像尺寸最小,从空间上从上向下看就想一个古代的金字塔。
现实中金字塔是这样的:
图像金字塔排列时候是这样的:
图像的金字塔变换我们可以理解为是一种图像的大小变换,是在保证图像的特征不变的情况下来进行图像大小的变换,图像处理中图像大小的变换中最常见的就是放大(zoom in)和缩小(zoom out),则对于图像金字塔来说从上向下变换就是放大,增大分辨率,从下向上变换就是缩小,减小分辨率。
高斯金字塔
高斯金字塔:用来对图像进行降采样。
高斯金字塔本质上为信号的多尺度表示法,亦即将同一信号或图片多次的进行高斯模糊,并且向下取样,藉以产生不同尺度下的多组信号或图片以进行后续的处理,例如在影像辨识上,可以借由比对不同尺度下的图片,以防止要寻找的内容可能在图片上有不同的大小。
高斯金字塔的理论基础为尺度空间理论,而后续也衍生出了多分辨率分析。
高斯金字塔的相关知识与概念我们可以总结为:高斯金字塔是从底向上,逐层降采样得到;
降采样后的图像是原图像(像素大小为X×Y)的X/2×Y/2,也就是对原图像删除偶数行与列(即得到降采样之后上一层的图片)。
高斯金字塔的生成过程
高斯金字塔的生成过程分为两部:
- 对当前层进行高斯模糊
- 对模糊后的图像删除当前层的偶数行与列,即可得到上一层的图像,这样子上一层与下一层图像相比都只有他的1/4大小
高斯不同(Difference of Gaussian-DOG):
定义:高斯不同就是把同一张图像在不同的参数下做高斯模糊之后的结果相减,得到的输出图像就成为高斯不同(DOG)
高斯不同是图像的内在特征,在灰度图像增强、角点检测中经常用到。
拉普拉斯金字塔
拉普拉斯金字塔:来重建一张图片根据他的上层降采样图片。
采样相关API
上采样(cv::pyrUp) – zoom in 放大
函数原型:
void cv::pyrUp( InputArray _src, OutputArray _dst, const Size& _dsz = SIze(), int borderType = BORDER_DEFAULT )
函数参数:
- src,输入图像,Mat类对象即可;
- dst,输出图像,和源图像有一样的尺寸和类型;
- dstsize,输出图像的大小,有默认值Size(),即默认情况下,由Size(src.cols*2,src.rows*2)来计算,且需要满足以下条件
| dstsize.width-src.cols*2 | <= (dstsize.width mod 2) | dstsize.height-src.rows*2 | <= (dstsize.height mod 2)
- borderType,边界模式。
例如:生成的图像是原图在宽与高各放大两倍
pyrUp(Mat src, Mat dst, Size(src.cols*2, src.rows*2))
另:
pyrUp函数执行高斯金字塔的采样操作,其实也可用拉普拉斯金字塔的,步骤如下:
- 它通过插入可为零的行与列,对源图像进行向上采样操作,
- 将结果与pyrDown()乘以4的内核做卷积。
降采样 (cv::pyrDown) – zoom out 缩小
函数原型为:
CV_EXPORTS_W void pyrDown( InputArray src, OutputArray dst, const Size& dstsize = Size() );
参数为:
- src,输入图像,Mat类对象即可;
- dst,输出图像,和源图像有一样的尺寸和类型;
- dstsize,输出图像的大小,有默认值Size(),即默认情况下,由
Size(src.cols2,src.rows2)来计算,且需要满足以下条件
| dstsize.width2 - src.cols | <= 2
| dstsize.height2 - src.rows | <= 2
- borderType,边界模式。
该pyrDown()函数执行了高斯金字塔建筑,首先,它将源图像与如下内核做
接着,它便通过对图像的偶数行和列做插值来进行向下采样操作。
例如:生成的图像是原图在宽与高各缩小1/2
pyrDown(Mat src, Mat dst, Size(src.cols/2, src.rows/2))
代码案例
#include <iostream> #include <math.h> #include <opencv2/opencv.hpp> #include<opencv2/highgui.hpp> #include <opencv2/highgui/highgui_c.h> using namespace cv; using namespace std; int main() { Mat src, src_up, src_down, src_dog; src = imread("./test2.jpg"); if (src.empty()) { cout << "could not load the image" << endl; return -1; } imshow("orign_image", src); // UP 上采样 pyrUp(src, src_up, Size(src.cols * 2, src.rows * 2)); imshow("UP", src_up); // DOWN 下采样 pyrDown(src, src_down, Size(src.cols / 2, src.rows / 2)); imshow("DOWN", src_down); // DOG 高斯不同 Mat src_gray, g1, g2, dst; cvtColor(src, src_gray, CV_BGR2GRAY); GaussianBlur(src_gray, g1, Size(7, 7), 0, 0); GaussianBlur(g1, g2, Size(7, 7), 0, 0); subtract(g1, g2, dst, Mat()); normalize(dst, dst, 255, 0, NORM_MINMAX); imshow("DOG", dst); waitKey(0); destroyAllWindows(); return 0; }