天天看點

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

作者:AI小李

如果需要處理的原圖及代碼,請移步GitHub位址

 GitHub - LeBron-Jian/ComputerVisionPractice

前言

  特征點檢測廣泛應用到目标比對,目标跟蹤,三維重建等應用中,在進行目标模組化時會對圖像進行目标特征的提取,常用的有顔色,角點,特征點,輪廓,紋理等特征。而下面學習常用的特征點檢測。

  總結一下提取特征點的作用:

  • 1,運動目标跟蹤
  • 2,物體識别
  • 3,圖像配準
  • 4,全景圖像拼接
  • 5,三維重建

  而一種重要的點特征就是角點,本文就學習基于角點檢測的算法:Harris角點檢測和SIFT特征。

1,Sift之前的江湖

  (這段的位址:https://blog.csdn.net/dcrmg/article/details/52577555)

  在Sift橫空出世之前,特征點檢測與比對江湖上占據霸主地位的是角點檢測家族。先探究一下角點家族不為人知的恩怨情仇。

  角點家族的族長是Moravec在1977年提出的 Moravec角點檢測算子,它是一種基于灰階方差的角點檢測方法,該算子計算圖像中某個像素點沿水準,垂直方向上的灰階差異,以确定角點位置,Moravec是第一個角點檢測算法,也是角點家族的開山鼻祖。

  角點的九袋長老是Chris Harris & Mike Stephens在 1988年提出的 harris角點檢測算子。Harris不止是考察水準,垂直4個方向上的灰階差異,而是考察了所有方向上的灰階差異,并且具有旋轉不變性和對部分仿射變換的穩定性。Harris是整個角點檢測家族的顔值擔當。

  角點家族的大護法是 J.shi 和 C.Tomasi在1994年提出的 Shi-Tomasi 角點檢測算子,它是對 Harris 角點檢測算子的改進,并且有一個直接“叫嚣” Harris算子的名字——“Good Feaures to Track”,在opencv中實作函數是 goodfeaturesToTrack。它通過考察自相關矩陣M的兩個特征值中的較小者來确定角點,大部分情況下,有比Harris更好的檢測效果。

  角點家族的大堂主是E.Rosten 和 T.Drummond 在 2006年提出的 FAST(Feature from Accelerated Segment Test)算子。它通過考察像素點與周圍領域内 16個像素點的差異來确定特征點(角點),并且通過分割測試算法對檢測效率做了極大的提升。它信奉“天下武功,唯快不破”的真理,在快的道路上銳意進取,基本可以滿足實時檢測系統的要求,在現今計算機視覺領域賺足了眼球。

  角點家族這種群雄逐鹿的局面一直持續了很多年,大家你追我趕,在群主 Moravec 的帶領下家族基業日漸殷實。直到20年後 1999年的某天,有一個叫Sift的後生出現了。

  1999年,大不列颠哥倫比亞大學的David G.Lowe 教授在現有基于不變量技術的特征檢測方法基礎上,提出了一種基于尺度空間的,對圖形縮放,旋轉,甚至仿射變換保持不變性的圖像局部特征描述算子——sift(尺度不變特征變換),全稱是Scale invariant Feature Transform,并且在2004年,又對Sift算法做了更為系統的完善。

2,角點的定義

  角點可以認為是圖像亮度變化劇烈的點或圖像邊緣曲線上曲率極大值的點。

  角點就是極值點,在某個方面屬性特别突出的點。

  角點可以是兩條線的交叉處,也可以是位于相鄰的兩個主要方向不同的事物上的點。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  從圖中可以看出:

  角點:最直覺的印象就是在水準,垂直兩個方向上變換均較大的點,例如上面E和F是角點,可以迅速定位到。

  邊緣:僅在水準或者垂直方向有較大的變化,例如上面C和D是邊界,可以大緻找到位置。

  平坦地區:在水準,垂直方向的變換量均較小,例如上面A和B是平坦地區,在圖像中有很多存在

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  下面看一下角點的類型:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

3,角點檢測

  角點檢測是擷取圖像特征的一種方法,廣泛用于運作檢測,圖像比對,視覺跟蹤,三維模組化和目辨別别等領域。也稱為特征點檢測。

  角點檢測算法可以歸為三類:

  • 基于灰階圖像的角點檢測
  • 基于二值圖像的角點檢測
  • 基于輪廓曲線的角點檢測

  其中,基于灰階圖像的角點檢測又分為基于梯度,基于模闆和基于模闆梯度組合三類方法。其中基于模闆的方法主要考慮像素領域點的灰階變化,即圖像亮度的變化,将與鄰點亮度對比足夠大的點定義為角點。

  基于圖像灰階的方法通過計算點的曲率及梯度來檢測角點,常用的基于模闆的角點檢測算法有:

  • Kitchen-Rosenfeld 角點檢測
  • Moravec算子
  • Forstner算子
  • Harris角點檢測
  • KLT角點檢測
  • SUSAN角點檢測

4,特征不變性

  在特征點檢測中經常提出尺度不變,旋轉不變,抗噪聲影響等,這些是判斷特征點是否穩定的名額。那麼什麼是特征呢?什麼又是局部不變特征呢?下面一一學習。

什麼是特征?

  每個物體,我們總可以用一些詞語或部件來描述它,比如人臉的特征:兩個眼睛,一個鼻子和一個嘴巴。對于圖像而言,我們需要計算機去了解圖像,描述圖像就需要計算機去取得圖像的特征,對圖像比較全面的描述即是一個二維矩陣,矩陣内的每個值代表圖像的亮度。有時候我們需要讓計算機更簡化的描述一個圖像,抓住一些顯著特征,這些特征要具有一些良好的性質,比如局部不變性。局部不變性一般包括兩個方面:尺度不變性與旋轉不變性。

尺度不變性:人類在識别一個物體時,不管這個物體或遠或近,都能對它進行正确的辨識,這就是所謂的尺度不變性。尺度空間理論經常與生物視覺關聯,有人也稱圖像局部不變性特征為基于生物視覺的不變性方法。

旋轉不變性:當這個物體發生旋轉時,我們照樣可以正确地辨認它,這就算所謂的旋轉不變性。

局部不變特征

  全局特征:從整個圖像中抽取的特征。較多的運用在圖像檢索領域,如圖像顔色直方圖。

  局部特征:從圖像的局部區域中抽取的特征(這個局部區域往往是圖像中的一個像素及它周圍的鄰域)

  一個好的局部特征應該具有以下的特征:

  1. 可重複性:同一個物體在不同時間,不同角度拍到圖像中,檢測到的特征對應的越多越好。
  2. 獨特性:特征在該物體上表現為獨特性,能與場景下其他物體區分。
  3. 局部性:特征往往是物體某個局部的特點,這樣才可以避免遮擋時不能比對的問題。
  4. 數量性:檢測到的特征數目一定要多,密集度最好能在一定程度上反映圖像的内容。
  5. 準确性:得到的特征應該能被精确定位,能夠精确到像素。
  6. 高效性:特征檢測算法運算要快。

那麼什麼是好的角點檢測算法:

  • 1,檢測出圖像中“真實”的角點
  • 2,準确的定位性能
  • 3,很高的重複檢測率
  • 4,噪聲的魯棒性
  • 5,較高的計算效率

  下面分别學習 Harris角點檢測和 SIFT算法。

1,Harris 角點檢測

1.1,Harris角點算法概述

  Harris角點是特征點檢測的基礎,提出了應用鄰域像素點灰階內插補點概念,進而進行判斷是否為角點,邊緣,平滑區域。Harris角點檢測原理是利用移動的視窗在圖像中計算灰階變化值,其中關鍵流程包括轉化為灰階圖像,計算差分圖像,高斯平滑,計算局部極值,确認角點。

1.1.1 Harris角點算法思想

  角點原理來源于人對角點的感性判斷,即圖像在各個方向灰階有明顯變化。算法的核心是利用局部視窗在圖像上進行移動判斷灰階發生較大的變化,是以此視窗用于計算圖像的灰階變化為:[-1, 0, 1;-1, 0, 1;-1, 0, 1] [-1, -1, -1; 0, 0, 0;1, 1, 1]。人各個方向上移動這個特征的小視窗,如下圖3中視窗内區域的灰階發生了較大的變化,那麼就認為在視窗内遇到了角點。如下圖1中,視窗内圖像的灰階沒有發生變化,那麼視窗内就不存在角點;如果視窗在某一個方向移動時,視窗内圖像的灰階發生了較大的變化,而在另一些方向上沒有發生變化,那麼,視窗内的圖像可能就是一條直線的線段。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

1.2,Harris角點檢測數學推導

  根據算法思想,Harris算法是利用視窗内圖像灰階的自相關性進行的,設計一個視窗在圖像中移動,建構數學模型,計算移動視窗的灰階內插補點(即移動前和移動後視窗所在區域圖像的自相關系數)。

  Harris算法是利用的視窗内圖像灰階的自相關性進行的,設定一個視窗,并在圖像中移動,計算移動前與移動後視窗所在區域圖像的自相關系數。

  自相關函數計算如下,(x, y)為視窗中心位置,w(u, v)為權重(一般取高斯函數),L表示視窗,(u, v)表示視窗中圖像位置。

  對于圖像I(x, y) ,當在點(x, y)處平移(Δx, Δy)後的自相似性:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  W(x, y) 是以點(x, y)為中心的視窗函數,即可以是常數,也可以是高斯權重函數(但是通常都為高斯權重函數):

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  為了減小計算量,基于泰勒展開進行簡化公式,對圖像l(x, y)在平移(Δx, Δy)後進行一階近似:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  其中 Ix, Iy 是 I(x, y) 的偏導數。

  将近似值代入自相關函數,有:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  将平方項展示并寫成矩陣形式,有:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  回到自相關表達式:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  近似可得下面表達:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  其中M是2*2的矩陣(M矩陣為偏導數矩陣),可由圖像的導數求得:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  化簡可得:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)
圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  經過上面的數學形式推導,已經得到了自相關函數的表達式。可以看得這也是一個橢圓的矩陣表達式形式(非标準橢圓),是以其系數矩陣M的特征值與橢圓的半軸長短有關。

1.2.1 橢圓的矩陣方差表示

  二次項函數本質上就是一個橢圓函數,橢圓如下:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  其橢圓方程式如下:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  如果将上述方差寫成矩陣形式如下:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

1.2.2 橢圓半軸與系數矩陣的關系

  一個n*n的矩陣,可以求解其特征值,我們對上述系數矩陣(含a、b)進行求解,則可得到特征值與橢圓半軸(a、b)的關系,下面我們看一下橢圓半軸與特征值的關系,如果求上述方程式的特征值,則可以得到特征值與橢圓半軸的關系,推導如下:

  用M表示參數:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  是以橢圓方程為:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  其特征值為 λ1 和 λ2,則特征值與半軸的關系為:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  我們在下面橢圓圖中可以看到:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  結論就是:特征值大,半軸短。

  邊界:一個特征值大,另一個特征值小,λ1 >> λ2 或者 λ2 >> λ1。自相關函數值在某一個方向上大,在其他方向上小。

  平面:兩個特征值都小,且近似相等;自相關函數數值在各個方向上都小

  角點:兩個特征值都很大且近似相等,自相關函數在所有方向都增大

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  經過上面的數學形式推導,已經得到了自相關函數的表達式。可以看得這也是一個橢圓的矩陣表達形式(非标準橢圓),是以其系數矩陣M的特征值與橢圓的半軸長短有關,這與上面預備知識中的結論一樣。

  假設M的特征值為 λ1 λ2,則分為以下三種情況:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  通過上面的情況,計算出特征值後就可以判别是否是角點了。

1.2.3 角點響應R值

  M為梯度的協方差矩陣,在實際應用中為了能夠應用更好的程式設計,定義了角點響應函數R,通過判斷R大小來判斷像素是否為角點。

  R取決于M的特征值,對于角點 |R| 很大,平坦的區域 |R| 很小,邊緣的 R 為負值。

  當然,這樣計算量非常大,因為圖像中的幾乎每個點都需要進行一次特征值的計算,下面給出一個角點響應函數R的經驗公式:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  detM 表示M的行列式,traceM表示M的迹,R表示角點響應值,alpha表示經驗常數,一般在0.04~0.06之間取值。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)
圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  判斷準則:當R超過某個設定的門檻值時,可認為是角點,反之,則不是。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

1.3,Harris 角點檢測算法流程

  步驟1:利用水準,豎直差分算子對圖像 I(x, y)的每個像素進行濾波以求得 X 和 Y方向的梯度 Ix和Iy,進而求得M中的四個元素的值。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)
圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  代碼中如果array為{ -1, 0, 1, -1, 0, 1, -1, 0, 1 }則是求解X方向的,如果為{-1, -1, -1, 0, 0, 0, 1, 1, 1}為Y方向的,則Ix和Iy求解結束。

  求解IX2 IY2 IXY相對比較簡單,像素相乘即可。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)
圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)
圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  對M的四個元素進行高斯平滑濾波,為的是消除一些不必要的孤立點和凸起,得到新的矩陣M。求M的話,我們使用高斯核對IX2 IY2 IXY進行權重,計算矩陣 M 的元素,A,B,C,然後得到M矩陣。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)
圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  步驟2:接下來使用M計算對應每個像素的角點響應函數R

  其中,角點響應函數R 為:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)
圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  改進的角點響應函數R為:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

   裡面沒有随意給定的參數k,取值應當比第一個令人滿意。

  步驟3:局部最大值抑制,同時選取其最大值

  步驟4:在矩陣R中,同時滿足 R(i, j)大于一定門檻值 threshold 和 R(i, j) 是某鄰域内的局部極大值,則被認為是角點。當角點量小于門檻值值,則不是候選角點。

1.4,Harris角點性質

1.4.1 門檻值決定檢測點數量

  增大 alpha 的值,将減小角點響應值 R,降低角點檢測的靈性,減少被檢測角點的數量;減少 alpha 值,将增大角點響應值 R,增加角點檢測的靈敏性,增加被檢測角點的數量。

1.4.2 Harris角點檢測算子對亮度和對比度的變化不敏感

  這是因為在進行 Harris角點檢測時,使用了微分算子對圖像進行微分運算,而微分運算對圖像密度的拉升或收縮和對亮度的擡高或下降不敏感。換言之,對亮度和對比度的仿射變換并不改變 Harris響應的極值點出現的位置,但是,由于門檻值的選擇,可能會影響角點檢測的數量。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)
圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

1.4.3 Harris角點檢測算子具有旋轉不變性

  Harris角點檢測算子使用的是角點附加的區域灰階二階矩矩陣。而二階矩矩陣可以表示成一個橢圓,橢圓的長短軸正是二階矩矩陣特征值平方根的倒數。當特征橢圓轉動時,特征值并不發生變換,是以判斷角點響應值也不發生變換,由此說明 Harris角點檢測算子具有旋轉不變性。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

1.4.4 Harris角點檢測算子不具有尺度不變性

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  如下圖所示,當右圖被縮小時,在檢測視窗尺寸不變的前提下,在視窗内所包含圖像的内容是完全不同的。左側的圖像可能被檢測為邊緣或曲線,而右邊的圖像則可能被檢測為一個角點。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

1.5,Harris角點檢測實戰

1.5.1 Harris的opencv源碼

  首先我們看一下Harris的opencv源碼:

def cornerHarris(src, blockSize, ksize, k, dst=None, borderType=None): # real signature unknown; restored from __doc__
    """
    cornerHarris(src, blockSize, ksize, k[, dst[, borderType]]) -> dst
    .   @brief Harris corner detector.
    .   
    .   The function runs the Harris corner detector on the image. Similarly to cornerMinEigenVal and
    .   cornerEigenValsAndVecs , for each pixel \f$(x, y)\f$ it calculates a \f$2\times2\f$ gradient covariance
    .   matrix \f$M^{(x,y)}\f$ over a \f$\texttt{blockSize} \times \texttt{blockSize}\f$ neighborhood. Then, it
    .   computes the following characteristic:
    .   
    .   \f[\texttt{dst} (x,y) =  \mathrm{det} M^{(x,y)} - k  \cdot \left ( \mathrm{tr} M^{(x,y)} \right )^2\f]
    .   
    .   Corners in the image can be found as the local maxima of this response map.
    .   
    .   @param src Input single-channel 8-bit or floating-point image.
    .   @param dst Image to store the Harris detector responses. It has the type CV_32FC1 and the same
    .   size as src .
    .   @param blockSize Neighborhood size (see the details on #cornerEigenValsAndVecs ).
    .   @param ksize Aperture parameter for the Sobel operator.
    .   @param k Harris detector free parameter. See the formula above.
    .   @param borderType Pixel extrapolation method. See #BorderTypes.
    """
    pass
           

  參數含義:

  • src:資料類型為 float32 的輸入圖像
  • blockSize:角點檢測中指定區域的大小
  • ksize:Sobel求導中使用的視窗大小
  • k:取值參數為 [0.04, 0.06]

1.5.2 Harris角點檢測opencv實戰

  下面以一張圖檔為例:

import cv2
import numpy as np

img = cv2.imread('test_1.jpg')
print('imgshape', img.shape)
# imgshape (800, 1200, 3)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# gray = np.float32(gray)
dst = cv2.cornerHarris(gray, 2, 3, 0.04)
print('dst.shape', dst.shape)
# dst.shape (800, 1200)

img[dst>0.01*dst.max()] = [0, 0, 255]
cv2.imshow('dst', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
           

  比 max 的 0.01 大,則表示為角點,我們拿到其角點。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  棋盤,角點比較多,但是是彩色的,如果想看真的關于角點的效果,可以用黑白棋盤。

  再看一張圖,效果如下:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

2,SIFT特征

2.1 SIFT特征概述

  SIFT 的全稱是 Scale Invariant Feature Transform,尺度不變特征變換,由加拿大教授David G.Lowe提出的。SIFT特征對旋轉,尺度縮放,亮度變化等保持不變性,是一種非常穩定的局部特征。

  SIFT提取圖像的局部特征,在尺度空間尋找極值點,并提取出其位置,尺度,方向資訊。SIFT的應用範圍包括物體辨識,機器人地圖感覺與導航,影像拼接,3D模型建立,手勢識别,影像追蹤等。

2.1.1 SIFT算法具有的特征

  圖像的局部特征,對旋轉,尺度縮放,亮度變化保持不變,對視角變化,仿射變換,噪聲也保持一定程度的穩定性。

  • 1,對旋轉,尺度縮放,亮度變化保持不變性,對視角變化,噪聲等也存在一定程度的穩定性
  • 2,獨特性,資訊量豐富,适用于在海量特征資料中進行快速,準确的比對
  • 3,多量性,即使少數幾個物體也可以産生大量的SIFT特征向量
  • 4,可擴充性,可以很友善的與其他形式的特征向量進行聯合

  SIFT算法的實質是在不同的尺度空間上尋找關鍵點(特征點),計算關鍵點的大小,方向,尺度資訊,利用這些資訊組成關鍵點對特征點進行描述的問題。SIFT所查找的關鍵點都是一些十分突出,不會因光照,仿射變換和噪聲等因素而變換的“穩定”特征點,如角點,邊緣點,暗區的亮點以及亮區的暗點等。比對的過程就是對比這些特征點的過程,這個流程可以用下圖表述:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

2.2 SIFT特征提取和比對的具體步驟

  首先,我們寫出SIFT特征提取和比對的步驟,如下:

  • 1,生成高斯差分金字塔(DOG金字塔),尺度空間建構
  • 2,尺度空間的極值檢測(關鍵點的初步查探)
  • 3,穩定關鍵點的精确定位(特征點定位)
  • 4,穩定關鍵點方向資訊配置設定(特征方向指派)
  • 5,關鍵點描述(特征點描述)
  • 6,特征點比對

  關于高斯金字塔的具體原理,可以參考如下部落格:

OpenCV計算機視覺學習(7)——圖像金字塔(高斯金字塔,拉普拉斯金字塔,圖像縮放resize()函數)

2.2.1 生成高斯差分金字塔(DOG金字塔),尺度空間建立

  (尺度空間建構的基礎是 DOG金字塔,而DOG金字塔是由高斯金字塔變換得到,關于高斯金字塔的部落格請參考:

OpenCV計算機視覺學習(7)——圖像金字塔(高斯金字塔,拉普拉斯金字塔,圖像縮放resize()函數)

  在一定的範圍内,無論物體是大還是小,人眼都可以分辨出來,然而計算機要有相同的能力卻很難,是以要讓機器能夠對物體在不同尺度下有一個統一的認知,就需要考慮圖像在不同的尺度下都存在的特點。

  尺度空間的擷取通常使用高斯濾波來實作:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  其中G是高斯函數,高斯函數公式如下:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  尺度空間的擷取即給一個圖像的不同點配置設定不同的權重,下面以5*5的高斯核為例,我們從下圖可以看到不同點配置設定的權重是不同的。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  當不同Sigma的高斯函數決定了對圖像的平滑程度,越大的Sigma值對應的圖像越模糊:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  高斯差分金字塔(DOG)的建立如下:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  每一組在層數上,DOG金字塔比高斯金字塔少一層。後續Sift特征點的提取都是在DOG金字塔上進行的。

  DOG定義公式:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  主要實作是通過對原始圖像進行尺度變換,獲得圖像多尺度下的尺度空間表示序列,對這些序列進行空間主輪廓的圖區,并以該主輪廓作為一種特征向量,實作邊緣,角點檢測不同分辨率上的關鍵點提取等。

2.2.2 DOG 空間極值點檢測(關鍵點的初步查探)

  搜尋所有尺度空間上的圖像,通過高斯微分函數來識别潛在的對尺度和選擇不變的興趣點。

  為了尋找尺度空間(DOG函數)的極值點,每個像素點要和其圖像域(同一尺度空間)和尺度域(相鄰的尺度空間)的所有相鄰點進行比較,當其大于(或小于)所有相鄰點時,該點就是極值點。如下圖所示:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  在二維的圖像中,中間的檢測點要和其所在圖像的3*3鄰域8個像素點,以及其相鄰的上下兩層圖像(在同一組内的尺度空間上)的3*3領域的18 個像素點,共 26個像素點進行比較。如此可以保證檢測到的關鍵點在尺度空間和二維圖像空間上都是局部極值點。

2.2.3 穩定關鍵點的精确定位

  DOG 值對噪聲和邊緣比較敏感,是以在第2步的尺度空間中檢測到的局部極值點還要經過進一步的篩選,去除不穩定和錯誤檢測出的極值點,另一點就是在建構高斯金字塔過程中采用了下采樣的圖像,在下采樣圖像中提取的極值點對應在原始圖像中的确切位置,也是要在本步驟中解決的問題。

  在每個候選的位置上,通過拟合精細模型來确定位置尺度,關鍵點的選取依據他們的穩定程度。這些候選關鍵點是DOG空間的局部極值點,而且這些極值點均為離散的點,精确定位極值點的一種方法是,對尺度空間的 DOG 函數進行曲線拟合,計算其極值點,進而實作關鍵點的精确定位。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  可以利用泰勒級數進行展開:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)
圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)
圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)
圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

消除邊界響應

  Hessian矩陣:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  令 α = λmax 為最大的特征值,β = λmin最小的特征值

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)
圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  Lower 在論文中給出 γ = 10,也就是說對于主曲率比值大于10的特征點将被删除。

2.2.4 穩定關鍵點方向資訊配置設定(特征點的主方向)

  穩定的極值點是在不同尺度空間下提取的,這保證了關鍵點的尺度不變性。為關鍵點配置設定方向資訊所要解決的問題是使得關鍵點對圖像角度和旋轉具有不變形。方向的配置設定是通過求每個極值點的梯度來實作的。

  對于任一關鍵點L(x, y)的梯度幅值(梯度的模) m(x, y) 以及梯度方向 Θ(x, y):

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)
圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  每個特征點可以得到三個資訊(x, y, σ, Θ),即位置,尺度和方向。具有多個方向的關鍵點可以被複制成多份,然後将方向值分别賦予複制後的特征點,一個特征點就産生了多個坐标,尺度相等,但是方向不同的特征點。

  分類給關鍵點的方向并不直接是關鍵點的梯度方向,而是按照一種梯度方向直方圖的方式給出的。具體的方法是:計算以關鍵點為中心的領域内所有點的梯度方向,當然梯度方向一定是在 0~360度範圍内,對這些梯度方向歸一化到 36 個方向内,每個方向代表了 10度的範圍。然後累積落到每個方向内的關鍵點個數,以此生成梯度方向直方圖。

  在完成關鍵點的梯度計算後,使用直方圖統計鄰域内像素的梯度和方向

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  将梯度方向直方圖中縱坐标最大的項代表的方向配置設定給目前關鍵點作為主方向,若在梯度直方圖中存在一個相當于主峰值 80% 能量的峰值,則将這個方向認為是關鍵點的輔助方向。輔助方向的設計可以增強比對的魯棒性,Lowe指出,大概有 15% 的關鍵點 具有輔方向,而恰恰是這 15%的關鍵點對穩定比對起到關鍵作用。

2.2.5 生成關鍵點特征描述

  對關鍵點的描述是後續實作比對的關鍵步驟,描述其實就是一種以數學方式定義關鍵的過程。描述子不但包含關鍵點,也包含關鍵點周圍對其有貢獻的鄰域點。

  為了保證特征矢量的旋轉不變性,要以特征點為中心,在附近領域内将坐标軸旋轉 Θ 角度,即将坐标軸旋轉為特征點的主方向。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)
圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  旋轉之後的主方向為中心取8*8的視窗,求每個像素的梯度幅值和方向,箭頭方向代表梯度方向,長度代表梯度幅值,然後利用高斯視窗對其進行權重運算,最後在每個4*4的小塊上繪制8個方向的梯度直方圖,計算每個梯度方向的累加值,即可形成一個種子點,即每個特征由4個種子點組成,每個種子點有8個方向的向量資訊。

  如下圖,對于2*2塊,每塊的所有像素點的梯度做高斯權重,每塊最終取8個方向,即可以生成 2*2*8 次元的向量,以這 2*2*8 維向量作為中心關鍵點的數學描述。

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

  論文中(David G.Lowed的實驗結果)建議對每個關鍵點使用 4*4 共 16個種子點來描述,這樣一個關鍵點就産生 128 維的SIFT特征向量。即采用128維向量的描述子進行關鍵點表征,綜合效果最佳:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

2.2.6 特征點比對

  特征點的比對通過計算兩組特征點的 128 維的關鍵點的歐式距離實作的。歐式距離越小,則相似度越高,當歐式距離小于設定的門檻值時,可以判定為比對成功。

2.3,Python實作SIFT特征檢測

2.3.1 更新opencv的安裝包

  3.4.3 以上 就進入了專利保護的階段,一些函數已經用不了,他們申請專利了,我們需要降版本。

  是以如果我們的版本大于3.4.3, 則需要降版本,目前最穩定的可以使用SIFT的opencv版本為3.4.1.15。

pip install opencv-python==3.4.1.15

pip install opencv-contrib-python==3.4.1.15
           

  3.4.1.15 使用SIFT函數是沒有任何問題的。

  安裝好之後,我們下面實作SIFT特征檢測。

2.3.2 SIFT代碼實作

  得到關鍵點之後,我們需要計算出特征,kp不能直接列印,因為是list格式,我們需要轉換為np.array()格式。

  拿到所有的向量點為 128次元 6827個特征點。

  代碼如下

import cv2
import numpy as np

img = cv2.imread('test_1.jpg')
print('imgshape', img.shape)
# imgshape (800, 1200, 3)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# gray = np.float32(gray)

# 得到特征點
sift = cv2.xfeatures2d.SIFT_create()
kp = sift.detect(gray, None)
# kp 是封裝好的東西,我們看不見,隻能展示

img = cv2.drawKeypoints(gray, kp, img)

img = cv2.resize(img, None, fx=0.5, fy=0.5)
cv2.imshow('dst', img)
cv2.waitKey(0)
cv2.destroyAllWindows()


# 計算特征
kp, des = sift.compute(gray, kp)  
print(np.array(kp).shape)  # (6827,)
print(des.shape)  # (6827, 128)
print(des[0])

'''
[  0.   0.   0.   0.   0.   0.   0.   0.  21.   8.   0.   0.   0.   0.
   0.   0. 157.  31.   3.   1.   0.   0.   2.  63.  75.   7.  20.  35.
  31.  74.  23.  66.   0.   0.   1.   3.   4.   1.   0.   0.  76.  15.
  13.  27.   8.   1.   0.   2. 157. 112.  50.  31.   2.   0.   0.   9.
  49.  42. 157. 157.  12.   4.   1.   5.   1.  13.   7.  12.  41.   5.
   0.   0. 104.   8.   5.  19.  53.   5.   1.  21. 157.  55.  35.  90.
  22.   0.   0.  18.   3.   6.  68. 157.  52.   0.   0.   0.   7.  34.
  10.  10.  11.   0.   2.   6.  44.   9.   4.   7.  19.   5.  14.  26.
  37.  28.  32.  92.  16.   2.   3.   4.   0.   0.   6.  92.  23.   0.
   0.   0.]
'''
           

  圖如下:

圖像特征點檢測之Harris角點檢測、sift算法(OpenCV計算機視覺)

2.3.3 opencv中SIFT 函數中keypoint 資料結構分析

  分析opencv中keypoint資料結構的相關資訊,我們首先找到opencv的官方文檔:

http://docs.opencv.org/java/org/opencv/features2d/KeyPoint.html

  可以看到KP的資料結果中有如下關鍵點:

  • angle:角度,表示關鍵點的方向,通過 Lowe 大神的論文可以知道,為了保證方向不變形,SIFT算法通過對關鍵點周圍領域進行梯度運算,求得該點方向,-1為初始值。
  • class_id:當要對圖像進行分類時,我們可以用 class_id 對每個特征點進行區分,未設定時為 -1,需要靠自己設定。
  • octave:代表是從金字塔哪一層提取得到的資料
  • pt:關鍵點點的坐标
  • response:響應程度,代表該點強壯大小
  • size:該點直徑大小

  注意:Keypoint隻是儲存了opencv的sift庫檢測到的特征點的一些基本資訊,也就是上面所說的這些,但sift所提取出來的特征向量其實不在這裡面。特征向量是通過SiftDescriptorExtractor 提取,結果放在一個 Mat 的資料結構中。這個資料結構才真正儲存了該特征點所對應的特征向量。

參考位址:https://blog.csdn.net/yangleo1987/article/details/53261637

https://blog.csdn.net/Sakura55/article/details/81506151

https://blog.csdn.net/dcrmg/article/details/52577555

https://www.cnblogs.com/cj695/p/4041399.html

https://www.cnblogs.com/cj695/p/4045443.html

https://wenku.baidu.com/view/b0a2788acc22bcd126ff0c48.html

https://www.cnblogs.com/ronny/p/3886013.html

結語

喜歡學習人工智能方向的小夥伴,可以點贊關注我哦~

繼續閱讀