OpenCV3.0中的图像金字塔与图片尺寸缩放
生活随笔
收集整理的這篇文章主要介紹了
OpenCV3.0中的图像金字塔与图片尺寸缩放
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? ? ? ? 圖像金字塔是圖像中多尺度表達的一種,最主要用于圖像分割,是一種以多分辨率來解釋圖像的有效但概念簡單的結構。一幅圖像的金字塔式一系列以金字塔形狀排列的,分辨率逐步降低且來源于同一張原始圖的圖像集合。其通過梯次向下采樣獲得,直到到達某個終止條件才停止采樣。金字塔的底部是待處理圖像的高分辨率表示,而頂部是低分辨率的近似。層級越高圖像越小,分辨率越低。
? ? ? ? ? ?通常有兩種類型的圖像金字塔,分別是:
- ? ? 數字金字塔(Gaussuan pyramin)-用來向下采樣,主要的圖像金字塔,主要用來向下采樣圖像
- 拉普拉斯金字塔(Laplaican pyramid)-用來從金字塔底層圖像重建上層未采樣的還原,在數字圖像處理中也即是預測殘差,可以對圖像進行最大程度的還原,配合高斯金字塔一起使用,是從金字塔底層圖像中向上采樣,重建一個圖像。
? ? ? ?當圖像金字塔的上層移動時,尺寸和分辨率會降低。在OpenCV中,從金字塔上一層圖像生成下一級圖像時可以使用PryDown,而通過PryUp將現有的圖像在每個維度上放大兩倍。
?注意:PryDown和PryUp函數互逆的,PryUp不是降采樣的逆操作。圖像首先在每個維度上擴大為原來的兩倍,新增的行(偶數行)以0填充,然后給指定的濾波器進行卷積(實際上是在每個維度都擴大為原來兩倍的過濾器)去估計“丟失”像素的近似值。
1.高斯金字塔
? ? 高斯金字塔是通過高斯平滑和亞采樣獲得一些采樣圖像,即是第K層高斯金字塔通過平滑、亞采樣就可以獲得第K+1層高斯圖像。高斯金字塔包括一些列的低通濾波器,其截止頻率從上一層到下一層以因子2逐漸增加,所以高斯金字塔可以跨越很大的頻率范圍。 ? ? ?a.對圖像向下采樣 ? ? 為了獲得第G(i+1)的金字塔圖像,采取如下方法: ? ? ? ? ?(1)對圖像G(i)進行高斯內核卷積 ? ? ? ? ?(2)將所有偶數列和偶數行去除 ? 得到的圖像即為G(i+1)的圖像,很明顯G(i+1)只有源圖像的四分之一,通過對輸入圖像G(i)(原始圖像)不停的迭代上述步驟就會得到整個金字塔,即向下采樣會丟失圖像的信息,縮小了圖像 ? ? ?b.對圖像的向上采樣 如果想放大圖像,則需要通過向上取樣操作得到 ? ? ? ?(1)將圖像在每個方向上擴大為原來的兩倍,新增的行和列以0填充 ? ? ? ?(2)使用先前同樣的內核(乘以4)與放大后的圖像卷積,獲得“新增像素”的近似值。 得到的圖像即為放大后的圖像,但是與源圖像想必會發現比較模糊,因為在縮放中已經丟失了一些信息。如果想在縮放過程中減少信息的丟失,這些數據就形成了拉普拉斯金字塔。
2.拉普拉斯金字塔
? 第i層的拉普拉斯金字塔的數學定義為: ? ? ? ? ? ? ? ? ? ?L(i) = G(i) -UP(G(i+1))&g 式中的G(i)表示第i層的圖像,UP()操作是將源圖像中位置為(x,y)的像素映射到目標圖像的(2X+1,2Y+1)位置,即在進行向上取樣,&表示卷積,g為5*5的高斯內核. 使用OpenCV中函數直接進行拉普拉斯運算:?L(i) = G(i) -PryUP(G(i+1))
圖像金字塔的一個重要應用就是圖像分割
3.尺寸調整:resize()函數 ? ? ?resize()函數是OpenCV中專門用來調整圖像大小的函數 ? ? ?此函數將源圖像精確的轉換為指定尺寸的目標圖像。如果源圖像中設置了ROI(Region Of Internet,感興趣區域),那么resize()函數會對源圖像的ROI區域進行調整圖像尺寸的操作,來輸出到目標圖像中。若目標中已經設置了ROI區域,不難理解resize()函數將會對源圖像進行尺寸調整并填充到目標圖像的ROI中。
C++:void resize(InputArray src,OutputArray dst,Size dsize,double fx = 0,double fy = 0,int interpolation = INTER_LINEAR) 很多時候不用考慮第二個參數dst的初始圖像尺寸和類型(即直接定義一個Mat類型的對象,不用對其初始化),因為其尺寸和類型可以由src,dsize,fx,fy這幾個參數來確定。 參數一:輸入圖像,即源圖像 參數二:輸出圖像,當其非零時,有著dsize的尺寸,或者由src.size()計算出來 參數三:輸出圖像的大小,如果為0,由下式計算 ? ? ? ? ? ? ? ? ?dsize = Size(round(fx*src.cols),round(fy*src.rows)) ? ? ? ? ? ? 其中dsize,fx,fy都不能為0 參數四:沿水平軸的縮放系數,有默認值0,當其不為0時,由下式進行計算: ? ? ? ? ? ? ? ? (double)dsize.width/src.cols 參數五:沿垂直軸的縮放系數,有默認值0,當其不為0時,由下式進行計算: ? ? ? ? ? ? ? ??(double)dsize.height/src.rows 參數六:用于指定插值模式,默認為INTER_LINEAR ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
若要縮小圖像,推薦使用CV_INTER_AREA來插值,若要放大圖像,推薦使用CV_INTER_CUBIC(效率不高)或者CV_INTER_LINEAR(效率高)
resize()函數調用示例:
// resize.cpp : 定義控制臺應用程序的入口點。 //#include "stdafx.h" #include <opencv2/opencv.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace cv;int _tmain(int argc, _TCHAR* argv[]) {//載入源圖像Mat srcImage = imread("1.jpg");Mat tempImage,dstImage1,dstImage2;//臨時變量和目標圖的定義tempImage = srcImage;//將原始圖復制臨時變量imshow("[源圖像]",srcImage);//進行尺寸調整resize(tempImage,dstImage1,Size(tempImage.cols/2,tempImage.rows/2),(0,0),(0,0),3);resize(tempImage,dstImage2,Size(tempImage.cols*2,tempImage.rows*2),(0,0),(0,0),3);imshow("[效果圖一]",dstImage1);imshow("[效果圖二]",dstImage2);waitKey(0);return 0; } 如下圖所示:
4.向上采樣:PryUp()函數
? ? ?PryUp()函數的作用是向上采樣并模糊一張圖像,說白了就是放大一張圖片
C++:void pyrUp(InputArray src,OutputArray dst,const Size& dstsize = Size(),int borderType = BORDER_DEFAULT) 參數二:輸出圖像,和輸入圖像有一樣的尺寸和類型 參數三:輸出圖像的大小,有默認值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) 參數四:邊界模式,一般不用理睬
首先通過插入為零的行和列,對源圖像進行向上采樣操作,然后將結果與pyrDown()乘以4的內核做卷積,示例如下: // pyrUp.cpp : 定義控制臺應用程序的入口點。 //#include "stdafx.h" #include <opencv2/opencv.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace cv;int _tmain(int argc, _TCHAR* argv[]) {//載入圖像Mat srcImage = imread("1.jpg");Mat tmpImage,dstImage;tmpImage = srcImage;imshow("[源圖像]",srcImage);pyrUp(tmpImage,dstImage,Size(tmpImage.cols*2,tmpImage.rows*2));imshow("[效果圖]",dstImage);waitKey(0);return 0; }
5.向下采樣:pyrDown()函數 ? pyrDown()函數的作用是向下采樣并模糊一張照片,就是縮小一張圖片
C++:void ?pyrDown(InputArray src,OutputArray dst,const Size&dstsize = Size(),int borderType ?= BORDER_DEFAULT) 參數二:輸出圖像,尺寸和類型和源圖像一致 參數三:輸出圖像的大小,有默認值Size(),即默認情況下,由Size Size((src.cols+1)/2,(src.rows+1)/2)來進行計算,且一直需要滿足下列條件: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|dstsize.width*2 - src.cols| <= 2 ? ? ? ? ? ? ? ? ? ? ? ? ?|dstsize.height?*2- src.rows| <= 2 該pryDown函數執行了高斯金字塔建造的向下采樣的步驟,首先將源圖像與如下內核做卷積:
接著通過對偶數行和偶數列做插值來進行向下采樣操作,示例如下: // pyrUp.cpp : 定義控制臺應用程序的入口點。 //#include "stdafx.h" #include <opencv2/opencv.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace cv;int _tmain(int argc, _TCHAR* argv[]) {//載入圖像Mat srcImage = imread("1.jpg");Mat tmpImage,dstImage;tmpImage = srcImage;imshow("[源圖像]",srcImage);//pyrUp(tmpImage,dstImage,Size(tmpImage.cols*2,tmpImage.rows*2));pyrDown(tmpImage,dstImage,Size(tmpImage.cols/2,tmpImage.rows/2));imshow("[效果圖]",dstImage);waitKey(0);return 0; }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
總結
以上是生活随笔為你收集整理的OpenCV3.0中的图像金字塔与图片尺寸缩放的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV3.0中的离散傅里叶变换
- 下一篇: OpenCV中阈值操作