OpenCV計算機視覺學習(13)——影像特徵點檢測(Harris角點檢測,sift演算法)

戰爭熱誠發表於2021-03-04

如果需要處理的原圖及程式碼,請移步小編的GitHub地址

  傳送門:請點選我

  如果點選有誤:https://github.com/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,角點的定義

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

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

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

   從圖中可以看出:

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

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

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

  下面看一下角點的型別:

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中,視窗內影像的灰度沒有發生變化,那麼視窗內就不存在角點;如果視窗在某一個方向移動時,視窗內影像的灰度發生了較大的變化,而在另一些方向上沒有發生變化,那麼,視窗內的影像可能就是一條直線的線段。

1.2,Harris角點檢測數學推導

  根據演算法思想,Harris演算法是利用視窗內影像灰度的自相關性進行的,設計一個視窗在影像中移動,構建數學模型,計算移動視窗的灰度差值(即移動前和移動後視窗所在區域影像的自相關係數)。

  Harris演算法是利用的視窗內影像灰度的自相關性進行的,設定一個視窗,並在影像中移動,計算移動前與移動後視窗所在區域影像的自相關係數。

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

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

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

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

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

  將近似值代入自相關函式,有:

  將平方項展示並寫成矩陣形式,有:

  回到自相關表示式:

  近似可得下面表達:

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

   化簡可得:

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

1.2.1  橢圓的矩陣方差表示

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

  其橢圓方程式如下:

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

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

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

  用M表示引數:

  所以橢圓方程為:

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

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

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

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

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

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

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

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

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

1.2.3  角點響應R值

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

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

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

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

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

1.3,Harris 角點檢測演算法流程

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

  程式碼中如果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相對比較簡單,畫素相乘即可。

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

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

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

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

   裡面沒有隨意給定的引數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響應的極值點出現的位置,但是,由於閾值的選擇,可能會影響角點檢測的數量。

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

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

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

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

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 大,則表示為角點,我們拿到其角點。

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

   再看一張圖,效果如下:

 

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所查詢的關鍵點都是一些十分突出,不會因光照,仿射變換和噪聲等因素而變換的“穩定”特徵點,如角點,邊緣點,暗區的亮點以及亮區的暗點等。匹配的過程就是對比這些特徵點的過程,這個流程可以用下圖表述:

2.2  SIFT特徵提取和匹配的具體步驟

  首先,我們寫出SIFT特徵提取和匹配的步驟,如下:

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

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

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

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

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

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

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

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

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

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

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

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

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

  DOG定義公式:

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

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

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

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

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

2.2.3  穩定關鍵點的精確定位

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

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

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

消除邊界響應

  Hessian矩陣:

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

  Lower 在論文中給出 γ = 10,也就是說對於主曲率比值大於10的特徵點將被刪除。

2.2.4  穩定關鍵點方向資訊分配(特徵點的主方向)

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

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

  每個特徵點可以得到三個資訊(x, y, σ, Θ),即位置,尺度和方向。具有多個方向的關鍵點可以被複製成多份,然後將方向值分別賦予複製後的特徵點,一個特徵點就產生了多個座標,尺度相等,但是方向不同的特徵點。

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

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

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

2.2.5  生成關鍵點特徵描述

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

   為了保證特徵向量的旋轉不變性,要以特徵點為中心,在附近領域內將座標軸旋轉 Θ 角度,即將座標軸旋轉為特徵點的主方向。

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

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

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

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.]
'''

   圖如下:

 

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

相關文章