影像金字塔(pryUp、pryDown)

我們這邊介紹影像金字塔,在OpenCV裡是可用pryUp()和pryDown(),分別對影像放大或縮小,影像金字塔通常在影像辨識上,將同一圖片多次的向下取樣, 藉以產生不同尺度下的多組圖片,藉由比對這些圖片,讓即使遇到不同大小的內容,也有好的搜尋結果。或者當物體檢測時,為了更快的處理速度,首先在頂層的小尺寸進行檢索,定位感興趣的物體,接著在高分辨的低層金字塔,進行更精確的搜索。

OpenCV有另一個調整影像大小的resize()函式,這兩者使用的地方不太一樣,如果單純調整影像輸出尺寸,這時使用resize()函式比較合適。

影像金字塔依算法分兩種,高斯(Gaussian)和拉普拉斯(Laplacian)金字塔,主要區分在計算不同層的金字塔像素值時,是用高斯濾波或拉普拉斯濾波,影像金字塔越上層越小,每上一層就縮小成原本的四分之一,最小為一個像素,以下為金字塔圖。

影像金字塔

OpenCV使用高斯金字塔,來計算上一層影像,計算的方式為:

  1. 對當層影像使用高斯濾波對影像進行迴旋(convolve)。
  2. 移除偶數的行和列,這時我們可得到上層四分之一大小的影像。

往下一層計算的方式為:

  1. 行和列都放大2倍,奇數的行和列為原本的值,偶數的行和列值設為零。
  2. 以同樣的高斯濾波進行迴旋,得到所有像素的值。

以下為OpenCV在影像金字塔上,所使用的高斯濾波核心:

影像金字塔

OpenCV金字塔放大

void pyrUp(InputArray src, OutputArray dst, const Size& dstsize=Size(), int borderType=BORDER_DEFAULT)

  • src:來源圖。
  • dst:輸出圖,深度會和來源圖相同,尺寸會依輸入參數決定。
  • dstsize:輸出圖的尺寸,在預設的情況之下,輸出圖的行和列都是輸入圖的2倍。

OpenCV金字塔縮小

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;
}

金字塔

金字塔

金字塔

回到首頁

回到OpenCV教學


參考資料:

OpenCV 教程