代码之家  ›  专栏  ›  技术社区  ›  Etan bbum

Harris角点检测器的实现

  •  11
  • Etan bbum  · 技术社区  · 14 年前

    我实现了一个哈里斯角探测器的教育目的,但我卡在哈里斯反应部分。基本上,我要做的是:

    1. 计算x和y方向上的图像强度梯度
    2. 模糊输出(1)
    3. 在3x3邻域和阈值输出中抑制(3)的输出中的非极大值

    1和2似乎工作得很好;但是,当Harris响应时,我得到的值非常小,没有一个点达到阈值。输入是一个标准的户外摄影。

    [...]
    [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
    

    5 回复  |  直到 9 年前
        1
  •  7
  •   jilles de wit    14 年前

    Harris角点检测中的角点被定义为“区域中的最高值像素”(通常是 3X3 5x5 )所以你关于没有达到“门槛”的评论对我来说似乎很奇怪。只需收集所有的像素,这些像素的值高于图像中的所有其他像素 他们周围的邻居。

    除此之外:

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

    一般来说,筛选输入的唯一合理时机是在这一点之前:

    [Ix, Iy] = intensityGradients(img);

    过滤 Ix2 Iy2 Ixy

    此外,我认为您的示例代码在这里是错误的(不起作用) harrisResponse

    H = harrisResponse(Ix2, Ixy, Iy2);
    [...]
    
    function K = harrisResponse(Ix, Iy)
    
        2
  •  6
  •   Walid Bousseta    7 年前

    我用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)
    
        3
  •  5
  •   iled S. Cassidy    8 年前

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

    1. 梯度计算
    2. 高斯滤波
    3. 哈里斯测度计算
    4. 非最大抑制
    5. 阈值化

    如果你是在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);
    
        4
  •  3
  •   Piotr    11 年前

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

    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(:))
    

        5
  •  0
  •   Dima    10 年前

    在计算机视觉系统工具箱中有一个函数叫做 detectHarrisFeatures .