Come implementare una trasformazione Hough basata su gradiente


9

Sto cercando di utilizzare la trasformazione di Hough per il rilevamento dei bordi e vorrei utilizzare le immagini a gradiente come base.

Quello che ho fatto finora, dato l'immagine Idi dimensioni [M,N]e le derivate parziali gx, gy, è calcolare l'angolo di pendenza in ciascun pixel come thetas = atan(gy(x,y) ./ gx. Allo stesso modo, calcolo l'entità del gradiente come magnitudes = sqrt(gx.^2+gy.^2).

Per creare la trasformazione di Hough, utilizzo il seguente codice MATLAB:

max_rho = ceil(sqrt(M^2 + N^2));
hough = zeros(2*max_rho, 101);
for x=1:M
    for y=1:N
        theta = thetas(x,y);
        rho = x*cos(theta) + y*sin(theta);

        rho_idx = round(rho)+max_rho;
        theta_idx = floor((theta + pi/2) / pi * 100) + 1;
        hough(rho_idx, theta_idx) = hough(rho_idx, theta_idx) + magnitudes(x,y);
    end
end

La trasformazione di Hough risultante sembra plausibile (vedi http://i.stack.imgur.com/hC9mP.png ), ma quando provo ad usare i suoi massimi come parametri di bordo nell'immagine originale, i risultati sembrano più o meno casuali. Ho fatto qualcosa di sbagliato nel costruire la trasformazione di Hough?

AGGIORNAMENTO : Ho avuto un errore stupido nel mio codice: è rhostato calcolato come x*cos(theta)+y*cos(theta)anziché x*cos(theta)+y*sin(theta). Cioè, stavo usando due coseni invece di un coseno e un seno. Ho modificato il codice sopra e la nuova immagine risultante è sotto. Questo, tuttavia, non ha dato bordi migliori.

@endolith: per tracciare un bordo, dato un valore massimo nella houghmatrice a rho_idx, theta_idx, traduco gli indici in rho,thetavalori:

theta = (theta_idx -1) / 100 * pi - pi / 2;
rho = rho_idx - max_rho;

Alla fine ho tracciato il bordo come y= (rho - x*cos(theta)) / sin(theta).

Nuovo risultato


"quando provo ad usare i suoi massimi come parametri del bordo nell'immagine originale" Come lo stai facendo?
endolith,

@Jonas Due Vesterheden Mi chiedo solo che questa è una volta l'immagine della frequenza doppler VS? ...
Spacey,

@Mohammad: Non che io sappia. L'immagine originale è di alcuni circuiti stampati. Cosa intendi con "VS"?
Jonas Due Vesterheden,

@JonasDueVesterheden 'VS' significa semplicemente 'versus'. (Tempo contro frequenza doppler ') :-)
Spacey,

Prima di applicare la soppressione Non max su di essa, è necessario uniformare la mappa hough.

Risposte:


2

Sono un po 'confuso dalla tua domanda. La trasformazione Hough viene utilizzata per rilevare linee, non bordi.

Se tutto ciò che desideri è una mappa dei bordi, dovresti semplicemente impostare la soglia del gradiente o utilizzare qualcosa di più sofisticato come il rilevatore di bordi Canny.

Se si desidera rilevare linee rette, sarebbe meglio iniziare con una mappa laterale e quindi utilizzare la houghfunzione se la casella degli strumenti Elaborazione immagine, se si ha accesso ad essa. Il problema con una trasformazione di Hough sul gradiente è che i pixel del bordo che formano una linea retta potrebbero avere orientamenti del gradiente opposti. Ad esempio, considera un motivo a scacchiera. Un bordo tra due file di quadrati capovolge l'orientamento a seconda che tu abbia un quadrato nero sopra e un quadrato bianco sotto o viceversa.

Per quanto riguarda la tua implementazione, penso che il problema sia che i contenitori nella tua matrice Hough sono troppo piccoli. In sostanza, la dimensione del contenitore nella dimensione rho è 1 e la dimensione del contenitore nella dimensione theta è inferiore a 2 gradi. Ciò significa che gli orientamenti del gradiente devono scendere molto precisamente per formare una linea, cosa che raramente accade nella pratica. Se si caculano rho_idx e theta_idx in modo che i bin siano più grandi, ciò renderà il rilevatore di linea più tollerante agli errori e si potrebbero ottenere linee migliori.


1

Non ho idea se questo sia un problema, ma atan () ti dà solo angoli da -90 a +90 gradi a causa dell'ambiguità del quadrante. Per ottenere l'angolo di sfumatura completo (da -180 a 180) è necessario utilizzare atan2 ().


Grazie per il suggerimento! A quanto ho capito, dovrebbe essere sufficiente usare gli angoli da -90 a +90 gradi, poiché le "direzioni" dei bordi non contano. Ho provato a utilizzare atan2, ma non sembra risolvere i problemi.
Jonas Due Vesterheden,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.