1. sift = cv2.xfeatures2d.SIFT_create() 實例化
參數說明:sift為實例化的sift函數
2. kp = sift.detect(gray, None) 找出圖像中的關鍵點
參數說明: kp表示生成的關鍵點,gray表示輸入的灰度圖,
3. ret = cv2.drawKeypoints(gray, kp, img) 在圖中畫出關鍵點
參數說明:gray表示輸入圖片, kp表示關鍵點,img表示輸出的圖片
4.kp, dst = sift.compute(kp) 計算關鍵點對應的sift特征向量
參數說明:kp表示輸入的關鍵點,dst表示輸出的sift特征向量,通常是128維的
第一步:進行高斯模糊,獲得不同模糊度的圖片
第二步:進行直接的降采樣,獲得多分辨的圖片
第三步:將高斯模糊后的圖片進行相減操作獲得差分金字塔,使用DOC公式
第四步:對差分金字塔進行上下金字塔的比較,獲得極值點
第五步:使用泰勒展開式,獲得精確的極值點
第六步:使用herrian公式,通過特征向量變化,比較λ1和λ2的大小,用於消除邊界點
第七步:使用sobel算子,計算特征點的梯度大小和梯度方向
第八步:統計特征點臨近位置的梯度方向,做出直方圖,求出特征點的主要方向
第九步:對應於特征的主要方向,進行旋轉,保持特征點大小的方向不變性
第十步:對領域的特征點進行統計,按照4*4的數目,每個區域生成8個方向,即每個方向的出現的次數作為特征,一般使用16個區域,即16*8= 128個特征
shift特征點:用來進行偵查和描述圖片的特征,它在空間尺度中尋找極值點,並提取位置,尺度(梯度大小),旋轉不變量(方向)
流程:
第一步:先對圖像進行高斯模糊,獲得5-6張的模糊后的圖片,高斯方程為G(x, y, σ) = 1/(2pi*σ^2) * e^-(x^2+y^2)/2σ^2,σ越大,高斯模糊的程度就越高
這里的G(x, y, σ)方程存在一些錯誤
這是高斯模糊后的圖片
第二步:構造多分辨金字塔,多分辨金字塔的構造直接使用降采樣不需要模糊的操作,這里可以使用平均降采樣
第三步:構造高斯差分金字塔, 圖中的每組5張圖片為原始圖片經過不同σ高斯參數模糊后獲得的圖。將5張圖進行上下的相減操作,獲得右邊的差分圖
下面這個式子表示的是高斯差分金字塔,即不同的高斯項進行相減,最后*I(x, y)表示差分金字塔的大小值
第四步:對獲得的高斯差分金字塔,查找極值點, 對於一個點是否是極值點,將其上面一幅圖對應的9個點+下面一幅圖對應的9個點,加上該點周圍的8的點,判斷這個點是否是極值點
第五步:如果是極值點,即為關鍵點,這里我們對關鍵點做一個精確的定位,這里使用泰勒公式進行展開
D(x) = D + ∂ D^T / ∂x * x + 1/2 * x^T * ∂D^2 / ∂^X^2 * x x表示的是x軸上的偏移量,對x進行求導等於0,解得最終的結果代回D(x),D(x)為最終的極值點
該圖使用簡化的泰勒展開式,求解0這一點的近似值
最下面的D(x, y, z) 為泰勒的二階展開式
將上述進行簡單表示,這就是偏移的D(x), 即獲得實際的極值點
第六步:消除邊界效應
使用harris角點檢測的原理, 求出H(x, y) 即構造的梯度變化矩陣,求解λ1和λ2, 如果λ1>>λ2則表示為邊界點,進行去除
第七步:使用sobel算子,每個特征點得到三個信息,獲得位置, 計算梯度的大小,以及梯度的方向
第八步:統計相鄰部分的梯度的方向,畫出直方圖,把直方圖中出現次數最多的作為主方向,如果次方向的次數大於主方向的0.8,那么次方向也是輔助方向
第九步:將梯度的方向進行按照原來的方向進行旋轉,以保證梯度旋轉的不變性
第十步:對特征點進行領域的位置統計,來生成sift特征向量, 對於左邊的那個圖,從4*4個領域中統計八個方向,因此有4*8個sift,右邊有16個即16*8=128個特征向量
代碼:
第一步:讀入圖片
第二步:進行灰度化
第三步:使用cv2.xfeatures2d.SIFT_create() 實例化sift函數
第四步:使用sift.detect(gray, None) 生成關鍵點
第五步:使用cv2.drawKeypoints 進行畫圖操作
第六步:使用sift.compute(kp) 求得關鍵點對應的128個特征向量
import numpy as np import cv2 img = cv2.imread('test_1.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) sift = cv2.xfeatures2d.SIFT_create() # 找出關鍵點 kp = sift.detect(gray, None) # 對關鍵點進行繪圖 ret = cv2.drawKeypoints(gray, kp, img) cv2.imshow('ret', ret) cv2.waitKey(0) cv2.destroyAllWindows() # 使用關鍵點找出sift特征向量 kp, des = sift.compute(gray, kp) print(np.shape(kp)) print(np.shape(des)) print(des[0])