10

Tôi đang thực hiện thiết bị dò góc Harris cho mục đích giáo dục nhưng tôi bị kẹt ở phần phản hồi harris. Về cơ bản, những gì tôi đang làm, là:Thực hiện thiết bị dò góc Harris

  1. Tính gradient cường hình ảnh trong x và y hướng
  2. đầu ra
  3. Blur (1)
  4. phản ứng
  5. Tính Harris qua sản lượng (2)
  6. Loại bỏ các phi tối đa ở đầu ra của (3) trong một vùng lân cận 3x3 và ngưỡng đầu ra

1 và 2 dường như hoạt động tốt; tuy nhiên, tôi nhận được các giá trị rất nhỏ như phản ứng của Harris và không có điểm nào đạt đến ngưỡng đó. Đầu vào là một nhiếp ảnh ngoài trời tiêu chuẩn.

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

Đối với hình mẫu, tối đa kết thúc là 6.4163e-018 có vẻ quá thấp.

Trả lời

7

Góc phát hiện góc Harris được định nghĩa là "pixel có giá trị cao nhất trong khu vực" (thường là 3X3 hoặc 5x5) để nhận xét của bạn về điểm không đạt đến "ngưỡng" có vẻ lạ đối với tôi. Chỉ cần thu thập tất cả các pixel có giá trị cao hơn tất cả các pixel khác trong vùng lân cận 5x5 xung quanh chúng.

Ngoài ra: Tôi không chắc chắn 100%, nhưng tôi nghĩ bạn nên có:

K(j,i) = det(H) - lambda*(trace(H)^2) đâu lambda là một hằng số dương mà làm việc trong trường hợp của bạn (và Harris gợi ý giá trị là 0,04).

Nói chung thời điểm nhạy cảm chỉ để lọc đầu vào của bạn là trước thời điểm này:

[Ix, Iy] = intensityGradients(img);

Filtering Ix2, Iy2Ixy không có ý nghĩa nhiều đối với tôi.

Hơn nữa, tôi nghĩ rằng mẫu mã của bạn là sai ở đây (không chức năng harrisResponse có hai hoặc ba biến đầu vào?):

thực hiện
H = harrisResponse(Ix2, Ixy, Iy2); 
[...] 

function K = harrisResponse(Ix, Iy) 
+0

Tôi đã hoàn nguyên để không lọc Ix2 vv nữa, do đó có một số lỗi còn lại trong bản sao trên stackoverflow. – Etan

+0

Vấn đề là tôi đã không tổng hợp tất cả các điểm ảnh trong hình vuông 3x3 để tìm ra Ix2 vv; thay vào đó, tôi vừa sử dụng pixel tương ứng. Sau khi thay đổi H theo cách nó tổng hợp tất cả Ix2, Ixy và Iy2 cho tất cả 9 pixel, nó trông rất đẹp. – Etan

+1

det (H)/dấu vết (H) là một xấp xỉ được sử dụng trong trường hợp bạn sẽ không có lambda. – Etan

3

đề xuất là terribly không hiệu quả. Cho phép bắt đầu sau khi tính toán gradient (có thể được tối ưu hóa quá):

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

Không vòng cần thiết, bởi vì Matlab ghét vòng.

+2

Nhưng tại sao tính toán 'C = (Ix. * Iy).^4' thay vì đơn giản' C = (Ix. * Iy) '? –

0

Có chức năng trong Hộp công cụ hệ thống tầm nhìn máy tính được gọi là detectHarrisFeatures.

3

Về cơ bản, phát hiện góc Harris sẽ có 5 bước:

  1. Gradient tính toán
  2. Gaussian smoothing
  3. Harris biện pháp tính toán
  4. đàn áp phi tối đa
  5. Thresholding

Nếu bạn đang thực hiện MATLAB, nó sẽ dễ hiểu thuật toán và nhận kết quả.

Các mã sau đây của MATLAB có thể giúp bạn giải quyết những nghi ngờ của bạn:

% 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

Các giải pháp mà tôi thực hiện với trăn, nó hoạt động cho tôi, tôi hy vọng bạn tìm thấy những gì bạn đang tìm kiếm

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)