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 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
5 Réponses :
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 En dehors de cela:
Je ne suis pas sûr à 100%, mais je pense que vous devriez avoir: 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 En outre, je pense que votre code exemple est faux ici (fonction 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. 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> ix2 code>, iy2 code> et ixy code > ne m'aime pas beaucoup. P> harrisresponse code> a deux ou trois variables d'entrée?): P > H = harrisResponse(Ix2, Ixy, Iy2);
[...]
function K = harrisResponse(Ix, Iy)
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?
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(:))
Mais pourquoi calculer c = (ix. * Iy). ^ 4 code> au lieu de simple c = (ix. * Iy) code>?
Il existe une fonction pour cela dans la boîte à outils du système de vision de l'ordinateur appelé DetectHarRiscatures CODE>. P>
Fondamentalement, la détection des angles Harris aura 5 étapes:
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);
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)
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