SIFT特征提取算法
SIFT的全稱是Scale Invariant Feature Transform,尺度不變特征變換,由加拿大教授David G.Lowe提出的。是在不同的尺度空間上查找關(guān)鍵點(diǎn)(特征點(diǎn)),并計(jì)算出關(guān)鍵點(diǎn)的方向。SIFT所查找到的關(guān)鍵點(diǎn)是一些十分突出、不會(huì)因光照、仿射變換和噪音等因素而變化的點(diǎn),如角點(diǎn)、邊緣點(diǎn)、暗區(qū)的亮點(diǎn)及亮區(qū)的暗點(diǎn)等。SIFT特征對(duì)旋轉(zhuǎn)、尺度縮放、亮度變化等保持不變性,是一種非常穩(wěn)定的局部特征。
主要步驟:
- 1.構(gòu)建DOG尺度空間
- 2.關(guān)鍵點(diǎn)搜索和定位
- 3.方向賦值
- 4.關(guān)鍵點(diǎn)描述子的生成
1.構(gòu)建DOG尺度空間
模擬圖像數(shù)據(jù)的多尺度特征,大尺度輪廓特征,小尺度細(xì)節(jié)特征。通過(guò)構(gòu)建高斯金字塔(每一層用不同的參數(shù)σ做高斯模糊(加權(quán))),保證圖像在任何尺度都能有對(duì)應(yīng)的特征點(diǎn),即保證尺度不變性。
a.尺度空間
在一定的范圍內(nèi),無(wú)論物體是大還是小,人眼都可以分辨出來(lái)。然而計(jì)算機(jī)要有相同的能力卻不是那么的容易,在未知的場(chǎng)景中,計(jì)算機(jī)視覺(jué)并不能提供物體的尺度大小,其中的一種方法是把物體不同尺度下的圖像都提供給機(jī)器,讓機(jī)器能夠?qū)ξ矬w在不同的尺度下有一個(gè)統(tǒng)一的認(rèn)知。在建立統(tǒng)一認(rèn)知的過(guò)程中,要考慮的就是在圖像在不同的尺度下都存在的特征點(diǎn)。
b.多分辨率圖像金字塔
在早期圖像的多尺度通常使用圖像金字塔表示形式。圖像金字塔是同一圖像在不同的分辨率下得到的一組結(jié)果其生成過(guò)程一般包括兩個(gè)步驟:
- 對(duì)原始圖像進(jìn)行平滑
- 對(duì)處理后的圖像進(jìn)行降采樣(通常是水平、垂直方向的1/2),降采樣后得到一系列不斷尺寸縮小的圖像。顯然,一個(gè)傳統(tǒng)的金字塔中,每一層的圖像是其上一層圖像長(zhǎng)、高的各一半。
多分辨率的圖像金字塔雖然生成簡(jiǎn)單,但其本質(zhì)是降采樣,圖像的局部特征則難以保持,也就是無(wú)法保持特征的尺度不變性。
c.高斯尺度空間
我們還可以通過(guò)圖像的模糊程度來(lái)模擬人在距離物體由遠(yuǎn)到近時(shí)物體在視網(wǎng)膜上成像過(guò)程,距離物體越近其尺寸越大圖像也越模糊,這就是高斯尺度空間,使用不同的參數(shù)模糊圖像(分辨率不變),是尺度空間的另一種表現(xiàn)形式。
我們知道圖像和高斯函數(shù)進(jìn)行卷積運(yùn)算能夠?qū)D像進(jìn)行模糊,使用不同的“高斯核”可得到不同模糊程度的圖像。一幅圖像其高斯尺度空間可由其和不同的高斯卷積得到:L(x,y,σ)=G(x,y,σ)?I(x,y)
G(x,y,σ)是高斯核函數(shù),σ稱為尺度空間因子,它是高斯正態(tài)分布的標(biāo)準(zhǔn)差,反映了圖像被模糊的程度,其值越大圖像越模糊,對(duì)應(yīng)的尺度也就越大。L(x,y,σ)代表著圖像的高斯尺度空間。
構(gòu)建尺度空間的目的是為了檢測(cè)出在不同的尺度下都存在的特征點(diǎn),而檢測(cè)特征點(diǎn)較好的算子是Δ^2G(高斯拉普拉斯,LoG)
使用LoG雖然能較好的檢測(cè)到圖像中的特征點(diǎn),但是其運(yùn)算量過(guò)大,通常可使用DoG(差分高斯,Difference of Gaussina)來(lái)近似計(jì)算LoG。
設(shè)k為相鄰兩個(gè)高斯尺度空間的比例因子,則DoG的定義:
D(x,y,σ)=[G(x,y,kσ)?G(x,y,σ)]?I(x,y)=L(x,y,kσ)?L(x,y,σ)
從上式可以知道,將相鄰的兩個(gè)高斯空間的圖像相減就得到了DoG的響應(yīng)圖像。為了得到DoG圖像,先要構(gòu)建高斯尺度空間,而高斯的尺度空間可以在圖像金字塔降采樣的基礎(chǔ)上加上高斯濾波得到,也就是對(duì)圖像金字塔的每層圖像使用不同的參數(shù)σ進(jìn)行高斯模糊,使每層金字塔有多張高斯模糊過(guò)的圖像。
如下圖,octave間是降采樣關(guān)系,且octave(i+1)的第一張(從下往上數(shù))圖像是由octave(i)中德倒數(shù)第三張圖像降采樣得到。octave內(nèi)的圖像大小一樣,只是高斯模糊使用的尺度參數(shù)不同。
對(duì)于一幅圖像,建立其在不同尺度scale下的圖像,也稱為octave,這是為了scale-invariant,也就是在任何尺度都能有對(duì)應(yīng)的特征點(diǎn)。下圖中右側(cè)的DoG就是我們構(gòu)建的尺度空間。
2.關(guān)鍵點(diǎn)搜索和定位
a.關(guān)鍵點(diǎn)搜索
為了尋找尺度空間的極值點(diǎn),每一個(gè)采樣點(diǎn)要和它所有的相鄰點(diǎn)比較,看其是否比它的圖像域和尺度域的相鄰點(diǎn)大或者小。如圖所示,中間的檢測(cè)點(diǎn)和它同尺度的8個(gè)相鄰點(diǎn)和上下相鄰尺度對(duì)應(yīng)的9×2個(gè)點(diǎn)共26個(gè)點(diǎn)比較,以確保在尺度空間和二維圖像空間都檢測(cè)到極值點(diǎn)。 一個(gè)點(diǎn)如果在DOG尺度空間本層以及上下兩層的26個(gè)領(lǐng)域中是最大或最小值時(shí),就認(rèn)為該點(diǎn)是圖像在該尺度下的一個(gè)特征點(diǎn)。下圖中將叉號(hào)點(diǎn)要比較的26個(gè)點(diǎn)都標(biāo)為了綠色。
b.關(guān)鍵點(diǎn)定位
找到所有特征點(diǎn)后,要去除低對(duì)比度和不穩(wěn)定的邊緣效應(yīng)的點(diǎn),留下具有代表性的關(guān)鍵點(diǎn)(比如,正方形旋轉(zhuǎn)后變?yōu)榱庑危绻眠吘壸鲎R(shí)別,4條邊就完全不一樣,就會(huì)錯(cuò)誤;如果用角點(diǎn)識(shí)別,則穩(wěn)定一些)。去除這些點(diǎn)的好處是增強(qiáng)匹配的抗噪能力和穩(wěn)定性。最后,對(duì)離散的點(diǎn)做曲線擬合,得到精確的關(guān)鍵點(diǎn)的位置和尺度信息。
3.方向賦值
為了實(shí)現(xiàn)旋轉(zhuǎn)不變性,需要根據(jù)檢測(cè)到的關(guān)鍵點(diǎn)的局部圖像結(jié)構(gòu)為特征點(diǎn)賦值。具體做法是用梯度方向直方圖。在計(jì)算直方圖時(shí),每個(gè)加入直方圖的采樣點(diǎn)都使用圓形高斯函數(shù)進(jìn)行加權(quán)處理,也就是進(jìn)行高斯平滑。這主要是因?yàn)?strong>SIFT算法只考慮了尺度和旋轉(zhuǎn)不變形,沒(méi)有考慮仿射不變性。通過(guò)高斯平滑,可以使關(guān)鍵點(diǎn)附近的梯度幅值有較大權(quán)重,從而部分彌補(bǔ)沒(méi)考慮仿射不變形產(chǎn)生的特征點(diǎn)不穩(wěn)定。注意,一個(gè)關(guān)鍵點(diǎn)可能具有多個(gè)關(guān)鍵方向,這有利于增強(qiáng)圖像匹配的魯棒性。
4.關(guān)鍵點(diǎn)描述子的生成
關(guān)鍵點(diǎn)描述子不但包括關(guān)鍵點(diǎn),還包括關(guān)鍵點(diǎn)周?chē)鷮?duì)其有貢獻(xiàn)的像素點(diǎn)。這樣可使關(guān)鍵點(diǎn)有更多的不變特性,提高目標(biāo)匹配效率。在描述子采樣區(qū)域時(shí),需要考慮旋轉(zhuǎn)后進(jìn)行雙線性插值,防止因旋轉(zhuǎn)圖像出現(xiàn)白點(diǎn)。同時(shí),為了保證旋轉(zhuǎn)不變性,要以特征點(diǎn)為中心,在附近領(lǐng)域內(nèi)旋轉(zhuǎn)θ角,然后計(jì)算采樣區(qū)域的梯度直方圖,形成n維SIFT特征矢量(如128-SIFT)。最后,為了去除光照變化的影響,需要對(duì)特征矢量進(jìn)行歸一化處理。
SIFT特征提取優(yōu)點(diǎn)
- SIFT特征是圖像的局部特征,其對(duì)旋轉(zhuǎn)、尺度縮放、亮度變化保持不變性,對(duì)視角變化、仿射變換、噪聲也保持一定程度的穩(wěn)定性。
- 獨(dú)特性(Distinctiveness)好,信息量豐富,適用于在海量特征數(shù)據(jù)庫(kù)中進(jìn)行快速、準(zhǔn)確的匹配。
- 多量性,即使少數(shù)的幾個(gè)物體也可以產(chǎn)生大量的SIFT特征向量。
- 高速性,經(jīng)優(yōu)化的SIFT匹配算法甚至可以達(dá)到實(shí)時(shí)的要求。
- 可擴(kuò)展性,可以很方便的與其他形式的特征向量進(jìn)行聯(lián)合。
- 需要較少的先驗(yàn)知識(shí),易于開(kāi)發(fā)。
近來(lái)不斷有人改進(jìn),其中最著名的有 SURF(計(jì)算量小,運(yùn)算速度快,提取的特征點(diǎn)幾乎與SIFT相同)和 CSIFT(彩色尺度特征不變變換,顧名思義,可以解決基于彩色圖像的SIFT問(wèn)題)。
SIFT特征提取缺點(diǎn)
- 實(shí)時(shí)性不高,因?yàn)橐粩嗟匾M(jìn)行下采樣和插值等操作;
- 有時(shí)特征點(diǎn)較少(比如模糊圖像);
- 對(duì)邊緣光滑的目標(biāo)無(wú)法準(zhǔn)確提取特征(比如邊緣平滑的圖像,檢測(cè)出的特征點(diǎn)過(guò)少,對(duì)圓更是無(wú)能為力)。
Python-OpenCV實(shí)現(xiàn):
import cv2
def sift_kp(image):
gray_image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d_SIFT.create()
kp,des = sift.detectAndCompute(image, None)
kp_image = cv2.drawKeypoints(image, kp, None)
return kp_image,kp,des
image = cv2.imread('dog.jpg')
kp_image, _, des = sift_kp(image)
print(image.shape, des.shape)
cv2.namedWindow('dog',cv2.WINDOW_NORMAL)
cv2.imshow('dog', kp_image)
if cv2.waitKey(0) == 27:
cv2.destroyAllWindows()
其中sift.detectAndCompute()函數(shù)返回kp,des。
kp存儲(chǔ)著特征點(diǎn)的信息:
- angle:角度,表示關(guān)鍵點(diǎn)的方向,通過(guò)Lowe大神的論文可以知道,為了保證方向不變形,SIFT算法通過(guò)對(duì)關(guān)鍵點(diǎn)周?chē)徲蜻M(jìn)行梯度運(yùn)算,求得該點(diǎn)方向。-1為初值。
- class_id:當(dāng)要對(duì)圖片進(jìn)行分類時(shí),我們可以用class_id對(duì)每個(gè)特征點(diǎn)進(jìn)行區(qū)分,未設(shè)定時(shí)為-1,需要靠自己設(shè)定。
- octave:代表是從金字塔哪一層提取的得到的數(shù)據(jù)。
- pt:關(guān)鍵點(diǎn)點(diǎn)的坐標(biāo)。
- response:響應(yīng)程度,代表該點(diǎn)強(qiáng)壯大小,更確切的說(shuō),是該點(diǎn)角點(diǎn)的程度。
- size:該點(diǎn)直徑的大小。
des為特征向量:
上圖dog的shape為(481, 500, 3),提取的特征向量des的shape為(501, 128),501個(gè)128維的特征點(diǎn)。
cv2.drawKeyPoints(image, keypoints, outImage, color, flags)
該方法可以在特征點(diǎn)處繪制一個(gè)小圓圈。
- image:輸入圖像,可以使三通道或單通道圖像。
- keypoints:特征點(diǎn)向量,向量?jī)?nèi)每一個(gè)元素是一個(gè)KeyPoint對(duì)象,包含了特征點(diǎn)的各種屬性信息。
- outImage:特征點(diǎn)繪制的畫(huà)布圖像,可以是原圖像。
- 繪制的特征點(diǎn)的顏色信息,默認(rèn)繪制的是隨機(jī)彩色。
- flags:特征點(diǎn)的繪制模式,其實(shí)就是設(shè)置特征點(diǎn)的哪些信息需要繪制,哪些不需要繪制,有以下幾種模式可選:
cv2.DRAW_MATCHES_FLAGS_DEFAULT: 只繪制特征點(diǎn)的坐標(biāo)點(diǎn),顯示在圖像上就是一個(gè)個(gè)小圓點(diǎn),每個(gè)小圓點(diǎn)的圓心坐標(biāo)都是特征點(diǎn)的坐標(biāo)。cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS:繪制特征點(diǎn)的時(shí)候繪制的是一個(gè)個(gè)帶有方向的圓,這種方法同時(shí)顯示圖像的坐標(biāo),size和方向,是最能顯示特征的一種繪制方式 。cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG:函數(shù)不創(chuàng)建輸出的圖像,而是直接在輸出圖像變量空間繪制,要求本身輸出圖像變量就是一個(gè)初始化好了的,size與type都是已經(jīng)初始化好的變量。
cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS: 單點(diǎn)的特征點(diǎn)不被繪制 。
參考
https://blog.csdn.net/happyer88/article/details/45817305
http://www.lxweimin.com/p/d94e558ebe26
https://www.cnblogs.com/wangguchangqing/p/4853263.html