10

Я использую детектор угла Гарриса для образовательных целей, но я застрял в части ответа Харриса. В основном, что я делаю, это:Реализация углового детектора Harris

  1. Compute градиентов интенсивности изображения в x- и у-направлении
  2. Размытия выхода (1)
  3. Вычислительного Harris ответа по выходу (2)
  4. Подавлять не-максимы в выводе (3) в 3х3-окрестности и пороговом выходе

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, который кажется слишком низким.

ответ

7

Угол в углу определения угла Харриса определяется как «пиксель наивысшего значения в регионе» (обычно 3X3 или 5x5), поэтому ваш комментарий о том, что точка не достигла «порога», кажется мне странной. Просто соберите все пиксели, которые имеют более высокое значение, чем все остальные пиксели в соседнем районе 5x5.

Помимо этого: Я не уверен на 100%, но я думаю, вы должны иметь:

K(j,i) = det(H) - lambda*(trace(H)^2) Где лямбда положительная константа, которая работает в вашем случае (и Харрис предложил значение 0,04).

В общем единственный разумный момент для фильтрации ввода является до этого момента:

[Ix, Iy] = intensityGradients(img);

Фильтрация Ix2, Iy2 и Ixy не имеет большого смысла для меня.

Кроме того, я думаю, ваш пример кода здесь не так (это функция harrisResponse имеет два или три входных переменных):

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

function K = harrisResponse(Ix, Iy) 
+0

Я вернулся, чтобы не фильтровать Ix2 и т. Д., Поэтому в копии на stackoverflow осталась некоторая ошибка. – Etan

+0

Проблема заключалась в том, что я не суммировал все пиксели в квадрате 3x3, чтобы узнать Ix2 и т. Д .; вместо этого я просто использовал соответствующий пиксель. После изменения H таким образом, что он суммирует все Ix2, Ixy и Iy2 для всех 9 пикселей, он выглядит очень красиво. – Etan

+1

det (H)/trace (H) является часто используемым приближением в случае, когда у вас не будет лямбда. – Etan

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

Но зачем вычислять 'C = (Ix. * Iy).^4' вместо простого' C = (Ix. * Iy) '? –

0

Существует функция, которая предусмотрена в панели инструментов Computer Vision System Tool detectHarrisFeatures.

3

В основном, Харрис обнаружения угол будет иметь 5 шагов:

  1. Gradient вычислений
  2. Gaussian сглаживания
  3. Harris мера вычисления
  4. Non-максимальное подавление
  5. Thresholding

Если вы внедряете 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); 
1

Решение, которое я реализовал с питоном, это работает для меня, я надеюсь, что вы найдете то, что вы ищете

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) 
Смежные вопросы