冒泡...恍恍惚惚了幾天...還是要振作沖鴨!
SIFT
介紹
SIFT(Scale-invariant feature transform)即尺度不變特征轉換犁嗅。
SIFT特征是基于物體上的一些局部外觀的興趣點,與影像的大小和旋轉無關趾牧。SIFT算法是用來提取圖像的局部特征的算法故黑,它的實質是在不同的尺度空間上查找關鍵點(特征點),并計算出關鍵點的方向遣臼。(注:查找到的關鍵點是一些十分突出性置,不會因光照,仿射變換和噪音等因素而變化的點揍堰,如角點鹏浅、邊緣點、暗區(qū)的亮點及亮區(qū)的暗點等屏歹。)
特點
1.SIFT特征是圖像的局部特征隐砸,其對旋轉、尺度縮放蝙眶、亮度變化保持不變性季希,對視角變化、仿射變換幽纷、噪聲也保持一定程度的穩(wěn)定性式塌;
2.獨特性(Distinctiveness)好,信息量豐富友浸,適用于在海量特征數據庫中進行快速峰尝、準確的匹配;
3.多量性收恢,即使少數的幾個物體也可以產生大量的特征向量武学。
4.高速性,經優(yōu)化的匹配算法甚至可以達到實時的要求伦意。
5.可擴展性火窒,可以很方便的與其他形式的特征向量進行聯(lián)合。
算法
1默赂、初始化操作沛鸵,構建圖像的金字塔
2、關鍵點搜索缆八、定位曲掰、篩選
3、關鍵點方向賦值
4奈辰、關鍵點描述子的生成
分步驟詳解:
(1)初始化操作栏妖,構建圖像的金字塔
名詞解釋:
圖像尺度空間:圖像的尺度空間它可以模擬人在距離目標由近到遠的過程中,目標在視網膜當中形成的圖像的過程奖恰。尺度越大圖像越模糊吊趾,相當于我們觀察遠處物體宛裕,這時候關注該物體的輪廓。比如可以這樣理解论泛,在過馬路的時候我們只可以看清馬路對面的行人的輪廓揩尸,但是他衣服的花紋就會顯得比較模糊。
特點:
高斯模糊: 這里尺度空間的生成需要使用高斯模糊來實現(xiàn)屁奏,Lindeberg等人已經證明高斯卷積核是實現(xiàn)尺度變換的唯一線性核岩榆。高斯模糊是一種圖像濾波器,它使用正態(tài)分布(高斯函數)計算模糊模板坟瓢,并使用該模板與原圖像做卷積運算勇边,達到模糊圖像的目的。
實現(xiàn):
八度(octave): 八度就是在特定尺寸(長寬)下折联,經不同高斯核模糊的圖像的集合粒褒。八度的集合是高斯金字塔。
第一步中的初始化操作就是通過高斯卷積核來實現(xiàn)尺度變換诚镰,從而模擬圖像的多尺度特征奕坟,之后就是建立高斯金字塔和差分高斯金字塔。
建立高斯金字塔:高斯金字塔構建過程中清笨,一般首先將圖像擴大一倍执赡,在擴大的圖像的基礎之上構建高斯金字塔,然后對該尺寸下圖像進行高斯模糊函筋,幾幅模糊之后的圖像集合構成了一個八度,然后對該八度下的最模糊的一幅圖像進行下采樣的過程奠伪,長和寬分別縮短一倍跌帐,圖像面積變?yōu)樵瓉硭姆种弧_@幅圖像就是下一個八度的初始圖像绊率,在初始圖像圖像的基礎上完成屬于這個八度的高斯模糊處理谨敛,以此類推完成整個算法所需要的所有八度構建,這樣這個高斯金字塔就構建出來了滤否。
建立差分高斯金字塔:差分脸狸,顧名思義,也就是要做差藐俺。對同一個八度的上下兩幅相鄰的圖像做差得到插值圖像炊甲,所有八度的這些插值圖像的集合,就構成了差分高斯金字塔欲芹。差分高斯金字塔的好處是為后續(xù)的特征點的提取提供了方便卿啡。
關于高斯金字塔的生成細節(jié)可以參考:(https://blog.csdn.net/hit2015spring/article/details/52895367)
(2)關鍵點搜索、定位菱父、篩選
尋找:實質是為了尋找尺度空間的極值點颈娜,因此每一個采樣點要和它所有的相鄰點比較剑逃,看其是否比它的圖像域和尺度域的相鄰點大或者小。
舉個例子:如圖所示官辽,中間的檢測點和它同尺度的8個相鄰點和上下相鄰尺度對應的9×2個點共8+18=26個點比較蛹磺,以確保在尺度空間和二維圖像空間都檢測到極值點。 一個點如果在DOG尺度空間本層以及上下兩層的26個領域中是最大或最小值時同仆,就認為該點是圖像在該尺度下的一個特征點萤捆。下圖中將叉號點要比較的26個點都標為了綠色。
定位:
在離散空間下尋找的點不一定是符合的臭觉,所以需要定位昆雀。
篩選:在DOG函數中蝠筑,它存在比較強的邊緣效應狞膘,而當特征點在邊緣的時候,這些點就會很不穩(wěn)定什乙,所以挽封,我們應該把這些邊緣效應很強的點找出來,進行篩選臣镣。
詳細過程可參見(https://blog.csdn.net/hit2015spring/article/details/52972890)
至此辅愿,我們得到了關鍵點的位置信息和尺度信息(x,y,σ)。
(3)關鍵點方向賦值
為了實現(xiàn)圖像的旋轉不變性忆某,需要根據檢測到的關鍵點的局部圖像結構為特征點方向賦值点待。
梯度直方圖:方向直方圖的核心是統(tǒng)計以關鍵點為原點,一定區(qū)域內的圖像像素點對關鍵點方向生成所作的貢獻弃舒。
由此可以得到每一個點的幅值和幅角癞埠,但是由于與特征點的距離不同,各個點對特征點的支持也是不一樣的聋呢,所以離得遠的就支持弱一點苗踪,離得近的就支持大一點,這里面的權重就要通過一個規(guī)則來管理削锰,而這個規(guī)則就是高斯濾波徒探,即以特征點為圓心,做一個高斯濾波喂窟,給它周圍的點加上一個高斯權重测暗。高斯函數的方差當然還是與這個特征點所在的圖像層的尺度有關央串。
直方圖峰值代表該關鍵點鄰域內圖像梯度的主方向,當存在另一個相當于主峰值碗啄。
(4)關鍵點描述子的生成
注意:這個描述子不但包括關鍵點质和,也包括關鍵點周圍對其有貢獻的像素點。
a.描述子采樣區(qū)域
b.區(qū)域坐標旋轉:為了使sift特征點具有旋轉不變性稚字,要以特征點為中心饲宿,在附近鄰域內旋轉θ角,即旋轉為特征點的方向胆描。
c.計算采樣區(qū)域梯度直方圖
將旋轉后區(qū)域劃分為d×d個子區(qū)域(每個區(qū)域間隔為mσ像元)瘫想,在子區(qū)域內計算8個方向的梯度直方圖,繪制每個方向梯度方向的累加值昌讲,形成一個種子點国夜。與求主方向不同的是,此時短绸,每個子區(qū)域梯度方向直方圖將0°~360°劃分為8個方向區(qū)間车吹,每個區(qū)間為45°。即每個種子點有8個方向區(qū)間的梯度強度信息醋闭。然后對子區(qū)域的像素的梯度大小采用mσd/2的高斯加權函數加權窄驹。由于存在d×d,即4×4個子區(qū)域证逻,所以最終共有4×4×8=128個數據乐埠,形成128維SIFT特征矢量。特征向量形成后囚企,為了去除光照變化的影響饮戳,需要對它們進行歸一化處理。
SIFT的缺點
- 實時性不高洞拨。
- 有時特征點較少。
- 對邊緣光滑的目標無法準確提取特征點负拟。
4.模糊的圖像和邊緣平滑的圖像烦衣,檢測出的特征點過少,對圓更是無能為力.
代碼
import cv2
import numpy as np
img = cv2.imread('F:/3.jpg') # 讀取要處理的圖片
alg = input('Select an Alg --> ')
def fd(algorithm):
if algorithm == 'SIFT':
return cv2.xfeatures2d.SIFT_create()
if algorithm == 'SURF':
threshold = input('Enter a threshold --> ') # 提示輸入SURF算法所采用的閾值
return cv2.xfeatures2d.SURF_create(float(threshold))
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 轉換為灰度圖像
fd_alg = fd(alg)
keypoints, descriptor = fd_alg.detectAndCompute(gray, None)
img = cv2.drawKeypoints(image=img, outImage=img, keypoints=keypoints,
flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
color=(51, 163, 236))
cv2.imshow('keypoints', img)
while (True):
if cv2.waitKey(30) & 0xff == ord('q'):
break
cv2.destroyAllWindows()
結果
參考(https://blog.csdn.net/happyer88/article/details/45817305 )
(https://blog.csdn.net/zddblog/article/details/7521424)
Finally~so tired!