11
votes

Mise en œuvre d'un détecteur de coin Harris

Je suis en train de mettre en œuvre un détecteur de coin Harris à des fins éducatives, mais je suis coincé à la partie Réponse de Harris. Fondamentalement, ce que je fais, c'est:

  1. Calculez des gradients d'intensité d'image de calcul dans X- et Y-direction LI>
  2. flou de sortie de (1) li>
  3. Compute Harris Réponse sur la sortie de (2) li>
  4. supprimer des non-maximums en sortie de (3) dans une sortie de 3x3-quartier et de seuil li> ol>

    1 et 2 semblent fonctionner bien; Cependant, je reçois de très petites valeurs en tant que réponse Harris, et aucun point n'atteint le seuil. L'entrée est une photographie extérieure standard. P>

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


0 commentaires

5 Réponses :


7
votes

Un coin dans la détection de coin Harris est défini comme "le pixel de valeur la plus élevée dans une région" (généralement 3x3 code> ou 5x5 code>) donc votre commentaire sur le point d'atteindre un " seuil "semble étrange pour moi. Collectez simplement tous les pixels qui ont une valeur plus élevée que tous les autres pixels du quartier code> 5x5 code> autour d'eux.

En dehors de cela: Je ne suis pas sûr à 100%, mais je pense que vous devriez avoir: p>

k (j, i) = det (h) - lambda * (trace (H) ^ 2) code > Où Lambda est une constante positive qui fonctionne dans votre cas (et la valeur suggérée Harris est de 0,04). P>

en général Le seul moment sensible pour filtrer votre entrée est avant ce point: p>

[IX, IY] = IntensensitéGradients (IMG); Code> P>

Filtrage ix2 code>, iy2 code> et ixy code > ne m'aime pas beaucoup. P>

En outre, je pense que votre code exemple est faux ici (fonction harrisresponse code> a deux ou trois variables d'entrée?): P >

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

function K = harrisResponse(Ix, Iy)


4 commentaires

Je n'ai plus de filtrer IX2, etc., il y avait donc un bogue à gauche dans la copie sur Stackoverflow.


Le problème était que je n'ai pas résumé tous les pixels du carré 3x3 pour connaître l'IX2, etc.; Au lieu de cela, je viens d'utiliser le pixel correspondant. Après avoir changé H de manière à résumer tout IX2, IXY et IY2 pour les 9 pixels, il a l'air très bien.


Det (h) / Trace (H) est une approximation souvent utilisée dans le cas où vous n'aurez pas de Lambda.


Je ne savais pas ce dernier tour. Joli. Il semble que vous résolvez vous-même le problème, sympa! (Et l'âge de l'âge travaille toujours: expliquer simplement le problème à quelqu'un vous aide à vous rendre à la solution) est-ce le code de travail?



3
votes

La mise en œuvre proposée est terriblement inefficace. Permet de démarrer après le calcul des gradients (qui peut être optimisé aussi):

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


1 commentaires

Mais pourquoi calculer c = (ix. * Iy). ^ 4 au lieu de simple c = (ix. * Iy) ?



0
votes

Il existe une fonction pour cela dans la boîte à outils du système de vision de l'ordinateur appelé DetectHarRiscatures .


0 commentaires

5
votes

Fondamentalement, la détection des angles Harris aura 5 étapes:

  1. Calcul de gradient LI>
  2. lissage gaussien li>
  3. Harris mesurez le calcul LI>
  4. Suppression non maximale li>
  5. seuillage li> ol>

    Si vous mettez en œuvre dans MATLAB, il sera facile de comprendre l'algorithme et d'obtenir les résultats. P>

    Le code suivant de MATLAB peut vous aider à résoudre vos doutes: P >

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


0 commentaires

7
votes

La solution que j'ai implémentée avec Python, cela fonctionne pour moi, j'espère que vous trouverez ce que vous recherchez

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)


2 commentaires

Qu'est-ce que PC, et PR ce qu'il donne?


@acousticPyThon PC et PR sont index où résultat == 1, signifie que le résultat [PC] [PR] [PR] == 1, les éléments du PC et PR à la même position sont les résultats égaux à un dans le tableau 2D