局部图像描述子——Harris角点检测器
文章目錄
- Harris角點檢測器
- 1 Harris角點檢測算法
- 2 Harris角點檢測代碼
- 3 在圖像間尋找對應點
- 4 總結
Harris角點檢測器
1 Harris角點檢測算法
Harris角點檢測算法(也稱Harris & Stephens角點檢測器)是一個極為簡單的角點檢測算法。該算法的主要思想是,如果像素周圍顯示存在多于一個方向的邊,則認為該點為興趣點,該點也就是稱為角點。角點就是極值點,即在某方面屬性特別突出的點,是在某些屬性上強度最大或者最小的孤立點、線段的終點。
在圖像域中點x上的對稱半正定矩陣可以定義為:
其中▽I為包含導數Ix和Iy的圖像梯度。
選擇權重矩陣W(通常為高斯濾波器G),可以得到卷積:
該卷積的目的是得到M1在周圍像素上的局部平均。計算出的矩陣稱為Harris矩陣。W的寬度決定了在像素x周圍的感興趣區域。像這樣在區域附近對Harris矩陣取平均的原因是特征值會依賴于局部圖像特性而變化。如果圖像的梯度在該區域變化,那么Harris的第二個特征值將不再是0。如果圖像的梯度沒有變化,Harris的特征值也不會變化。
取決于該區域▽I的值,Harris矩陣的特征值有三種情況:
在不需要實際計算特征值的情況下,引入指示函數:
為了去除加權常數k,通常使用商數:
作為指示器。
算法的核心是利用局部窗口在圖像上進行移動,判斷灰度是否發生較大的變化。如果窗口內的灰度值(在梯度圖上)都有較大的變化,那么這個窗口所在區域就存在角點。
這樣就可以將 Harris 角點檢測算法分為以下三步:
- 當窗口(局部區域)同時向 xx (水平)和 yy(垂直) 兩個方向移動時計算窗口內部的像素值變化量 E(x,y)E(x,y) ;
- 對于每個窗口,都計算其對應的一個角點響應函數R;
- 然后對該函數進行閾值處理,如果 R>threshold,表示該窗口對應一個角點特征。
2 Harris角點檢測代碼
在這里需要使用到scipy.ndimage.filters模塊中的高斯導數濾波器來計算導數,因為需要在角點檢測過程中抑制噪聲強度。
首先將角點響應函數添加到harris.py文件中,該函數使用高斯導數實現。同樣地,參數σ定義了使用的高斯濾波器的尺度大小。
from scipy.ndimage import filtersdef compute_harris_response(im, sigma = 3):imx = zeros(im.shape)filters.gaussian_filter(im, (sigma, sigma), (0, 1), imx)imy = zeros(im.shape)filters.gaussian_filter(im, (sigma, sigma), (1, 0), imy)Wxx = filters.gaussian_filter(imx * imx, sigma)Wxy = filters.gaussian_filter(imx * imy, sigma)Wyy = filters.gaussian_filter(imy * imy, sigma)Wdet = Wxx * Wyy - Wxy ** 2Wtr = Wxx + Wyyreturn Wdet / Wtr上面的函數返回像素值為Harris響應函數值的一幅圖像。然后需要從中挑選出像素值高于閾值的所有圖像點,再加上額外的限制,即角點之間的間隔必須大于設定的最小距離。這種方法會產生很好的角點檢測結果。
為了實現該算法,我們獲取所有的候選像素點,以角點響應值遞減的順序排序,然后將距離已標記為角點位置過近的區域從候選像素點中刪除。將下面的函數添加到harris.py中:
def get_harris_points(harrisim, min_dist = 10, threshold = 0.1):corner_threshold = harrisim.max() * thresholdharrisim_t = (harrisim > corner_threshold) * 1coords = array(harrisim_t.nonzero()).Tcandidate_values = [harrisim[c[0], c[1]] for c in coords]index = argsort(candidate_values)allowed_locations = zeros(harrisim.shape)allowed_locations[min_dist: -min_dist, min_dist: -min_dist] = 1filtered_coords = []for i in index:if allowed_locations[coords[i, 0], coords[i, 1]] == 1:filtered_coords.append(coords[i])allowed_locations[(coords[i, 0] - min_dist) : (coords[i, 0] + min_dist), (coords[i, 1] - min_dist) : (coords[i, 1] + min_dist)] = 0return filtered_coords為了顯示圖像中的角點,可以使用Matplotlib模塊繪制函數,并將其添加到harris.py文件中:
def plot_harris_points(image, filtered_coords):figure()gray()imshow(image)plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*')axis('off')show()這樣準備工作就已經完成,接下來運行下邊這段代碼,打開灰度圖,計算響應函數并基于響應值選擇角點,最后在原始圖像中覆蓋繪制檢測出的角點。
from PIL import Image from numpy import * from pylab import * from scipy.ndimage import filters import harrisim = array(Image.open('jimei_grey.jpg'))harrisim = harris.compute_harris_response(im)filtered_coords = harris.get_harris_points(harrisim, 6)harris.plot_harris_points(im, filtered_coords) 圖1 使用Harris角點檢測器檢測角點從上圖可以明顯看出,隨著閾值從0.01增到0.05再到0.1,檢測出的角點越來越少,并且角點檢測算子對亮度的變化更敏感,在亮區域角點更多??梢钥闯?#xff0c;Harris角點檢測獲取的角點在圖像中分布不均勻(對比度高的區域角點多)。
3 在圖像間尋找對應點
Harris角點檢測器僅僅能夠檢測出圖像中的興趣點,但是沒有給出通過比較圖像間的興趣點來尋找匹配角點的方法。所以就需要在每個點添加一個描述子并給出一個比較這些描述子的方法。
興趣點描述子是分配給興趣點的一個向量,描述該點附近的圖像的表觀信息。描述子越好,尋找到的對應點越好。我們用對應點或者點的對應來描述相同物體和場景點在不同圖像上形成的像素點。
Harris角點的描述子通常是由周圍圖像像素塊的灰度值,以及用于比較的歸一化互相關矩陣構成的。圖像的像素塊由以該像素點為中心的周圍矩形部分圖像構成。
為了獲取圖像像素塊,并使用歸一化的互相關矩陣來比較它們,需要將以下兩個函數添加到harris.py中:
def get_descriptors(image,filtered_coords,wid=5):desc = []for coords in filtered_coords:patch = image[coords[0]-wid:coords[0]+wid+1,coords[1]-wid:coords[1]+wid+1].flatten()desc.append(patch)return desc def match(desc1,desc2,threshold=0.5):n=len(desc1[0])d = -ones((len(desc1),len(desc2)))for i in range(len(desc1)):for j in range(len(desc2)):d1 = (desc1[i] - mean(desc1[i])) / std(desc1[i])d2 = (desc2[j] - mean(desc2[j])) / std(desc2[j])ncc_value = sum(d1*d2)/(n-1)if ncc_value>threshold:d[i,j] = ncc_valuendx = argsort(-d)matchscores = ndx[:,0]return matchscores第一個函數的參數為奇數大小長度的方形灰度圖像塊,該圖像塊的中心為處理的像素點。該函數將圖像塊像素值壓平成一個向量,然后添加到描述子列表中。第二個函數使用歸一化的互相關矩陣,將每個描述子匹配到另一個圖像中的最優的候選點。由于數值較高的距離代表兩個點能夠更好地匹配,所以在排序之前,對距離取相反數。為了獲得更穩定的匹配,我們從第二幅圖像向第一幅圖像匹配,然后過濾掉在兩種方法中不都是最好的匹配。用下邊的函數實現:
def match_twosided(desc1,desc2,threshold=0.5):matches_12 = match(desc1,desc2,threshold)matches_21 = match(desc2,desc1,threshold)ndx_12 = where(matches_12 >= 0)[0]for n in ndx_12:if matches_21[matches_12[n]] != n:matches_12[n] = -1return matches_12這些匹配可以通過在兩邊分別繪制出圖像,使用線段連接匹配的像素點來直觀地可視化。可視化過程由以下代碼實現:
def appendimages(im1,im2):rows1 = im1.shape[0]rows2 = im2.shape[0]if rows1 < rows2:im1 = concatenate((im1,zeros((rows2-rows1,im1,shape[1]))),axis=0)elif rows1>rows2:im2 = concatenate((im2,zeros((rows1-rows2,im2.shape[1]))),axis=0)return concatenate((im1,im2),axis=1)def plot_matches(im1,im2,locs1,locs2,matchscores,show_below=True):im3 = appendimages(im1,im2)if show_below:im3 = vstack((im3,im3))imshow(im3)cols1 = im1.shape[1]for i,m in enumerate(matchscores):if m>0:plot([locs1[i][1],locs2[m][1]+cols1],[locs1[i][0],locs2[m][0]],'c')axis('off')使用歸一化互相關矩陣尋找對應點的實例:
from PIL import Image from numpy import * from pylab import * from scipy.ndimage import filters import harrisim1 = array(Image.open('jimei.jpg').convert('L')) im2 = array(Image.open('jimei2.jpg').convert('L'))wid = 5 harrisim = harris.compute_harris_response(im1, 5) filtered_coords1 = harris.get_harris_points(harrisim,wid+1) d1 = harris.get_descriptors(im1,filtered_coords1,wid)harrisim = harris.compute_harris_response(im2,5) filtered_coords2 = harris.get_harris_points(harrisim,wid+1) d2 = harris.get_descriptors(im2,filtered_coords2,wid)print('staring matching') matches = harris.match_twosided(d1,d2)figure() gray() harris.plot_matches(im1,im2,filtered_coords1,filtered_coords2,matches) show() 圖2 使用歸一化的互相關矩陣應用于Harris角點周圍的圖像塊從上圖可以看出,算法的結果存在一些不正確匹配,因為圖像像素塊的互相關矩陣具有較弱的描述性,而且描述符不具有尺度不變性和旋轉不變性,算法中像素塊的大小也會影響匹配的結果。
4 總結
角點檢測是計算機視覺系統中用來獲得圖像特征的一種重要方法,也稱為特征點檢測。如果某一點在任意方向的一個微小變動都會引起灰度很大的變化,那么我們就把這個點稱為圖像的一個角點。更形象一點的話,我們可以把角點理解為平面的交匯處或者邊的交點,導致交點的局部區域具有多個不同區域的不同方向的邊界。角點在保留圖像圖形重要特征的同時,可以有效地減少信息的數據量,有效地提高了計算的速度,有利于圖像的可靠匹配,該方法也是特征檢測與匹配的基礎。harris角點檢測是一種直接基于灰度圖像的角點提取算法。
總結來說,harris角點檢測就是:像素點梯度坐標分布較散、梯度變化程度較大、對應矩陣M 的特征值都較大時,窗口中含有角點;像素點的梯度在某一個方向上變化較大、另一個方向上變化較小,相應M 的特征值一個較大一個較小時,窗口中含有邊緣;像素點的梯度坐標分布集中在原點附近、梯度變化幅度非常小、對應M 的特征值都比較小時,窗口處于平坦區域。且具有旋轉不變性、對亮度和對比度的變化不靈敏以及不具有尺度不變性等性質。
從實驗可以看出,對亮度和對比度的仿射變換并不改變Harris響應的極值點出現的位置,但是,由于閾值的選擇,可能會影響角點檢測的數量。特征點的提取過程可以減少噪聲的影響,對灰度變化、圖像形變以及遮擋等都有較好的適應能力。位置也會影響角點數量,特征點的匹配度量值相對位置變化比較敏感,可以提高匹配的精度。最后閥值對角點數量的影響也很大,閥值越大,角點數量就會越少。
總結
以上是生活随笔為你收集整理的局部图像描述子——Harris角点检测器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数字图像处理——形态学图像处理及图像分割
- 下一篇: 局部图像描述子——SIFT(尺度不变特征