天天看點

OpenCV 圖像上采樣和降采樣

文章目錄

  • 相關概念
    • 圖像金字塔
    • 高斯金字塔
      • 高斯金字塔的生成過程
    • 高斯不同(Difference of Gaussian-DOG):
    • 拉普拉斯金字塔
  • 采樣相關API
    • 上采樣(cv::pyrUp) – zoom in 放大
    • 降采樣 (cv::pyrDown) – zoom out 縮小
  • 代碼案例

好了,這次學的又是高大上的詞,遇到問題不要慌,讓我們先一點點的了解一些新的概念。

OpenCV 圖像上采樣和降采樣

相關概念

圖像金字塔

  1. 我們在圖像進行中常常會調整圖像大小,最常見的就是放大(zoom in)和縮小(zoom out),盡管幾何變換也可以實作圖像放大和縮小,但是這裡我們介紹圖像金字塔
  2. 一個圖像金字塔式一系列的圖像組成,最底下一張是圖像尺寸最大,最上方的圖像尺寸最小,從空間上從上向下看就想一個古代的金字塔。

現實中金字塔是這樣的:

OpenCV 圖像上采樣和降采樣

圖像金字塔排列時候是這樣的:

OpenCV 圖像上采樣和降采樣

圖像的金字塔變換我們可以了解為是一種圖像的大小變換,是在保證圖像的特征不變的情況下來進行圖像大小的變換,圖像進行中圖像大小的變換中最常見的就是放大(zoom in)和縮小(zoom out),則對于圖像金字塔來說從上向下變換就是放大,增大分辨率,從下向上變換就是縮小,減小分辨率。

高斯金字塔

高斯金字塔:用來對圖像進行降采樣。

高斯金字塔本質上為信号的多尺度表示法,亦即将同一信号或圖檔多次的進行高斯模糊,并且向下取樣,藉以産生不同尺度下的多組信号或圖檔以進行後續的處理,例如在影像辨識上,可以借由比對不同尺度下的圖檔,以防止要尋找的内容可能在圖檔上有不同的大小。

高斯金字塔的理論基礎為尺度空間理論,而後續也衍生出了多分辨率分析。

OpenCV 圖像上采樣和降采樣

高斯金字塔的相關知識與概念我們可以總結為:高斯金字塔是從底向上,逐層降采樣得到;

降采樣後的圖像是原圖像(像素大小為

X×Y

)的

X/2×Y/2

,也就是對原圖像删除偶數行與列(即得到降采樣之後上一層的圖檔)。

高斯金字塔的生成過程

高斯金字塔的生成過程分為兩部:

  1. 對目前層進行高斯模糊
  2. 對模糊後的圖像删除目前層的偶數行與列,即可得到上一層的圖像,這樣子上一層與下一層圖像相比都隻有他的1/4大小
    OpenCV 圖像上采樣和降采樣

高斯不同(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()函數執行了高斯金字塔建築,首先,它将源圖像與如下核心做

OpenCV 圖像上采樣和降采樣
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;
}