前言
在上一章中描述了如何進(jìn)行形態(tài)學(xué)操作(開操作拔创、閉操作剩燥、形態(tài)學(xué)梯度、頂帽及黑帽)变擒,詳細(xì)描述可點擊查看(http://www.reibang.com/writer#/notebooks/47386368/notes/77896029)
目標(biāo)
本章中策添,將學(xué)習(xí):
- 圖像金字塔概念
- 采樣API
- 代碼演示
圖像金字塔概念
- 圖像金字塔是圖像中對尺度表達(dá)的一種,最主要用于圖像的分割摩窃,是一種以多分辨率來解釋圖像的有效但概念簡單的結(jié)構(gòu)。
- 圖像金字塔最初用于機器視覺和圖像壓縮蒂秘,一幅圖像的金字塔是一系列以金字塔形狀排列的分辨率逐步降低,且來源于同一張原始圖的圖像集合蒲牧。其通過梯次向下采樣獲得,直到達(dá)到某個中值條件才停止采樣翠订。
- 金字塔的底部是待處理圖像的高分辨率表示梧躺,而頂部是低分辨率的近似棘脐。
- 我們將一層一層的圖像比喻成金字塔:層級越高,則圖像越小榛了,分辨率越低构哺。
金字塔圖像.png
一般情況下有兩種類型的圖像金字塔常常出現(xiàn)在文獻(xiàn)和實際運用中碟嘴。他們分別是: - 高斯金字塔(Gaussianpyramid):從底向上栅组,逐層降采樣得到,降采樣之后圖像大小是原圖像的MxN的M/2 x N/2排截,就是對原圖像刪除偶數(shù)行與列嫌蚤,即得到降采樣之后上一層的圖片断傲;
-
拉普拉斯金字塔(Laplacianpyramid): 用來從金字塔低層圖像重建上層未采樣圖像,在數(shù)字圖像處理中也即是預(yù)測殘差垦垂,可以對圖像進(jìn)行最大程度的還原劫拗,配合高斯金字塔一起使用。
兩者的簡要區(qū)別:高斯金字塔用來向下降采樣圖像,而拉普拉斯金字塔則用來從金字塔底層圖像中向上采樣重建一個圖像揭绑。
要從金字塔第i層生成第i+1層(我們表示第i+1層為G_i+1)他匪,我們先要用高斯核對G_1進(jìn)行卷積,然后刪除所有偶數(shù)行和偶數(shù)列。當(dāng)然的是,新得到圖像面積會變?yōu)樵磮D像的四分之一关筒。按上述過程對輸入圖像G_0執(zhí)行操作就可產(chǎn)生出整個金字塔萍肆。
當(dāng)圖像向金字塔的上層移動時塘揣,尺寸和分辨率就降低。OpenCV中,從金字塔中上一級圖像生成下一級圖像的可以用PryDown搭独。而通過PryUp將現(xiàn)有的圖像在每個維度都放大兩遍。 -
高斯不同(Difference of Gaussion-DOG):就是把同一張圖像在不同的參數(shù)下做高斯模糊之后的結(jié)果相減嗤朴,得到的輸出圖像雹姊。高斯不同是圖像的內(nèi)在特征,在灰度圖像增強敦姻,角點檢測中經(jīng)常用到歧杏。
圖像層級.png
相關(guān)API
-
上采樣: void pyrUp( InputArray src, OutputArray dst,const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );
函數(shù)作用:先對圖像進(jìn)行升采樣(將圖像尺寸行和列方向增大一倍)旺入,然后再進(jìn)行高斯平滑凯力;
函數(shù)說明:倒數(shù)第二個參數(shù),在默認(rèn)的情況下拗秘,這個尺寸大小是按照 Size(src.cols2, (src.rows2) 來計算的聘殖。如果你自己要指定大小奸腺,那么一定要滿足下面的條件:|dstsize.width - src.cols * 2| ≤ (dstsize.width mod 2); //如果width是偶數(shù)血久,那么必須dstsize.width是src.cols的2倍氧吐;|dstsize.height - src.rows * 2| ≤ (dstsize.height mod 2);然后這個函數(shù)運行的過程就是先將圖像的尺寸行和列方向都放大一倍末盔,然后進(jìn)行高斯平滑陨舱,不過此時高斯平滑的kernel是上面pyrDown()中的kernel乘上4游盲,而不是完全相同蛮粮。( 其實也很容易理解然想,行和列方向各放大一倍的結(jié)果就是圖像的面積放大四倍,所以這里給之前的kernel乘以4)令哟。 -
上采樣: void pyrUp( InputArray src, OutputArray dst,const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );
函數(shù)作用:先對圖像進(jìn)行高斯平滑励饵,然后再進(jìn)行降采樣(將圖像尺寸行和列方向縮減一半)滑燃;
函數(shù)說明:倒數(shù)第二個參數(shù)表窘,這個參數(shù)指的是降采樣之后的目標(biāo)圖像的大小乐严,我們可以看出它是有默認(rèn)值的昂验,如果我們調(diào)用函數(shù)的時候不指定第三個參數(shù),那么這個值是按照 Size((src.cols+1)/2, (src.rows+1)/2) 計算的占婉。而且不管你自己如何指定這個參數(shù)逆济,一定必須保證滿足以下關(guān)系式:
|dstsize.width * 2 - src.cols| ≤ 2;
|dstsize.height * 2 - src.rows| ≤ 2;
也就是說降采樣的意思其實是把圖像的尺寸縮減一半,行和列同時縮減一半抛虫。所以你指定的大小建椰,無非就是多一行少一列的區(qū)別而已涎劈。在大多數(shù)情況下使用默認(rèn)值就可了阅茶,因為這個函數(shù)不是縮減圖像至任意尺寸,就只是縮減一半蹦浦,所以沒必要搞得那么復(fù)雜盲镶。
這個縮減的過程是這樣的溉贿,隔行隔列刪去圖像中的對應(yīng)行和列宇色!由此我們也可以看出,這樣縮減會帶來的影響就是:原圖中那些精細(xì)的細(xì)節(jié)邊緣等地方宣蠕,會因此變得鋸齒狀抢蚀,產(chǎn)生失真皿曲,因此為了縮小之后圖像看起來自然屋休,必須進(jìn)行平滑博投,這也就是這個算法為什么在降采樣之前先對圖像進(jìn)行了高斯模糊的原因毅哗。
代碼演示
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
// 1、加載圖像尿瞭,可以是BGR或者灰度圖像
Mat src = imread("D:/瀏覽器下載/谷歌下載/lena512color.tiff");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
char input_win[] = "input image";
namedWindow(input_win, WINDOW_AUTOSIZE);
imshow(input_win, src);
Mat dst;
char output_win[] = "pyrUp image";
namedWindow(output_win, WINDOW_AUTOSIZE);
// 上采樣
pyrUp(src, dst, Size(src.cols * 2, src.rows * 2));
imshow(output_win, dst);
// 降采樣
Mat downImg;
pyrDown(src, downImg, Size(src.cols / 2, src.rows / 2));
imshow("pyrDown image", downImg);
// DOG
Mat gray_src, g1, g2,dogimage;
cvtColor(src, gray_src, COLOR_BGR2GRAY); // 轉(zhuǎn)換圖像色彩空間
GaussianBlur(gray_src, g1, Size(5, 5), 0, 0); // 高斯模糊
GaussianBlur(g1, g2, Size(5, 5), 0, 0);
subtract(g1, g2, dogimage); // 圖像相減值非常低,圖像輪廓如果不做處理疏旨,不清晰
normalize(dogimage, dogimage, 255, 0, NORM_MINMAX); // 歸一化顯示,圖像映射到0-255范圍
imshow("DOG Image", dogimage);
waitKey(0);
return 0;
}
···

