SIFT四部曲之——高斯滤波
版權聲明:本文為博主原創文章,未經博主允許不得轉載。博客不用于商業活動,博主對博客的使用,擁有最終解釋權?
本文為原創作品,未經本人同意,禁止轉載,禁止用于商業用途!本人對博客使用擁有最終解釋權?
歡迎關注我的網上圖書室:晨鳧追風和 微信公眾號:青春當追風
?
或許網絡上有各位牛人已經對sift算法進行各種的詳解和說明,我(小菜鳥)在翻閱各種資料和對opencv中的代碼進行反推之后,終于理解該算法。并記錄之,供大家一起交流學習!這個博文主要記錄了我的學習歷程,或許對你有幫助,或許可以啟發你,或許你只是一笑而過!沒關系,至少自己總結過。
這篇文章主要是對sift算法的每一個步驟,每一個參數進行說明,并在最后用matlab實現該算法,從理論到代碼實現或許需要考慮方方面面,但是它并不是那么的難!
1、算法簡介
開始之前要例行一些東西,對sift的簡單介紹。如果不想看直接跳到第二部分,沒問題!
Sift(Scale-invariant feature transform)尺度不變特征轉換,CV界中赫赫有名的算法,由David Lowe(圖1的老頭)提出,該算法受專利保護,專利權屬于英屬哥倫比亞大學。
圖1 David Lowe
Sift算法可以將一幅圖像映射(變換)為一個局部特征向量集;特征向量具有平移、縮放、旋轉不變性,同時對光照變化、仿射及投影變換也有一定的不變性。
SIFT算法的特點有:(只是理論,所以看看就好)
1.SIFT特征是圖像的局部特征,其對旋轉、尺度縮放、亮度變化保持不變性,對視角變化、仿射變換、噪聲也保持一定程度的穩定性;
2.獨特性(Distinctiveness)好,信息量豐富,適用于在海量特征數據庫中進行快速、準確的匹配;
3.多量性,即使少數的幾個物體也可以產生大量的特征向量;
4.高速性,經優化的匹配算法甚至可以達到實時的要求;
5.可擴展性,可以很方便的與其他形式的特征向量進行聯合。
SIFT算法可以解決的問題:
目標的自身狀態、場景所處的環境和成像器材的成像特性等因素影響圖像配準目標識別跟蹤的性能。而算法在一定程度上可解決:
1.目標的旋轉、縮放、平移
2.投影變換
3.光照影響
4.目標遮擋
5.雜物場景
SIFT算法的實質是在不同的尺度空間上查找關鍵點,并計算出關鍵點的方向。所查找到的關鍵點是一些十分突出,不會因光照,仿射變換和噪音等因素而變化的點,如角點、邊緣點、暗區的亮點及亮區的暗點等。
SIFT算法可以分解為如下四步:
1.高斯差分(DoG)濾波:搜索所有尺度上的圖像位置。通過高斯微分函數來識別潛在的對于尺度和旋轉不變的興趣點。
2.尺度空間的極值檢測和關鍵點位置確定:對DoG金字塔中的每一層,進行尺度空間的極值檢測(極大值和極小值),把每一個極值點作為候選點,在每個候選的位置上,通過一個擬合精細的模型來確定位置和尺度。關鍵點的選擇依據于它們的穩定程度。
3.關鍵點方向確定:基于圖像局部的梯度方向,分配給每個關鍵點位置一個或多個方向。所有后面的對圖像數據的操作都相對于關鍵點的方向、尺度和位置進行變換,從而提供對于這些變換的不變性。
4.構建關鍵點特征描述符:在每個關鍵點周圍的內,在選定的尺度上測量圖像局部的梯度。這些梯度被變換成一種表示,這種表示允許比較大的局部形狀的變形和光照變化。
2.高斯差分(DoG)濾波:
在這個部分開始之前,首先要普及一下一些相關的知識點。
2.1圖像尺度空間
在圖像信息處理中引入一個名為尺度的參數,通過對圖像進行一些變換,獲得在多個尺度空間下的圖像空間序列,對這些序列可以進行一些特征的提取等操作,可以實現邊緣,角點檢測和不同分辨率上的特征提取。
對這個尺度空間的理解:它可以模擬人在距離目標由近到遠的過程中,目標在視網膜當中形成的圖像的過程。尺度越大圖像越模糊,相當于我們觀察遠處物體,這時候關注該物體的輪廓。如下圖,我們看到遠方只有兩個人的外形,并不能看到衣服上的花紋。
尺度空間滿足視覺不變性。
- 滿足灰度不變性和對比度不變性:當我們用眼睛觀察物體時,當物體所處背景的光照條件變化時,視網膜感知圖像的亮度水平和對比度是不同的,因此要求尺度空間算子對圖像的分析不受圖像的灰度水平和對比度變化的影響。
- 滿足平移不變性、尺度不變性、歐幾里德不變性以及仿射不變性:相對于某一固定坐標系,當觀察者和物體之間的相對位置變化時,視網膜所感知的圖像的位置、大小、角度和形狀是不同的,因此要求尺度空間算子對圖像的分析和圖像的位置、大小、角度以及仿射變換無關。
一個圖像的尺度空間表示在該尺度下,該坐標處的值。
2.2二維高斯函數和高斯模糊
下面這些只是一些基礎性的知識,公式并不需要推導,接受就好。
高斯濾波器,使用正態分布計算的一種卷積模板(基本概念,這不懂的話,需要自己入門),利用高斯濾波器和圖像進行卷積運算,可對圖像進行模糊處理。公式如下(這是一個二維的高斯濾波器):
二維高斯曲面如下:
圖3 高斯二維曲面
其中為正態分布的標準差,在高斯模糊中,它越大,圖像越模糊。這里要定義一個模糊半徑,
表示模板元素到模板中心的距離。
當然上面只是一個連續的曲面,在對圖像進行高斯模糊的過程中需要的是高斯模板,這個模板和圖像卷積便可得到高斯模糊圖像。正態分布中,在大于3*的范圍之外存在的概率占僅0.3%,所以在3*的范圍之外,那些像素所起作用基本可以忽略不計了,所以高斯模板只需要計算的大小即可。根據的值計算可以計算出高斯模板。
最后提幾條高斯模糊的特性(后面的理解中會被用到)
下面是高斯模板的生成代碼:
?
function[g,x] = gaussian_filter(sigma,sample) sample = 3.5; if ~exist('sample')sample = 7.0/2.0; end %設置濾波閾值 n = 2*round(sample * sigma) + 1;x = 1:n; x = x-ceil(n/2); g = exp(-(x.^2)/(2*sigma^2))/(sigma*sqrt(2*pi)); end這里產生的是一行的高斯模板,即運用了對模板進行線性分解的這個性質。當時,該模板為
| 6.60729028444640e-06 | 0.000426170838253310 | 0.00170911194387669 | 0.000426170838253310 | 6.60729028444640e-06 |
| 0.000426170838253310 | 0.0274880587288661 | 0.110237879438303 | 0.0274880587288661 | 0.000426170838253310 |
| 0.00170911194387669 | 0.110237879438303 | 0.442097064144154 | 0.110237879438303 | 0.00170911194387669 |
| 0.000426170838253310 | 0.0274880587288661 | 0.110237879438303 | 0.0274880587288661 | 0.000426170838253310 |
| 6.60729028444640e-06 | 0.000426170838253310 | 0.00170911194387669 | 0.000426170838253310 | 0 |
當時,該高斯模糊的效果如圖4
圖4高斯模糊效果
2.3高斯金字塔
先說高斯金字塔要得到啥吧:
高斯金字塔主要是為了得到不同尺度的圖片,這些圖片的尺度必須是連續的,所以要對圖片進行高斯濾波。高斯金字塔是一個原始圖像,產生幾組(octave)每一組中又包含著幾層(interval)。如圖5:
圖5高斯金字塔示意
當然在構建高斯金字塔之前還需要確定的是我們需要構建該金字塔的階數(o)和每一組的層數(s)。
高斯金字塔的構建主要就是分成兩步走
關鍵:模糊尺度的確定
關鍵:降采樣的母本圖片的確定
在高斯金字塔的構建中,圖像每一組的大小與相應階數的對應關系為:(原始圖像以512*512為例)
| 階數 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 大小 | 512 | 256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 |
2.4高斯差分金字塔(這一部分是結論性的知識)
2002年Mikolajczyk在詳細的實驗比較中發現尺度歸一化的高斯拉普拉斯函數的極大值和極小值同其它的特征提取函數(如:梯度,Hessian或Harris角特征)比較,能夠產生最穩定的圖像特征。
而Lindeberg早在1994年就發現高斯差分函數(Difference of Gaussian 算子)與尺度歸一化的高斯拉普拉斯函數非常近似。其中和的關系可以從如下公式推導得到:
利用差分近似代替微分,則有:
其中k-1是個常數,并不影響極值點位置的求取。而高斯拉普拉斯和高斯差分的比較如圖6:
圖6高斯拉普拉斯和高斯差分
如圖所示,紅色曲線表示的是高斯差分算子,而藍色曲線表示的是高斯拉普拉斯算子。使用更高效的高斯差分算子代替拉普拉斯算子進行極值檢測,如下:
Ok講到這里,聰明的讀者就應該知道了,學習前面那么多的知識,只是為了對sift特征點的出場做鋪墊。在實際計算時,使用高斯金字塔每組中相鄰上下兩層圖像相減,得到高斯差分圖像,如圖7所示,進行極值檢測。這樣就能得到sift特征點的候選人,對,只是候選。
圖7高斯差分金字塔生成
2.5高斯金字塔生成的細節
上述所有的知識已經把sift關鍵點候選人的選舉辦法說清楚了,現在該講一講選舉過程中所應該注意的4個問題,這樣就把這一部分結束。
這兩個問題歸根到底還是高斯金字塔構建的過程中的4個問題。
下面一一解答:
1、金字塔的階數(O)一般為4,也可以根據圖像大小來選擇,但是要滿足下列關系:
分別表示圖像的行數和列數。
2、每一階的層數(S)一般選擇5或者6,一般選擇6的時候效果最好。在這邊就要根據前面的說明,特征點的選舉是要在相鄰的兩層差分金字塔上面進行檢測的,所以要得到n個尺度的特征點,就要在層的差分金字塔上檢測,(自己畫個圖就ok了),然而要產生n+2層的差分金字塔,就要有n+3層的高斯金字塔,這樣相鄰的相減,才能產生n+2層差分。注意:這里的檢測都是同階里面不同層的操作。所以S = n + 3。記住這個n,有用!
3、尺度因子的選擇,或許這是本節中最讓人頭疼的一件事情了。然而在看完眾多源碼和例程之后我把自己的見解整理如下:
先要理解幾個概念:
高斯金字塔的模糊尺度:這個尺度是我們產生模板的尺度
攝像頭模糊的尺度:這個尺度是圖像被相機鏡頭模糊后的尺度,一般為固定值,這里定義0.5。
圖像的尺度:這個尺度是攝像頭模糊尺度和高斯金字塔尺度的合作用,滿足方和根的關系。Lowe定義圖片的尺度為1.6。
這里插入解答第4個問題,即下一階的第一層圖像是根據上一階的倒數第三層圖像進行降采樣得到的。見圖8
圖8降采樣示意圖
好了回來繼續解答第三個問題,
在一階的圖像內,每一層之間的高斯模糊的尺度因子的比值為 ,
于是同一階的第s層高斯模糊尺度就變成了
這里是這一階的第一層圖像的高斯模糊尺度
根據圖7所示,第n+1階的圖像,它的高斯模糊尺度是,這個圖像的高斯模糊帶到了下一階的第一層圖像中去,于是不同階相同層的高斯模糊尺度是2倍關系。如圖9所示
圖9不同層之間的尺度示意
綜上可以概括出階內及階之間的尺度關系了。
i:表示第i階的圖像
s:表示階內第s層的圖像
在理清楚圖像互相之間的關系之后,我們需要的是第一階,第一層的高斯模糊尺度,這樣就能根據上述關系,搞到所有的高斯模糊尺度了。還記得兩個數嗎?0.5和1.6,這時候就派上用場了。
在lowe的論文中,他定義圖片的尺度是1.6,被攝像頭模糊的尺度是0.5,于是可以算得高斯模糊是
但是這個1.52對我們來說并沒有啥意思,lowe為了獲得更多的特征點(姑且這么解釋吧)他先對原始圖像進行擴大一倍。(有各種插值的方法,這里用雙線性插值)然后呢再對它進行高斯平滑作為第一階第一層,這時候它的高斯模糊尺度為
于是得到最開始的高斯模糊尺度。這下可以得到所有的高斯模糊尺度了。
到此為止,我們講完所有理論的工作了,然而在實際實現中,同一階第s+1層的圖片是在第s層圖片的基礎上進行高斯模糊得到的,還記得那個方和根的關系吧。故,第s+1層圖片由第s層圖片用一個尺度的模板進行高斯卷積得到。
最后產生高斯金字塔,相鄰層相減,便得到高斯差分金字塔。附上這一部分的生成代碼:
im = imread('gray_testImage1.jpg');im = im2double(im);% 設定輸入量的默認值 if ~exist('octaves') %%最大的階數octaves = 4;endif ~exist('intervals')%%每一階最大的層數intervals = 2;endif ~exist('object_mask')%%計算模板大小object_mask = ones(size(im));endif size(object_mask) ~= size(im)object_mask = ones(size(im));endif ~exist('contrast_threshold')contrast_threshold = 0.02;%%設置去除低對比度特征點閾值大小endif ~exist('curvature_threshold')curvature_threshold = 10.0;%%設置去除邊緣特征點閾值大小endif ~exist('interactive')%%設置迭代次數interactive = 1;end interactive = 2;% 檢驗輸入灰度圖像的像素灰度值是否已歸一化到[0,1]if( (min(im(:)) < 0) | (max(im(:)) > 1) )fprintf( 2, 'Warning: image not normalized to [0,1].\n' );end% 將輸入圖像經過高斯平滑處理,采用雙線性差值將其擴大一倍. if interactive >= 1fprintf( 2, 'Doubling image size for first octave...\n' ); endtic;antialias_sigma = 0.5; %%高斯平滑參數if antialias_sigma == 0 %%不進行平滑操作signal = im;elseg = gaussian_filter( antialias_sigma ); %%%產生高斯模板if exist('corrsep') == 3signal = corrsep( g, g, im );elsesignal = conv2( g, g, im, 'same' ); %%高斯卷積endendsignal = im;[X Y] = meshgrid( 1:0.5:size(signal,2), 1:0.5:size(signal,1) );signal = interp2( signal, X, Y, 'linear' ); %%雙線性插值擴展圖片subsample = [0.5]; % 降采樣率;%下一步是生成高斯和差分高斯(DOG)金字塔,這兩個金字塔的數據分別存儲在名為gauss_pyr{orient,interval}% 和DOG_pyr{orient,interval}的元胞數字中。高斯金字塔含有s+3層,差分高斯金字塔含有s+2層。if interactive >= 1fprintf( 2, 'Prebluring image...\n' ); endpreblur_sigma = sqrt(sqrt(2)^2 - (2*antialias_sigma)^2);if preblur_sigma == 0gauss_pyr{1,1} = signal; %%matlab cell數據類型有待考證elseg = gaussian_filter( preblur_sigma );if exist('corrsep') == 3gauss_pyr{1,1} = corrsep( g, g, signal );elsegauss_pyr{1,1} = conv2( g, g, signal, 'same' );endendclear signalpre_time = toc;if interactive >= 1fprintf( 2, 'Preprocessing time %.2f seconds.\n', pre_time );endinitial_sigma = sqrt((2 * antialias_sigma)^2 + preblur_sigma^2);%計算第一層第一階模糊金字塔的sigma值%%計算不同階層的siamaabsolute_sigma = zeros(octaves,intervals + 3);absolute_sigma(1,1) = initial_sigma * subsample(1);%%對生成的金字塔的濾波核大小和標準差進行跟蹤filter_size = zeros(octaves, intervals+3);filter_sigma = zeros(octaves, intervals+3);tic%%計算差分高斯金字塔for octave = 1:octavessigma = initial_sigma;g = gaussian_filter(sigma);filter_size(octave,1) = length(g);filter_sigma(octave,1) = sigma;DOG_pyr{octave} = zeros(size(gauss_pyr{octave,1},1),size(gauss_pyr{octave,1},2),intervals+2);%%從第二層計算差分金字塔for interval = 2:(intervals + 3)sigma_f = sqrt(2^(2/intervals) - 1) * sigma;g = gaussian_filter(sigma_f);sigma = (2^(1/intervals)) *sigma %%得到下一個sigmaabsolute_sigma(octave,interval) = sigma * subsample(octave);%存儲濾波器的核大小及標準差filter_size(octave,interval) = length(g);filter_sigma(octave,interval) = sigma;if exist('corrsep')==3gauss_pyr{octave,interval} = corrsep(g,g,gauss_pyr{octave,interval - 1});elsegauss_pyr{octave,interval} = conv2(g,g,gauss_pyr{octave,interval - 1},'same');endDOG_pyr{octave}(:,:,interval - 1) = gauss_pyr{octave,interval} - gauss_pyr{octave,interval -1};endif octave < octavessz = size(gauss_pyr{octave,intervals + 1});[X,Y]= meshgrid(1:2:sz(2),1:2:sz(1));gauss_pyr{octave + 1,1} = interp2(gauss_pyr{octave,intervals + 1},X,Y,'*nearest');abslute_sigma(octave+1,1) = absolute_sigma(octave,intervals+1);subsample = [subsample subsample(end)*2];endendpyr_time = toc;% 在交互模式下顯示高斯金字塔 if interactive >= 2sz = zeros(1,2);sz(2) = (intervals+3)*size(gauss_pyr{1,1},2);for octave = 1:octavessz(1) = sz(1) + size(gauss_pyr{octave,1},1);endpic = zeros(sz);y = 1;for octave = 1:octavesx = 1;sz = size(gauss_pyr{octave,1});for interval = 1:(intervals + 3)pic(y:(y+sz(1)-1),x:(x+sz(2)-1)) = gauss_pyr{octave,interval}; x = x + sz(2);endy = y + sz(1);endfig = figure;clf;imshow(pic); % resizeImageFig( fig, size(pic), 0.25 ); % fprintf( 2, 'The gaussian pyramid (0.25 scale).\nPress any key to continue.\n' ); % pause; % close(fig) end% 在交互模式下顯示差分高斯金字塔 if interactive >= 2sz = zeros(1,2);sz(2) = (intervals+2)*size(DOG_pyr{1}(:,:,1),2);for octave = 1:octavessz(1) = sz(1) + size(DOG_pyr{octave}(:,:,1),1);endpic = zeros(sz);y = 1;for octave = 1:octavesx = 1;sz = size(DOG_pyr{octave}(:,:,1));for interval = 1:(intervals + 2)pic(y:(y+sz(1)-1),x:(x+sz(2)-1)) = DOG_pyr{octave}(:,:,interval); x = x + sz(2);endy = y + sz(1);endfig = figure;imshow(pic); % clf; % imagesc(pic);%%%這個函數可以調整圖像顯示 % resizeImageFig( fig, size(pic), 0.25 ); % fprintf( 2, 'The DOG pyramid (0.25 scale).\nPress any key to continue.\n' ); % pause; % close(fig) end?
Ok,至此,我們完成第一部分的高斯濾波和金字塔構建工作。
最后,我要貼上幾個引導我學習的博客文章鏈接,對你們表示感謝!尊重作者的勞動成果,知識共享,但不代表著盜取!
未經本人同意禁止轉載!
http://blog.csdn.net/zddblog/article/details/7450033
歡迎·閱讀SIFT四部曲之——極值檢測
總結
以上是生活随笔為你收集整理的SIFT四部曲之——高斯滤波的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第九节:掌握vue的另一个核心:组件
- 下一篇: 性能优化(6):为什么一定要将css置顶