我們這邊介紹影像金字塔,在OpenCV裡是可用pryUp()和pryDown(),分別對影像放大或縮小,影像金字塔通常在影像辨識上,將同一圖片多次的向下取樣, 藉以產生不同尺度下的多組圖片,藉由比對這些圖片,讓即使遇到不同大小的內容,也有好的搜尋結果。或者當物體檢測時,為了更快的處理速度,首先在頂層的小尺寸進行檢索,定位感興趣的物體,接著在高分辨的低層金字塔,進行更精確的搜索。
OpenCV有另一個調整影像大小的resize()函式,這兩者使用的地方不太一樣,如果單純調整影像輸出尺寸,這時使用resize()函式比較合適。
影像金字塔依算法分兩種,高斯(Gaussian)和拉普拉斯(Laplacian)金字塔,主要區分在計算不同層的金字塔像素值時,是用高斯濾波或拉普拉斯濾波,影像金字塔越上層越小,每上一層就縮小成原本的四分之一,最小為一個像素,以下為金字塔圖。
OpenCV使用高斯金字塔,來計算上一層影像,計算的方式為:
對當層影像使用高斯濾波對影像進行迴旋(convolve)。 移除偶數的行和列,這時我們可得到上層四分之一大小的影像。往下一層計算的方式為:
行和列都放大2倍,奇數的行和列為原本的值,偶數的行和列值設為零。 以同樣的高斯濾波進行迴旋,得到所有像素的值。以下為OpenCV在影像金字塔上,所使用的高斯濾波核心:
void pyrUp(InputArray src, OutputArray dst, const Size& dstsize=Size(), int borderType=BORDER_DEFAULT)
src:來源圖。dst:輸出圖,深度會和來源圖相同,尺寸會依輸入參數決定。dstsize:輸出圖的尺寸,在預設的情況之下,輸出圖的行和列都是輸入圖的2倍。void pyrDown(InputArray src, OutputArray dst, const Size& dstsize=Size(), int borderType=BORDER_DEFAULT)
src:來源圖。dst:輸出圖,深度會和來源圖相同,尺寸會依輸入參數決定。dstsize:輸出圖的尺寸,在預設的情況之下,輸出圖的尺寸為:Size((src.cols+1)/2, (src.rows+1)/2)。以下示範pyrDown()和pyrUp()的使用,當我們縮小影像時會遺失部分的解析度,所以當我們再將影像放大時,會不如原圖清晰:
#include <cstdio> #include <opencv2/opencv.hpp> using namespace cv; int main(){ Mat src = imread("lena.jpg"); Mat dst1; Mat 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("pyrDown", dst1); imshow("pyrUp", dst2); waitKey(0); return 0; }转自:http://monkeycoding.com/?p=589