天天看點

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

作者:IT智能化專欄

文章目錄

  • ⭐️項目前言
  • ⭐️圖像特征檢測Harris原理
  • ⭐️圖像特征檢測SIFT原理
  • ⭐️圖像特征比對實戰

⭐️項目前言

對于圖像特征檢測的應用場景有很多,比如目标檢測、物體識别、三維重建、圖像配準、圖像了解。我們可以識别出來一些特定的關鍵點來讓計算機認識圖像的某些特征,該應用也應用于目前較為火熱的人臉識别技術當中。後續我們我介紹一下有關于人臉識别的項目實戰。這節課先跟着我,做一下這個圖像特征如何檢測的,它是基于什麼原理。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

⭐️圖像特征檢測Harris原理

  • 角點:在圖像的角度來看,無論是沿着水準方向還是豎直方向進行移動時候,灰階級會發生變化,而且這個變化是非常迅速的,我們稱這個圖像就是一個角點。
  • 邊界:在圖像的角度上來看,指把圖像按照水準或者垂直方向移動的時候,隻有一個一個方向變化的比較明顯,另一個方向變化就比較微弱,這樣的我們就稱之為邊界。
  • 平面:平面就是說無論向垂直方向還是水準方向移動,圖像的灰階值都不會發生迅速的變化,這個就是平面。
計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

原理圖,這裡第一個圖表示的就是平面灰階值沒有明顯變化,第二個圖就是要給邊界灰階值水準方向變化明顯垂直方向灰階值變化并不明顯,第三個圖表示的就是一個角點,無論水準還是垂直方向都很明顯。主要看灰階級的變化結果:

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

對于圖像l(x,y),當在點(x,y)處平移(▲x,▲y)後的圖像灰階級的相似性是:

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

這裡就是w(u,v)表示權重矩陣,而I就表示圖像的灰階級後面表示圖像灰階值的內插補點,變化程度。假設圖像l(x,y)為3*3,那麼就有9個像素點x1-x9,當移動之後,那麼我們就得到了一個新的像素點集合z1-z9,我們要對其進行一個像素值的減法操作。其中W(u,v)表示權重矩陣項,他是一個以(x,y)為中心的一個視窗,可以是常數也可以是高斯權重函數。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

第一個圖就是使用常數的一個視窗,沒有什麼變化,對于3*3的九個點都平等對待。但是對于高斯權重函數來說,他是一個越靠近中心點的權重就越大的一個函數。就類似于這樣。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

而我們一般都使用高斯權重函數。當▲x,▲y變化的都相對較小的時候,我們将圖像平移由(x,y)移動(▲x,▲y)後進行一個一階近似,泰勒展開公式:

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

這裡我們使用泰勒公式展開之後呢?就把(▲x,▲y)的變化認為很小很小,就給直接省略了。其中Ix和Iy就是對于x,y的偏導數。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

這裡我們主要看這裡,因為前面是一個不變的數值,是以我們将這裡做一個平方,防止像素值相減後負值對結果的影響。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

這裡M(x,y)就是,當我們求出來這個M矩陣,那麼對于他是怎麼變化的是不是就清楚了:

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

化簡一下代回原式子就是:

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

這裡我們根據自己學習過的線性代數知識,對其進行對角化,可以得到lamda1=1/a2,lamda2=1/b2:肯定會得到兩個特征值,特征向量。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

這裡我們就可以把角點表示成這樣,就是lamda的兩個值變化的都快,那麼他就是角點。一個變化較快一個比較慢,那麼就是邊界,如果都比較緩慢,那麼就是一個平面。

邊界:一個特征值大,一個特征值小,自相關函數在某一個方向上大,在其他方向上小。

平面:兩個特征都小,且近似相等。

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

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

在OpenCV當中我們使用,cv2.cornerHarris()來進行角點檢測。

其中參數都有:

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

    我們使用幾個小圖像去做一下角點檢測:

import cv2 
import numpy as np

img = cv2.imread('white-black.webp')
print ('img.shape:',img.shape)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# gray = np.float32(gray)
dst = cv2.cornerHarris(gray, 2, 3, 0.04)
print ('dst.shape:',dst.shape)
img[dst>0.01*dst.max()]=[0,0,255]
cv2.imshow('dst',img) 
cv2.waitKey(0) 
cv2.destroyAllWindows()
12345678910111213           
計算機視覺項目_3、圖像特征檢測harris、sift、特征比對
計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

這裡有一些點檢測的不是特别好,然後我們用黑白棋盤來看一下。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

這個效果堪稱完美!!!

⭐️圖像特征檢測SIFT原理

SIFT是指尺度空間:是指在一定的範圍内,無論物體是大是小,人眼都可以進行一個識别,然後計算機要去識别卻很難,是以要讓計算機能夠對物體進行一個在不同尺度下都存在一個統一的認知,就要考慮圖像在不同的尺度在都存在的特點,尺度空間的擷取一般使用高斯模糊來實作-高斯濾波。

我們再說說SIFT有什麼優點:

1、具有較好的穩定性和不變性,能夠适應旋轉、尺度縮放、亮度的變化,能在一定程度上不受視角變化、仿射變換、噪聲的幹擾。

2、區分性好,能夠在海量特征資料庫中進行快速準确的區分資訊進行比對

3、多量性,就算隻有單個物體,也能産生大量特征向量

4、高速性,能夠快速的進行特征向量比對

5、可擴充性,能夠與其它形式的特征向量進行聯合

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

我們都知道如果圖檔經過高斯濾波操作之後呢,他會變模糊,那麼為什麼要這麼做呢?因為當我們從很近的看一個人的時候,他是清晰的,那麼從很遠看的時候他就是模糊的。是以我們為了模拟這個過程,就用高斯濾波來進行相同了一個模拟。

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

是以我們要介紹一個金字塔,高斯差分金字塔。

我們需要做一個多分辨率的金字塔,對于金字塔的每一層都要做高斯濾波。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

根據意思就是5個輸入的高斯圖像,相鄰的進行像素值相減,得到4張差分後的結果。那麼我們想要找什麼呢?找SIFT,就是特征點,那麼什麼樣的點被認為是特征點呢?通常關鍵點數值較大、差分結果較大的、極值裡面較大的。是不是有點像之前講的圖像金字塔。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

為了尋找尺度空間的極值點,每個像素點要和其圖像域(同一尺度空間)和尺度域(相鄰的尺度空間)的所有相鄰點進行比較,當其大于(或者小于)所有相鄰點時,該點就是極值點。如下圖所示,中間的檢測點要和其所在圖像的3×3鄰域8個像素點,以及其相鄰的上下兩層的3×3領域18個像素點,共26個像素點進行比較。因為這個極值點需要上下都有圖檔闆子,是以最上面的和最下面的無法生成DOG。

這些候選關鍵點是DOG空間的局部極值點,而且這些極值點均為離散的點,精确定位極值點的一種方法是,對尺度空間DoG函數進行曲線拟合,計算其極值點,進而實作關鍵點的精确定位。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

然後我們對其進行曲線拟合。對于二維空間來說拟合公式就是這樣

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

那麼如果上升到三維空間來說,就是這樣的公式;

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

這裡我們就可以求到真正的極值點。

對于一些特征點,我們還要進行一個過濾,比如說我們要消除邊界響應。

Hessian矩陣:

我們在講harris的時候,已經介紹過了得到的檢測角點,邊界的矩陣就差不多是這個。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

然後我們對其進行了對角化,a=lmax表示最大的特征值,b=lmin為最小的特征值。

如果有a/b>10,我們就認定為這個點很接近邊界了。此時我們要将對于主曲率比值大于10的特征點進行删除。

進行了如上的操作之後,我們就得到了最後想要的關鍵點。我們還要找一個特征點的方向,因為我們當驗證兩個圖象是否相似的時候,不僅僅要從數值上下手,還要從方向上才會更加準确。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

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

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

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

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

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

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

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

論文中建議對每個關鍵點使用4x4共16個種子點來描述,這樣一個關鍵點就會産生128維的SIFT特征向量。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對
import cv2
import numpy as np
img = cv2.imread('test_1.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.__version__
sift = cv2.SIFT_create()
kp = sift.detect(gray, None)
img = cv2.drawKeypoints(gray, kp, img)
cv2.imshow('drawKeypoints', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
kp, des = sift.compute(gray, kp)
print (np.array(kp).shape)
des.shape
des[0]
123456789101112131415           

導入圖像,然後進行顔色空間轉換。并看一下cv2的版本。然後求了一下sift,最後展示了一下特征第一個。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對
計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

⭐️圖像特征比對實戰

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對
import cv2 
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
img1 = cv2.imread('box.png', 0)
img2 = cv2.imread('box_in_scene.png', 0)
def cv_show(name,img):
    cv2.imshow(name, img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
cv_show('img1',img1)
cv_show('img2',img2)
sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)
bf = cv2.BFMatcher(crossCheck=True)
12345678910111213141516           
計算機視覺項目_3、圖像特征檢測harris、sift、特征比對
計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

首先我們導入一個具體圖像和一個整體圖像,用于做特征比對。原理就是使用sift分别識别處關鍵點,然後對關鍵點進行一個比對。我們具體看一下實戰結果。kp1, des1 = sift.detectAndCompute(img1, None)這裡我們得到關鍵點和向量資訊,得到特征向量。然後使用特征向量進行比對。bf = cv2.BFMatcher(crossCheck=True)crossCheck表示兩個特征點要互相匹,例如A中的第i個特征點與B中的第j個特征點最近的,并且B中的第j個特征點到A中的第i個特征點也是

NORM_L2: 歸一化數組的(歐幾裡德距離),如果其他特征計算方法需要考慮不同的比對計算方式。

matches = bf.match(des1, des2)
matches = sorted(matches, key=lambda x: x.distance)
12           

對關鍵點進行一一比對。一對一比對。

img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:10], None,flags=2)
cv_show('img3',img3)
12           
計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

然後一對多進行比對。

bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)
good = []
for m, n in matches:
    if m.distance < 0.75 * n.distance:
        good.append([m])
img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2)
cv_show('img3',img3)
12345678           
計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

一個點對應最近的兩個點。

然後我們又做了一個圖像的特征比對。一對一的。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

然後我們做了我的特征比對。

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

最終的結果是:

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

多比對的結果是

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

檢測的非常完美!!!這裡我們就把這個圖像特征比對講解完了。讓計算機去識别物體,人臉,所有的圖像!!!

計算機視覺項目_3、圖像特征檢測harris、sift、特征比對

繼續閱讀