天天看點

【opencv學習筆記】014之上采樣與降采樣

目錄

​​一、前言​​

​​二、圖像金字塔​​

​​1、聊個題外話​​

​​2、圖像金字塔​​

​​3、上采樣與降采樣​​

​​1.高斯金字塔​​

​​2.高斯不同​​

​​3.拉普拉斯金字塔​​

​​4.API​​

​​5.代碼展示​​

​​6.執行結果​​

​​7.先降采樣再上采樣​​

​​8.執行結果​​

一、前言

繼續填坑。

如果想看其他有關于OpenCV學習方法介紹、學習教程、代碼實戰、常見報錯及解決方案等相關内容,可以直接看我的OpenCV分類:

二、圖像金字塔

1、聊個題外話

大家對金字塔的印象是什麼。

歡迎大家評論。對于我來說,金字塔的印象:

【opencv學習筆記】014之上采樣與降采樣

迪迦出現的地方

【opencv學習筆記】014之上采樣與降采樣

法老的陵墓

2、圖像金字塔

不管是那種金字塔,說白了都是四棱錐,大家看下圖:

這個也可以看做金字塔,如果我們把一個小方格當成一個二值圖像的像素,那麼我們可以從最底層變到最高層,也可以從最高層變到最底層。那如果這是一個圖像的話,從上往下,我們就實作了圖像的放大,從下往上就實作了圖像的縮小。

是以在圖像中,我們可以利用這樣的四棱錐進行進行圖像的縮放,我們将這個四棱錐稱之為:圖像金字塔。

而圖像的放大與縮小分别稱之為上采樣和降采樣或下采樣。

3、上采樣與降采樣

通過上面,我們知道,

上采樣就是放大圖像,通過放大圖像,我們可以增加圖像的像素,進而可以得到更高的分辨率。

降采樣就是縮小圖像,通過縮小圖像,我們可以減少圖像的像素,一方面,我們可以生成對應圖像的縮略圖,另一方面,我們可以減少圖像的大小,節約記憶體。

但是我們通過上采樣的得到的圖,和經過縮小的圖像的原圖還是有差別的,因為我們很難真正獲得圖像的原始位置的像素,是以通過上采樣得到的圖,可能會看着不是那麼清晰,那麼流暢,圖像品質不是那麼的好。

接下來我們着重講兩個圖像金字塔:高斯金字塔和拉普拉斯金字塔。

1.高斯金字塔

高斯金字塔是從底向上,用于對圖像進行降采樣。高斯金字塔對原圖像删除偶數行與列,即得到降采樣之後上一層的圖檔。是以經過一次高斯金字塔,圖像的行列變為原來的1/2 。

具體的步驟分為兩步:

1.進行高斯模糊

2.删除目前層的偶數行與列。

2.高斯不同

把同一張圖像在不同的參數下做高斯模糊之後的結果相減,得到的輸出圖像。稱為高斯不同(Difference of Gaussian-DOG)。

高斯不同是圖像的内在特征,在灰階圖像增強、角點檢測中經常用到。

3.拉普拉斯金字塔

拉普拉斯金字塔很高斯金字塔不同,是用其上層的圖像,獲得其下層的圖像,比如我們可以通過高斯金字塔進行圖像的降采樣,然後我們可以使用拉普拉斯金字塔進行圖像的上采樣。

4.API

圖像的上采樣API如下:

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

函數參數含義如下:

(1)InputArray類型的src ,輸入圖像。

(2)OutputArray類型的dst ,輸出圖像,圖像的大小是規定的(根據參數3)和輸入圖像有相同的類型。

(3)Size類型的指針dstsize ,設定的輸出圖像大小。

(4)int類型的borderType ,像素外推方法,請參見cv::BorderTypes(僅支援BORDER_DEFAULT)。

圖像的降采樣API如下:

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

函數參數含義如下:

(1)InputArray類型的src ,輸入圖像。

(2)OutputArray類型的dst ,輸出圖像,圖像的大小是規定的(根據參數3)和輸入圖像有相同的類型。

(3)Size類型的指針dstsize ,設定的輸出圖像大小。

(4)int類型的borderType ,像素外推方法,請參見cv::BorderTypes(僅支援BORDER_DEFAULT)。

上采樣函數和降采樣函數的圖像一般在使用過程中,我們隻設定前三個參數。

5.代碼展示

講完API,我們看一個具體的例子。

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
  Mat img, src;
  img = imread("E:/image/girl3.png");
  if (!img.data)
  {
    cout << "could not load image !";
    return -1;
  }
  imshow("show img", img);
  pyrUp(img, src, Size(img.cols * 2, img.rows * 2));
  imshow("output up image", src);
  pyrDown(img, src, Size(img.cols/2, img.rows/2));
  imshow("output down image", src);

  waitKey(0);
  return 0;
}      

6.執行結果

【opencv學習筆記】014之上采樣與降采樣

原圖

【opencv學習筆記】014之上采樣與降采樣

降采樣後的圖像

【opencv學習筆記】014之上采樣與降采樣

上采樣後的圖像

我們發現,通過上采樣的圖像,除了尺寸變大,還變得模糊了。那我們可以嘗試一下,先通過降采樣,再進行上采樣會如何呢?

7.先降采樣再上采樣

講完API,我們看一個具體的例子。

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
  Mat img;
  img = imread("E:/image/girl3.png");
  if (!img.data)
  {
    cout << "could not load image !";
    return -1;
  }
  imshow("show img", img);
  
        pyrDown(img, img, Size(img.cols / 2, img.rows / 2));
  pyrUp(img, img, Size(img.cols * 2, img.rows * 2));
  imshow("output down image", img);

  waitKey(0);
  return 0;
}      

8.執行結果

【opencv學習筆記】014之上采樣與降采樣

原圖

【opencv學習筆記】014之上采樣與降采樣

先降采樣再上采樣