Frage

Ich bin der Umsetzung einer Ecke Harris Detektor für pädagogische Zwecke, aber ich bin an der harris Antwort Teil stecken. Im Grunde, was ich tue, ist:

  1. Compute Bild Intensitätsgradienten in x- und y-Richtung
  2. Blur Ausgabe von (1)
  3. Compute Harris Antwort über Ausgabe von (2)
  4. Suppress nicht-Maximas in Ausgang (3) in einem 3x3-Nachbarschaft und Schwellenausgang

1 und 2 scheinen zu funktionieren; Allerdings bekomme ich sehr kleine Werte wie die Harris Antwort und keinen Punkt hat die Schwelle zu erreichen. Eingang ist eine Standard-Outdoor-Fotografie.

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

Für das Beispielbild, max endet als 6.4163e-018, die viel zu niedrig erscheint.

War es hilfreich?

Lösung

Eine Ecke in Harris Eckendetektion wird als „der höchste Pixelwert in einem Bereich“ (in der Regel 3X3 oder 5x5) definiert, um Ihr Kommentar zu keinem Zeitpunkt eine „Schwelle“ erreicht mich fremd zu sein scheint. Sammeln Sie einfach alle Pixel, die einen höheren Wert als alle anderen Pixel in der 5x5 Nachbarschaft um sie herum haben.

Ansonsten: Ich bin nicht 100% sicher, aber ich denke, Sie sollten haben:

K(j,i) = det(H) - lambda*(trace(H)^2) Wo Lambda eine positive Konstante ist, dass die Arbeiten in Ihrem Fall (und Harris vorgeschlagene Wert ist 0,04).

Im Allgemeinen ist der einzige vernünftige Moment Ihre Eingabe zu filtern, ist vor diesem Punkt:

[Ix, Iy] = intensityGradients(img);

Das Filtern Ix2, Iy2 und Ixy nicht viel Sinn für mich macht.

Außerdem denke ich, Ihr Beispielcode hier falsch ist (tut Funktion harrisResponse haben zwei oder drei Eingangsgrößen?):

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

function K = harrisResponse(Ix, Iy)

Andere Tipps

Die Lösung, dass ich mit Python implementiert, es funktioniert für mich Ich hoffe, Sie finden, was Sie suchen

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)

Vorgeschlagene Implementierung ist schrecklich ineffizient. Lets' starten, nachdem Gradienten Berechnung (die auch optimiert werden kann):

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

keine Schleifen erforderlich, da Matlab hasst Schleifen.

Im Grunde Erkennung Harris Ecke wird 5 Stufen hat:

  1. Gradient Berechnung
  2. Gaußglättung
  3. Harris Maß Berechnung
  4. Nicht maximale Unterdrückung
  5. Thresholding

Wenn Sie in MATLAB implementieren, wird es leicht sein, den Algorithmus zu verstehen und die Ergebnisse erhalten.

Der folgende Code von MATLAB kann Ihnen helfen, Ihre Zweifel zu lösen:

% 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);

Es gibt eine Funktion für den in der Computer Vision System Toolbox namens detectHarrisFeatures.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top