Harris角點檢測數學計算過程與CornerHarris方法參數的一點說明【DataWhale學習記錄】

1 基礎知識

1.1 圖像梯度的解釋

  1. 圖像的梯度與數學中的梯度在形式上是由差異的,原因在於圖像的特點,圖像是一個離散的二維函數,接下來會嘗試說明這一點,但從意義上來說是相同的,是爲了表現圖像灰度的變化率
  2. 在數學微積分中,一維函數的一階微分的基本定義是:
    一維函數的一階微分的基本定義
    二維函數的一階微分的基本定義是:
    二維函數的一階微分的基本定義
    對於灰度圖這樣二維數組的圖像,它其實就是一個離散的二位函數,說它離散,是因爲每個灰度值取值爲整數而不是小數,因此ϵ不能無限小,而ϵ的最小單位即是1像素。因此當ϵ取最小值1時,灰度圖(離散的二維函數)的一階微分基本定義是:
    灰度圖(離散的二維函數)的一階微分基本定義
    我們可以觀察到,圖像在(x, y)點處x方向和y方向上的梯度相當於2個相鄰像素之間的差值。而且一般地,我們會使用兩個方向上梯度的絕對值,因爲我們只關心圖像的灰度值變化大小,而梯度方向只需要知道是水平還是垂直即可,無須知曉到底是具體是向左還是向右,向下還是向上。
  3. 計算圖像某點的梯度。
    上面,我們介紹了圖像某個點的水平梯度gx和垂直梯度gy的計算方式,而將兩者結合起來即可得到圖像中該點的梯度的大小與方向。
    a. 計算梯度的大小,在數學上,這種結合的公式是:
    M(x,y)=(gx)2+(gy)2M(x,y) = \sqrt{(gx) ^2+ (gy)^2}
    但是圖像處理中經常使用以下方式(用絕對值加和來近似平方和平方根)來減小計算開支。
    M(x,y)=gx+gyM(x,y) = |gx| + |gy|
    b. 計算梯度的方向
    arctan[fyfx]arctan[\dfrac {\frac {\partial f} {\partial y}} {\frac {\partial f} {\partial x}}]
    再進一步擴展,圖像的梯度也常用來判斷某個窗口區域是平坦、邊緣還是角點。而在邊緣檢測中,圖像某一點的梯度方向是與邊緣方向相垂直的,所以知道了梯度的方向,就曉得了邊緣的方向,在以後的邊緣檢測、輪廓檢測等知識中會用到。
    最後,希望大家記住梯度的計算是以每一個像素點爲中心,而非一個區域(比如 3×3)。

參考文章:
圖像梯度的基本原理.
canny算法(2)——圖像梯度的計算(sobel算子)

1.2 Sobel算子簡介

  1. sobel算子用來檢測主體與主體之間的邊緣特徵,其效果有點類似高斯濾波,能夠使得離中心點越近的像素權重越大,越重要
  2. 需要解釋的是,我們剛纔介紹了,圖像在某一點A的梯度,只需要計算其相鄰兩個像素點的差值即可得到X方向Y方向上的梯度;
    但爲了更加合理的判斷某一點的梯度大小,需要藉助算子爲這個以點A爲中心的ksize×ksize區域(一般是ksize取3或5或者其他奇數)添加權重,來擴大差異,增強邊緣檢測效果
    而且在運用中,因爲計算一點的梯度需要藉助周邊區域的多個點的灰度值,因而對圖像中的噪點比較敏感,因此時常在調用sobel方法進行計算之前,需要先借助高斯濾波器或者其他濾波器對原圖像進行平滑\模糊處理以降噪
    所以完整的Sobel梯度計算過程是:1.高斯濾波器對原圖像平滑降噪GaussianBlur 2.轉灰度圖cvtColor3.求X和Y方向的梯度Sobel
  3. sobel算子的形式
    sx=[101202101]s_x = \left[ \begin{matrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{matrix} \right]
    sy=[121000121]s_y = \left[ \begin{matrix} -1 & 2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{matrix} \right]
  4. 在OpenCV - Python 中,調用cv2.Sobel方法,一般的sobel算子是,右減左,下減上,進而得到圖像中某一點的x方向上的梯度或者y方向上的梯度。另外,因爲進行減法操作後不一定得到的是正值,也可能是負值,但是uint8不允許負值的存在,因此要指定ddepth = cv2.CV_64F 以包容負值的存在(eg:cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)),此時進行圖像的展示,會先將數組中的負值視爲0。但是隨後會調用其他方法(cv2.convertScaleAbs)以進行絕對值化的操作,此時進行展示時,會使得負值轉化爲正值,得到我們完整的特徵圖。
  5. sobel算子的計算梯度的數學計算類似於卷積神經網絡的卷積計算,而具體的計算過程參考sobel算子原理與實現.在此需要注意,sobel算子是算梯度的,雖然計算涉及很多的像素點,但是它計算的結果是一個值,是計算區域中心座標的梯度值!
  6. sobel算子的計算梯度時,對於邊緣點的梯度,一般會做填充處理,即如果算子核大小爲3的話,會在圖像四邊界填充一層像素值爲0的點。
  7. 不明之處:我們這篇文章其實是打算講CornerHarris的參數的。而sobel算子是Harris角點檢測過程中使用的算子,但是CornerHarris的參數中似乎只能指定sobel算子的大小即ksize,而不能指定具體使用的核是啥,而這一點有待深挖,因爲我也看到過自定義算子,比如,高斯濾波器曾作爲圖像降噪的方式,也可用來計算梯度並賦予到某些方法(eg.erode)中的情況。

參考文獻:
OpenCV-Python教程
Sobel邊緣檢測
canny算法(2)——圖像梯度的計算

1.3 濾波器

  1. 主要想推薦一篇文章圖像平滑去噪之高斯濾波器。具體的濾波器內容內容比較廣泛,讀者自行學習。
  2. 高斯濾波器的形式。由於高斯濾波實質是一種加權平均濾波,爲了實現平均,核還帶有一個係數,例如上圖中的十六分之一、八十四分之一。這些係數等於矩陣中所有數值之和的倒數。相比之下,sobel算子的核在計算時,只是簡單的加權求和。
    高斯濾波器
  3. 高斯濾波的特點。因爲高斯濾波是以空間距離來確定權重大小的,但並沒有考慮用顏色距離來確定權重,這樣就導致了高斯濾波在去除噪聲的同時,也一定程度上模糊了邊界。
    高斯濾波器的特點,模糊

2 Harris角點檢測過程與非嚴謹性數學推導

2.1 角點以及角點檢測過程

  1. 之前講過圖像梯度,而通過梯度可以進行邊緣檢測,除此之外,還可以檢測角點。系統地來說,一個圖像根據圖像灰度值變化大小地不同可以分爲三個級別:平坦區域、邊緣位置和角點三類。當然,分類也是根據具體的值,這個可以根據之後出現的參數進行人爲的調整。
    而三種類型的特點是:
    • 角點(特徵點)是當窗口向各方向移動,都會引起像素值發生很大變化的一個位置點;
    • 邊緣特徵是僅當窗口單方向上來回移動,纔會引起像素值發生較大變化的一個位置區域;
    • 平坦區域是無論窗口移動方向如何,都不會引起像素值發生很大的變化的區域
      參考圖像:
      角點
      這個地方不多介紹,角點不懂的可以自行學習。以下內容多少有點跳躍,建議多看幾篇詳細介紹角點檢測的文章,再閱讀下文。
  2. 角點檢測過程

2.2 角點檢測過程概述

  1. 需要注意的是,本文的角點檢測過程,會穿插OpenCV中Cornerharris方法的參數的介紹與思考。因此對於不曉得該方法的讀者,遇到相關文字時,先掠過。
  2. 先介紹以下CornerHarris方法的API
    cv2.cornerHarris(img,blocksize,ksize,k)
    a. img 一般時二維的灰度圖,float32的輸入圖像。
    b. blocksize 角點檢測中的窗口大小
    c. ksize sobel算子的大小
    d. 取值一般在[0.04,0.06]之間,而其時響應函數R中的一個參數。
  3. 角點檢測過程與數學推導
  • 計算每個blocksize大小的窗口的灰度值變化大小(但實際上最後間接的去求了自相似函數的特徵值)。
  • 計算響應函數R
  • R值與閾值比較,判斷每個窗口下是否包含角點。

2.2.1 計算每個blocksize大小的窗口的灰度值變化大小

2.2.1.1

計算每個blocksize大小的窗口的灰度值變化(也可以稱爲“自相似性”)。而變化值可以由自相似函數給出。
自相似函數
其中,W(u,v)W(u,v)是以點(u,v)(u,v)爲中心的窗口,既可以是常數,又可以是高斯加權函數。
在這裏插入圖片描述

w(u,v)w(u,v)是一個權重矩陣,shape大小爲blocksize,注意它並不是sobel算子,確切地說,他們都是權重矩陣,但是目的並不同,用處不同,sobel算子用於計算每一個點的梯度,ww則用於反映窗口灰度值總體變化大小中各帶位置的像素點的權重、貢獻度如何。所以ksize和blocksize並不是一回事,且沒有關係
w(u,v)w(u,v)由常數或者高斯加權構成時,常常分別爲以下兩種:
[111111111]\left[ \begin{matrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{matrix} \right]
116[121242121]\frac 1 {16} \left[ \begin{matrix} 1 & 2 & 1 \\ 2 & 4 & 2 \\ 1 & 2 & 1 \end{matrix} \right]
但是似乎在cornerHarris中無法人爲指定具體權重,只能指定blocksize。
(u,v)(u,v)是窗口區域中點的座標,如果blocksize=3,則(u,v)(u,v)一共有9個。

ΔxΔy\Delta x \Delta y表示每個(u,v)(u,v)向右向下的移動單位,而其基本單位是1像素。

I(u,v)I(u,v)表示圖像中在(u,v)(u,v)點的灰度值。

至此,對於自相似函數的計算,在指定blocksize,給定img後,僅I(u+Δx,v+Δy)I(u+\Delta x,v+\Delta y) 不知如何求解。

2.2.1.2

》》而這個項式的計算,需要藉助泰勒公式的一階展開式近似計算。
I(u+Δx,v+Δy)=I(u,v)+Ix(u,v)Δx+Iy(u,v)Δy+o(Δx2,Δy2)I(u+\Delta x,v+\Delta y) =I(u,v) + I_x(u,v) \Delta x+I_y(u,v) \Delta y+o({\Delta x}^2,{\Delta y}^2)

此時,I(u+Δx,v+Δy)I(u,v)Ix(u,v)Δx+Iy(u,v)ΔyI(u+\Delta x,v+\Delta y) - I(u,v) \approx I_x(u,v) \Delta x+I_y(u,v) \Delta y ,可以看出I(u,v)I(u,v)被抵消,而o(Δx2,Δy2)o({\Delta x}^2,{\Delta y}^2)佩亞諾餘項作爲高階無窮小,可以被忽略掉,因此上式爲近似求解。

同時,注意此時的Ix(u,v)Iy(u,v)I_x(u,v) I_y(u,v)即是我們之前講的每一個點的水平梯度值和縱向梯度值
但是即使如此,我們還是不能很好的處理ΔxΔy\Delta x \Delta y的取值。

由此需要藉助線性代數中的二次型來間接解決這麼個問題,而之所以說是間接解決自相似函數的計算問題,是因爲利用二次型是用來計算特徵值,再通過響應函數R可計算得到score分數,以用來跟系統設定的閾值比較判斷是否該窗口中包含角點。而在這個過程中,包括特徵值的求解過程,ΔxΔy\Delta x \Delta y一直都沒有參與計算。

在具體解釋特徵值計算過程之前,需要解釋一個問題,爲什麼泰勒展開式要展開到一階而不是二階,原因很簡單,我們想通過泰勒展開式引入導數以實現近似的計算(因爲準確計算不可能),而一階二階等更高階都可以做到,只是計算二階導數會引起計算量的大大增加,且一階導數的近似效果已經足夠了。因此就沒有考慮二階展開式。

2.2.1.3

》》》接下來,進一步推算,開始前,先告訴大家,這一步是爲了求出自相似函數的特徵值,避免因爲其他內容的介紹而糊塗。
先展示一下泰勒展開式之後的自相似函數的近似結果:

c(s,y;Δx,Δy)w(Ix(u,v)Δx+Iy(u,v)Δy)2c(s,y;\Delta x,\Delta y) \approx \displaystyle \sum_{w}{(I_x(u,v) \Delta x+I_y(u,v) \Delta y)^2}

爲了簡潔,講w(x,y)w(x,y)先不具體展示出來了。被收納到了求和運算符下面。

然後,二次型的結果就是如此:
c(s,y;Δx,Δy)[Δx,Δy]M(x,y)[ΔxΔy]c(s,y;\Delta x,\Delta y) \approx [\Delta x ,\Delta y]M(x,y)\left[ \begin{matrix} \Delta x \\ \Delta y \end{matrix}\right]

其中

2.2.1.4

接下來的一小段內容是說:該自相似函數可以視爲一個橢圓,而橢圓的形狀與特徵值的大小相關
而對於
c(s,y;Δx,Δy)AΔx2+2CΔxΔy+BΔy2c(s,y;\Delta x,\Delta y) \approx A{\Delta x}^2 + 2C{\Delta x}{\Delta y} + B{\Delta y}^2,如果把c視爲一個常數,那麼這就是一個二次型方程,而二次型方程在二維圖像中就是一個橢圓。而常數的具體取值並不影響橢圓的形狀。而橢圓的形狀又恰好是我們要重點研究的,**準確的說是它的長短軸與我們想要求得特徵值密切相關。**因此在此我們姑且將該二次型方程視爲:
AΔx2+2CΔxΔy+BΔy2=1A{\Delta x}^2 + 2C{\Delta x}{\Delta y} + B{\Delta y}^2 = 1

其中,橢圓圖像因爲有2CΔxΔy2C{\Delta x}{\Delta y}的存在,而具有一定的傾斜程度。
參考圖像

圖來自二次型的意義是什麼?有什麼應用? - 馬同學的回答 - 知乎 非常讚的回答!推薦閱讀。

2.2.1.5

接下里這段是說,求特徵值爲什麼藉助矩陣,且特徵值的意義是什麼
首先,求特徵值爲什麼藉助矩陣,這個問題我不該問的,因爲求特徵值本身就需要藉助矩陣運算。
其次,特徵值或者確切說特徵矩陣意味這什麼?首先,矩陣代表着運動,且當矩陣維度沒有發生改變時,一個矩陣就包含了兩個運動:旋轉和拉伸。而如果想把這兩個運動分解,可以對矩陣進行正交化操作和特徵值分解,由此得到兩個矩陣正交矩陣和對角矩陣
在這裏插入圖片描述
正交矩陣就單純的意味着旋轉運動,而對角矩陣就單純地意味着左右上下拉伸運動。
在這裏插入圖片描述
而對於一個二次方程的二次型矩陣即M(x,y)更換成它對應的對角矩陣,則一個傾斜的橢圓就扶正了。
結合下圖進行理解上一段話,如果沒能理解,那一定不是你的原因,一定是我沒說清楚,具體可以參考文章:二次型的意義是什麼?有什麼應用? - 馬同學的回答 - 知乎
在這裏插入圖片描述

2.2.1.6

有了前面的基礎知識,我們不難理解,其實我上面的那麼多文字,有點囉嗦了。因爲只要我們知道了二次型矩陣,經過“特徵值分解”就可以得到對角矩陣,得到特徵值。
在這裏插入圖片描述
因爲是二維的矩陣,所以最後的特徵值只有兩個,而這兩個特徵值又對應了橢圓的長短軸關係
在這裏插入圖片描述
還記得之前提起過,一張圖像是由三類區域構成:

三種類型的特點是:
- 角點(特徵點)是當窗口向各方向移動,都會引起像素值發生很大變化的一個位置點;
- 邊緣特徵是僅當窗口單方向(要麼水平,要麼垂直方向)上來回移動,纔會引起像素值發生較大變化的一個位置區域;
- 平坦區域是無論窗口移動方向如何,都不會引起像素值發生很大的變化的區域

對應的,參考下面一張圖片內容:
在這裏插入圖片描述
也就是說,這兩個特徵值分別對應水平和垂直兩個方向。

如果某個窗口下在向水平方向移動時,水平特徵值很大,而在垂直方向上移動時,垂直特徵值較小,那麼表示,該窗口下存在一片區域是邊界特徵。

而如果某個窗口在水平和垂直方向上的特徵值都非常大,那麼就表示,該窗口下的一片區域存在角點

2.2.2 計算響應函數R

那麼最後的問題是,怎麼根據特徵值來衡量該窗口下存在的是角點還是其他其他。
注意,因爲我們這裏使用的是Harris角點檢測,所以從衡量方法上來看,我們只關注其是否是角點,而關注如果該窗口下不包含角點,那麼窗口下的區域到底是平坦還是邊界!
衡量方法即是:響應函數R。
R=detM(x,y)k(trM(x,y))2R = \mathrm{det} M^{(x,y)} - k \cdot \left ( \mathrm{tr} M^{(x,y)} \right )^2
我們看到了cornerHarris方法的第四個參數k,是由用戶自行指定的。

2.2.3 R值與閾值相比較,判斷該窗口下是否包含角點

注意這個閾值應該時內置的,但是爲了實現對角點檢測數量的控制,因此給R中添加了k參數,通過調整參數k,可以判斷窗口下識別的點是否可以稱得上是滿足自己要求的角點。

參考內容:
Opencv計算機視覺實戰(Python版)
Markdown / KaTex數學公式彙總
Harris特徵點檢測器-興趣點檢測|Task01
cornerHarris函數
還有一些文章在文中已經提及,再次就不再贅述。

至此,全部內容結束。第一次寫這麼多的博文,文章的佈局,我也盡力了。我也是看了很多的文章纔得到這樣的一個總結,我不是數學專業的學生,只是Opencv方向的小白,如果有錯誤,或者編輯上的不便,煩請賜教,哪怕只是提出問題!感謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章