我们这边介绍图片金字塔,在OpenCV里是可以用pryUp()和pryDown()分别对图片进行放大或缩小,图片金字塔通常在图片辨识上,将同一图片多次向下取样,籍以产生不同尺度下的多组图片,籍由比对这些图片,让即使遇到不同大小的内容也有好的搜索结果。或是当物体检测时,为了更快的处理速度,首先在顶层的小尺寸进行检索,定位感兴趣的物体,接着在高分辨的低层金字塔进行精确的搜索。
OpenCV有另一个调整图片大小的函数resize(),这两者使用的地方不太一样,如果单纯调整图片输出尺寸,这时候用resize()函数比较合适。
金字塔算法分两种,高斯(Gaussian)和拉普拉斯(Laplacian)金字塔,主要区分在计算不同层的金字塔像素时是用高斯滤波或普拉斯滤波,图片金字塔越上层越小,每上一层就缩小成原本的四分之一,最小为一个像素,以下为金字塔图
OpenCV使用高斯金字塔,來計算上一層影像,計算的方式為:
- 对图片进行高斯滤波后卷积
- 移除偶数的行和列,这时我们可得到上层四分之一的图片
往下一层的计算方式为:
- 行和列都放大2倍,奇數的行和列為原本的值,偶數的行和列值設為零。
- 以同樣的高斯濾波進行卷积,得到所有像素的值。
以下為OpenCV在影像金字塔上,所使用的高斯濾波核心:
void pyrUp(InputArray src, OutputArray dst, const Size& dstsize=Size(), int borderType = BORDER_DEFAULT)
- src 输入图
- dst 输出图,深度会和来源图相同,尺寸会依输入图参数决定
- dstsize 输出图的尺寸,在预定的情况下,输出图的尺寸为: Size((src.cols+1)/2,(src.rows+1)/2).
示例:
#include <opencv2/opencv.hpp>
#include <opencv2/staic3.hpp>
using namespace cv;
int main()
{
Mat src = imread("lena.jpg",CV_LOAD_IMAGE_UCHANGE);
Mat dst1,dst2;
pyrDown(src,dst1,Size(src.cols/2,src.rows/2));
pyrUp(dst1,dst2, Size(dst1.cols*2,dst1.rows*2));
imshow("origin",src);
imshow("pryDown",dst2);
imshow("pryUp", dst3);
waitKey(0);
return 0;
}