实施Harris角点探测器

时间:2010-10-05 09:03:50

标签: algorithm matlab computer-vision feature-detection corner-detection

我正在实施Harris角点探测器用于教育目的,但我被卡在哈里斯响应部分。基本上,我在做的是:

  1. 计算x和y方向的图像强度梯度
  2. 模糊(1)
  3. 的输出
  4. 计算Harris对(2)
  5. 输出的响应
  6. 在3x3邻域和阈值输出中抑制(3)输出中的非最大值
  7. 1和2似乎工作正常;然而,随着哈里斯的反应,我得到的值非常小,没有任何一点达到阈值。输入是标准的户外摄影。

    [...]
    [Ix, Iy] = intensityGradients(img);
    g = fspecial('gaussian');
    Ix = imfilter(Ix, g);
    Iy = imfilter(Iy, g);
    H = harrisResponse(Ix, Iy);
    [...]
    
    function K = harrisResponse(Ix, Iy)
        max = 0;
        [sy, sx] = size(Ix);
        K = zeros(sy, sx);
        for i = 1:sx,
            for j = 1:sy,
                H = [Ix(j,i) * Ix(j,i), Ix(j,i) * Iy(j,i)
                    Ix(j,i) * Iy(j,i), Iy(j,i) * Iy(j,i)];
                K(j,i) = det(H) / trace(H);
                if K(j,i) > max,
                    max = K(j,i);
                end
            end
        end
        max
    end
    

    对于样本图片,max最终为6.4163e-018,这似乎太低了。

5 个答案:

答案 0 :(得分:7)

哈里斯角点检测中的一个角被定义为“区域中的最高值像素”(通常是3X35x5)所以你对没有点达到“阈值”的评论对我来说似乎很奇怪。只需收集所有像素值高于其周围5x5邻域中所有其他像素的值。

除此之外: 我不是百分百肯定,但我认为你应该:

K(j,i) = det(H) - lambda*(trace(H)^2) lambda是一个在你的情况下有效的正常数(Harris建议值为0.04)。

一般来说,过滤输入的唯一合理时刻是在此之前:

[Ix, Iy] = intensityGradients(img);

过滤Ix2Iy2Ixy对我来说没有多大意义。

此外,我认为您的示例代码在这里是错误的(函数harrisResponse是否有两个或三个输入变量?):

H = harrisResponse(Ix2, Ixy, Iy2);
[...]

function K = harrisResponse(Ix, Iy)

答案 1 :(得分:3)

拟议的实施非常低效。 让我们在计算梯度后开始(也可以优化):

A = Ix.^2;
B = Iy.^2;
C = (Ix.*Iy).^4;
lambda = 0.04;

H = (A.*B - C) - lambda*(A+B).^2;

% if you really need max:
max(H(:))

不需要循环,因为Matlab讨厌循环。

答案 2 :(得分:3)

基本上,Harris角点检测将有5个步骤:

  1. 渐变计算
  2. 高斯平滑
  3. 哈里斯度量计算
  4. 非最大限制抑制
  5. 阈值
  6. 如果您在MATLAB中实现,将很容易理解算法并获得结果。

    以下MATLAB代码可以帮助您解决疑虑:

    % Step 1: Compute derivatives of image
    Ix = conv2(im, dx, 'same');
    Iy = conv2(im, dy, 'same');
    
    % Step 2: Smooth space image derivatives (gaussian filtering)
    Ix2 = conv2(Ix .^ 2, g, 'same');
    Iy2 = conv2(Iy .^ 2, g, 'same');
    Ixy = conv2(Ix .* Iy, g, 'same');
    
    % Step 3: Harris corner measure
    harris = (Ix2 .* Iy2 - Ixy .^ 2) ./ (Ix2 + Iy2);
    
    % Step 4: Find local maxima (non maximum suppression)
    mx = ordfilt2(harris, size .^ 2, ones(size));
    
    % Step 5: Thresholding
    harris = (harris == mx) & (harris > threshold);
    

答案 3 :(得分:3)

我用python实现的解决方案,它对我有用,我希望你能找到你想要的东西

import numpy as np
import matplotlib.pyplot as plt
from PIL.Image import *
from scipy import ndimage

def imap1(im):
    print('testing the picture . . .')
    a = Image.getpixel(im, (0, 0))
    if type(a) == int:
        return im
    else:
        c, l = im.size
        imarr = np.asarray(im)
        neim = np.zeros((l, c))
        for i in range(l):
            for j in range(c):
                t = imarr[i, j]
                ts = sum(t)/len(t)
                neim[i, j] = ts
        return neim

def Harris(im):
    neim = imap1(im)
    imarr = np.asarray(neim, dtype=np.float64)
    ix = ndimage.sobel(imarr, 0)
    iy = ndimage.sobel(imarr, 1)
    ix2 = ix * ix
    iy2 = iy * iy
    ixy = ix * iy
    ix2 = ndimage.gaussian_filter(ix2, sigma=2)
    iy2 = ndimage.gaussian_filter(iy2, sigma=2)
    ixy = ndimage.gaussian_filter(ixy, sigma=2)
    c, l = imarr.shape
    result = np.zeros((c, l))
    r = np.zeros((c, l))
    rmax = 0
    for i in range(c):
        print('loking for corner . . .')
        for j in range(l):
            print('test ',j)
            m = np.array([[ix2[i, j], ixy[i, j]], [ixy[i, j], iy2[i, j]]], dtype=np.float64)
            r[i, j] = np.linalg.det(m) - 0.04 * (np.power(np.trace(m), 2))
            if r[i, j] > rmax:
                rmax = r[i, j]
    for i in range(c - 1):
        print(". .")
        for j in range(l - 1):
            print('loking')
            if r[i, j] > 0.01 * rmax and r[i, j] > r[i-1, j-1] and r[i, j] > r[i-1, j+1]\
                                     and r[i, j] > r[i+1, j-1] and r[i, j] > r[i+1, j+1]:
                result[i, j] = 1

    pc, pr = np.where(result == 1)
    plt.plot(pr, pc, 'r+')
    plt.savefig('harris_test.png')
    plt.imshow(im, 'gray')
    plt.show()
    # plt.imsave('harris_test.png', im, 'gray')

im = open('chess.png')
Harris(im)

答案 4 :(得分:0)

计算机视觉系统工具箱中有一个名为detectHarrisFeatures的功能。