opencv —— resize、pyrUp 和 pyrDown 图像金字塔(高斯金字塔、拉普拉斯金字塔)与尺寸缩放(向上采样、向下采样)
我們經(jīng)常會將某種尺寸的圖像轉(zhuǎn)化為其他尺寸的圖像,如果需要放大或者縮小圖像的尺寸,在 OpenCV 中可以使用如下兩種方法:
resize 函數(shù),最直接的方法。
pyrUp 和pyrDown 函數(shù),即圖像金字塔相關(guān)的兩個函數(shù),對圖像進行向上采樣和向下采樣的操作。
pyrUp 和pyrDown 其實和專門用于放大縮小圖像尺寸的 resize 在功能上差不多,批著圖像金字塔的皮,說白了還是對圖像進行放大和縮小操作。
圖像金字塔
一幅圖像的金字塔是一系列以金字塔形狀排列,分辨率逐漸降低且源于同一張原始圖的圖像集合。金字塔的底部是待處理圖像的高分辨率表示,而頂部是低分辨率的近似。層級越高,圖像越小,分辨率越低。
圖像金字塔是圖像中多尺度表達的一種,最初用于機器視覺和圖像壓縮,最主要功能用于圖像分割,是一種以多分辨率來解釋圖像的有效但概念簡單的結(jié)構(gòu)。
向上、向下采樣
圖像金字塔中的向上和向下采樣分別通過pyrUp 和pyrDown實現(xiàn)。這里的向上向下采樣,是針對圖像的尺寸而言的(和金字塔的方向相反),向上就是圖像尺寸加倍,向下就是圖像尺寸減半。但需要注意的是,pyrUp 和pyrDown不是互逆的。
對于pyrUp,圖像首先在每個維度上擴大為原來的兩倍,新增的行和列(偶數(shù)行和列)以 0 填充。然后用指定的濾波器進行卷積(實際上是一個在每個維度上都擴大為原來兩倍的過濾器)去估計”丟失“像素的近似值。
對于pyrDown,我們先要用高斯核對圖像進行卷積,然后刪除所有偶數(shù)行和偶數(shù)列,新的到的圖像面積就會變成源圖像的四分之一。
高斯金字塔
高斯金字塔是通過高斯平滑和亞采樣獲得的一系列采樣圖像。
向下采樣方法:① 對圖像進行高斯內(nèi)核卷積;② 將所有偶數(shù)行和列去除。
向上采樣方法:① 將圖像在每個方向上擴大為原來的兩倍,新增的行和列以 0 填充;② 使用原先同樣的內(nèi)核(乘以 4)與放大后的圖像卷積,獲得”新增像素“的近似值。在縮放過程中已經(jīng)丟失了一些信息,如果想在縮放過程中減少信息的丟失,就需要用到拉普拉斯金字塔。
拉普拉斯金字塔
拉普拉斯金字塔是通過源圖像減去先縮小再放大的圖像的一系列圖像構(gòu)成。
數(shù)學定義:Li = Gi — pryUp( Gi+1)g5×5
尺寸調(diào)整:resize 函數(shù)
此函數(shù)將源圖像精確地轉(zhuǎn)換為指定尺寸地目標圖像。如果源圖像中設(shè)置了 ROI(感興趣區(qū)域),那么 resize() 函數(shù)就會對源圖像地 ROI 區(qū)域進行調(diào)整尺寸操作,來輸出到目標圖像中。若目標圖像中已經(jīng)設(shè)置了 ROI 區(qū)域,不難理解 resize() 函數(shù)將會對源圖像進行尺寸調(diào)整并填充到目標圖像的 ROI 區(qū)域中去。
void resize(InputArray src, OutputArray dst, Size dsize, double fx = 0, double fy = 0, int interpolation = INTER_LINEAR);
src,輸入圖像,Mat 類對象即可。
dst,輸出圖像,若其非零時,有著 dsize 的尺寸,或者由 src.size() 計算出來。
dsize,輸出圖像的尺寸。如果它等于零,由如下公式進行計算:
dsize = Size ( round ( fx * src.cols ), round( fy * src.rows ) );
fx,延水平軸的縮放系數(shù),有默認值 0,且為 0 時,由下式進行計算:
fx = (double) dsize.width / src.cols
fy,延垂直軸的縮放系數(shù),有默認值 0,為 0 時,由下式進行計算:
fy = (double) dsize.height / src.rows
interpolation,指定插值方式,默認為INTER_LINEAR (線性插值)。插值就是根據(jù)已知數(shù)據(jù)點(條件),來預(yù)測未知數(shù)據(jù)點值得方法。在尺寸調(diào)整過程中,圖像的大小可能發(fā)生改變。此時像素與像素之間的關(guān)系就不是一一對應(yīng)關(guān)系,因此在尺寸調(diào)整過程中,可能會涉及到像素值的插值計算。可選插值方式如下:
INTER_NEAREST(最近鄰差值)
INTER_LINEAR(線性插值,默認)
INTER_AREA(區(qū)域插值,利用像素區(qū)域關(guān)系的重采樣插值)
INTER_CUBIC(三次樣條插值,超過 4×4 像素鄰域內(nèi)的雙三次插值)
INTER_LANCZOS4(Lanczos 插值,超過 8×8 像素鄰域的 Lanczos 插值)
若要縮小圖像,一般情況下最好用INTER_AREA 來插值;若要放大圖像,一般情況下用INTER_LINEAR。
代碼示例:
#include <opencv.hpp>
using namespace cv;
int main() {
Mat src = imread("C:/Users/齊明洋/Desktop/證件照/7.jpg");
imshow("src", src);
//方法一
Mat dst1 = Mat(200, 300, CV_8UC3);
resize(src, dst1, dst1.size());
imshow("dst1", dst1);
//方法二
Mat dst2;
resize(src, dst2, Size(), 0.5, 0.5);
imshow("dst2", dst2);
waitKey(0);
}
效果演示:
向上采樣:pyrUp 函數(shù)
pyrUp 函數(shù)的作用是向上采樣并模糊一張圖像,說白了就是放大一張圖片。
void pyrUp(InputArray src, OutputArray dst, const Size& dstsize = Size(), int borderType= BORDER_DEFAULT);
src,輸入圖像,即源圖像,Mat 類的對象即可。
dst,輸出圖像。
dstsize,輸出圖像的大小,有默認值 Size(),默認情況下,由 Size(src.cols * 2, src.rows * 2) 來進行計算
borderType,邊界擴展的方式,一般不考慮,選擇默認值。
向下采樣:pyrDown 函數(shù)
pyrDown函數(shù)的作用是向下采樣并模糊一張圖像,說白了就是縮小一張圖片。
void pyrDown(InputArray src, OutputArray dst, const Size& dstsize = Size(), int borderType= BORDER_DEFAULT);
src,輸入圖像,即源圖像,Mat 類的對象即可。
dst,輸出圖像。
dstsize,輸出圖像的大小,有默認值 Size(),默認情況下,由 Size( (src.cols + 1) / 2,(src.rows + 1) / 2) 來進行計算
borderType,邊界擴展的方式,一般不考慮,選擇默認值。
代碼示例:
#include <opencv.hpp>
using namespace cv;
int main() {
Mat src = imread("C:/Users/齊明洋/Desktop/證件照/7.jpg");
imshow("src", src);
Mat up_img, down_img;
pyrUp(src, up_img);
pyrDown(src, down_img);
imshow("up_img", up_img);
imshow("down_img", down_img);
waitKey(0);
}
效果演示:
總結(jié)
以上是生活随笔為你收集整理的opencv —— resize、pyrUp 和 pyrDown 图像金字塔(高斯金字塔、拉普拉斯金字塔)与尺寸缩放(向上采样、向下采样)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Netty源码之解码中两种数据积累器(C
- 下一篇: 实现两个div并排的三种方式