計算機視覺--Harris角點檢測實現與分析(二)


關於Harris角點檢測的基本概念和不同場景下的檢測結果分析已記錄在上一篇博客中(點擊): 計算機視覺–Harris角點檢測實現與分析(一).本篇主要對Harris角點檢測響應函數進行分析。

一、Harris角點檢測

1.1 基本原理

      人眼對角點的識別通常是在一個局部的小區域或小窗口完成的。如果在各個方向上移動這個特徵的小窗口,窗口內區域的灰度發生了較大的變化,那麼就認爲在窗口內遇到了角點。如果這個特定的窗口在圖像各個方向上移動時,窗口內圖像的灰度沒有發生變化,那麼窗口內就不存在角點;如果窗口在某一個方向移動時,窗口內圖像的灰度發生了較大的變化,而在另一些方向上沒有發生變化,那麼,窗口內的圖像可能就是一條直線的線段。
在這裏插入圖片描述

1.2 數學表達

將圖像窗口平移[u,v]產生灰度變化E(u,v):
在這裏插入圖片描述
如何求解平移後的圖像灰度I(x+u,y+v),以及灰度變化E(u,v)?

這裏用到知識點二元函數泰勒展開,將I(x+u, y+v)函數在(x, y)處泰勒展開,得:
在這裏插入圖片描述
於是對於局部微小的移動量 [u,v],可以近似得到下面的表達:
在這裏插入圖片描述
其中M是 2*2 矩陣,可由圖像的導數求得:
在這裏插入圖片描述
窗口移動導致的圖像變化量:實對稱矩陣M的特徵值分析
在這裏插入圖片描述
記M的特徵值爲λ1、λ2
在這裏插入圖片描述
定義:角點響應函數R:
在這裏插入圖片描述

二、代碼實現

Harris角點檢測器響應函數爲compute_harris_response(im, sigma=3),在本段代碼中,將其重寫,便於觀察角點響應函數R的值。

# -*- coding: utf-8 -*-
from pylab import *
from PIL import Image
from PCV.localdescriptors import harris
from scipy.ndimage import filters
"""
Example of detecting Harris corner points (Figure 2-1 in the book).
"""

def compute_harris_response(im, sigma=3):
    # 在一幅灰度圖像中,對每個像素計算Harris角點檢測器響應函數

    # 計算導數
    k = 0.04
    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)

    # 計算harris矩陣分量
    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 ** 2
    Wtr = Wxx + Wyy

    # 返回像素值爲 Harris 響應函數值的一幅圖像
    print(Wdet - (k * Wtr))  # 輸出角點響應函數R
    R=Wdet - (k * Wtr)
    #figure()
    #imshow(R)
    return Wdet / Wtr  # 此處可消除參數k的影響


# 讀入圖像(讀取圖像到數組中)
im = array(Image.open('../data/empire.jpg').convert('L'))  # 括號內:讀取一幅圖像,並將其轉換成灰度圖像

# 檢測harris角點
harrisim = compute_harris_response(im)
# compute_harris_response(im, sigma):
#     在一幅灰度圖像中,對每一個像素計算Harris角點檢測器響應函數
#     im:(數組圖像)  sigma:標準差默認爲3

# Harris響應函數
# print (harrisim)
harrisim1 = 255 - harrisim
figure()
gray()

# 畫出Harris響應圖
subplot(141)
imshow(harrisim1)
print harrisim1.shape
axis('off')
axis('equal')

threshold = [0.01, 0.05, 0.1]
for i, thres in enumerate(threshold):
    # enumerate()函數用於將一個可遍歷的數據對象(如列表、元組或字符串)組合爲一個索引序列,同時列出數據和數據下標,一般用在for 循環當中
    filtered_coords = harris.get_harris_points(harrisim, 6, thres)
    # get_harris_points(harrisim, min_dist=10, threshold=0.1):
    #       從一幅Harris 響應圖像harrisim中返回角點。min_dist 爲分割角點和圖像邊界的最少像素數目(默認爲10)。
    #       threshold 爲閥值,大於閥值的harris響應函數值被認爲是可能的角點,並在harrism_t矩陣中相應的位置1,其餘地方置0
    subplot(1, 4, i + 2)
    imshow(im)
    print im.shape
    plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*')  # 標出角點
    axis('off')

show()

三、結果與分析

3.1 不同場景的R值討論

場景一:垂直或水平邊緣多
在這裏插入圖片描述
在這裏插入圖片描述
場景二:紋理角點豐富
在這裏插入圖片描述
在這裏插入圖片描述
場景三:平坦
在這裏插入圖片描述
在這裏插入圖片描述
分析:由上述運行結果可得–

  • 對於R的表達式:
    在這裏插入圖片描述
    R只與M的特徵值有關

  • 對於紋理角點豐富的場景,R爲大數值正數

  • 對於垂直或水平邊緣多的場景,R爲大數值負數

  • 對於平坦的場景,R爲小數值

3.2 參數k對角點檢測的影響

在其他條件不變的前提下,改變k值:
k=0.02:
在這裏插入圖片描述
k=0.04:
在這裏插入圖片描述
k=0.05:
在這裏插入圖片描述
k=0.06:
在這裏插入圖片描述
k=0.08:
在這裏插入圖片描述
分析:
增大k的值,將減小角點響應值R,降低角點檢測的靈性,減少被檢測角點的數量;減小k值,將增大角點響應值R,增加角點檢測的靈敏性,增加被檢測角點的數量。

四、總結

在三種不同的場景下,得到的R值結果不同。k值增大,R值會隨之減小,檢測角點數量也會減少。本次實驗中,遇到的問題是在測試圖片的R值時出現報錯,經檢查發現是圖片像素太高,進入圖片-編輯,修改像素值爲較小值即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章