Aiuta a capire la trasformazione di Hough


19

Sto cercando di ottenere una trasformazione di Hough per funzionare in MATLAB, ma sto riscontrando problemi. Ho un modo davvero brutto di rilevare i picchi che devono essere riparati, ma prima devo essere in grado di invertire la trasformazione di hough per creare di nuovo correttamente le linee. Questo è il tipo di cose che sto ricevendo proprio ora:

inserisci qui la descrizione dell'immagine

sembra ruotato di 90 gradi, ma non sono sicuro del perché. Non sono sicuro se è il mio spazio Hough ad essere sbagliato, o se è il modo in cui de-Hough e traccia le linee. Qualcuno potrebbe anche aiutare a migliorare il mio rilevamento di picco? Le immagini utilizzate nel codice sono qui

%% load a sample image; convert to grayscale; convert to binary

%create 'x' image (works well)
a = eye(255);
b = flipud(eye(255));
x = a + b;
x(128,128) = 1;

%image = rgb2gray(imread('up.png')) < 255;
%image = rgb2gray(imread('hexagon.png')) < 255;
%image = rgb2gray(imread('traingle.png')) < 255;
%%% these work
%image = x;
%image = a;
image = b;    

%% set up variables for hough transform
theta_sample_frequency = 0.01;                                             
[x, y] = size(image);
rho_limit = norm([x y]);                                                
rho = (-rho_limit:1:rho_limit);
theta = (0:theta_sample_frequency:pi);
num_thetas = numel(theta);
num_rhos = numel(rho);
hough_space = zeros(num_rhos, num_thetas);

%% perform hough transform
for xi = 1:x
    for yj = 1:y
        if image(xi, yj) == 1 
            for theta_index = 1:num_thetas
                th = theta(theta_index);
                r  = xi * cos(th) + yj * sin(th);
                rho_index = round(r + num_rhos/2);                      
                hough_space(rho_index, theta_index) = ...
                     hough_space(rho_index, theta_index) + 1;
            end
        end
    end
end  

%% show hough transform
subplot(1,2,1);
imagesc(theta, rho, hough_space);
title('Hough Transform');
xlabel('Theta (radians)');
ylabel('Rho (pixels)');
colormap('gray');

%% detect peaks in hough transform
r = [];
c = [];
[max_in_col, row_number] = max(hough_space);
[rows, cols] = size(image);
difference = 25;
thresh = max(max(hough_space)) - difference;
for i = 1:size(max_in_col, 2)
   if max_in_col(i) > thresh
       c(end + 1) = i;
       r(end + 1) = row_number(i);
   end
end

%% plot all the detected peaks on hough transform image
hold on;
plot(theta(c), rho(r),'rx');
hold off;


%% plot the detected line superimposed on the original image
subplot(1,2,2)
imagesc(image);
colormap(gray);
hold on;

for i = 1:size(c,2)
    th = theta(c(i));
    rh = rho(r(i));
    m = -(cos(th)/sin(th));
    b = rh/sin(th);
    x = 1:cols;
    plot(x, m*x+b);
    hold on;
end

Collegato: come fare il De-Houghing di un'immagine trasformata di Hough?


sei riuscito a risolvere il tuo problema? sto affrontando un problema simile. grazie
Erez Posner

Transformation de hough sous matlab pour détecter plusieurs

Risposte:


11

Innanzitutto, Matlab ha una trasformazione Hough integrata : non è necessario reinventare la ruota.

[H,T,R] = hough(BW,'RhoResolution',0.5,'Theta',-90:0.5:89.5);

Sebbene l'immagine non richieda necessariamente il rilevamento dei bordi, è possibile migliorare i tempi di elaborazione e l'efficacia dell'algoritmo che sto utilizzando. Il tuo triangolo ha regioni grasse di bianco e nero. Idealmente, il triangolo dovrebbe avere uno spessore di 1px che segna i bordi del triangolo. Usa il rilevamento di Canny Edge

BW = edge(Image,'canny');

il risultato è \ theta è compreso nell'intervallo gradi mentre la trama è (o ), quindi sottrai gradi ( ).-90<θ<900<θ<1800<θ<π90π/2

Vi è il potenziale per scegliere il picco sbagliato perché ci sono picchi vicini che possono essere più grandi nella matrice dell'accumulatore. Mentre ci sono molti algoritmi qui è uno che ho visto usato in Hough Transforms in passato:

1) Define a region shape (typically its square) 
2) Define an accumulator threshold  
3) Select one pixel in the accumulator matrix
4) If it is a peak (i.e., larger than neighboring values above a threshold)
       a) look at the points within the region shape.
       b) If there is a larger value
              this is not a peak
          Else
              this is a peak
 5) Move to next pixel in accumulator matrix.

Cerca in HoughLines per visualizzare le linee di trasformazione di Hough, i risultati:

http://www.mathworks.com/help/toolbox/images/ref/houghlines.html

Effetti dell'utilizzo di Canny Edge Detector

Il rilevamento dei bordi può potenzialmente trasformare ciascun lato del triangolo in due linee.

L'obiettivo del rilevamento del margine astuto è quello di produrre bordi estremamente sottili / stretti utilizzando la soppressione non prossimale

Canny Edge Detection in a Nutshell (Fonte: Digital Image Processing, Gonazalez)

1) Smooth input Image using a Gaussian Filter
2) Compute the Gradient magnitude and angle (Sobel, Perwitt or robert cross filters)
3) Apply Nonmaxima suppression (this is where the thinning happens) 
   a) Figure out which direction the edge is
   b) If the edge's magnitude is smaller than one of its two neighbors in the direction of the edge
          set the edge point to zero
      Else
          leave it alone
4) Use double thresholding and connectivity analysis to detect and link edges

Grazie per la risposta. Lo sto facendo da zero per capirlo meglio. il rilevamento intelligente del margine fornisce ancora 2 triangoli. uno per il bordo interno e fuori per il bordo esterno. Ho imparato la teoria da Wikipedia, che afferma che theta è 0: pi. So che la funzione integrata utilizza -pi / 2: pi / 2, ma non dovrebbe esserci una vera differenza?
waspinator

Fin dall'inizio, la distanza non dovrebbe fare la differenza. (puoi dire la differenza tra una linea che è stata ruotata di 180 gradi?) TUTTAVIA, Ciò fa la differenza se stai usando la trasformazione hough per gli algoritmi di correzione delle immagini. (Significherebbe la differenza tra un'immagine
capovolta

Il rilevamento dei bordi non produrrebbe 2 righe in cui si desidera trovarne solo 1? Qualcosa che trova il centro di una linea spessa sarebbe meglio.
endolith

@endolith Incluso un po 'di discussione sul rilevamento dei bordi nel post originale
CyberMen,

'Non c'è bisogno di reinventare la ruota'? Dillo al mio istruttore ;-)
Nathan Schwermann,

3
    if image(xi, yj) == 1 

deve essere modificato in

    if image(yj, xi) == 1 

affinché le linee si risolvano nel profondo


1

La risposta usando i 3 loop è meno che ottimale e potrebbe essere migliorata, qui c'è più di un approccio / punto di vista intuitivo:

Ogni coppia di punti validi imposta un unico a & b di y = ax + b. Una linea avrà molte coppie con lo stesso valore a & b, quindi una linea lunga sarà presente come picco. Questo vale anche per le coordinate polari di r & teta.

Invece di trattare ogni punto separatamente, usa coppie di punti. Se è possibile memorizzare tutti i punti (di solito sparsi) in un elenco separato, è meglio, ma non è un must.

  1. Prendi ogni coppia e calcola il suo a & b. (arrotondato a valori discreti)
  2. Passare al punto specifico dell'array e aggiungere 1.

Linea lunga -> molte coppie con la stessa a, b.
Punti sporadici -> piccoli conteggi in celle specifiche -> più come il disordine.


Un altro modo di vederlo è dal punto di vista del Radon / proiettivo.

  • Una linea proietterà fortemente su una "linea di raccolta" perpendicolare, quindi con un punteggio elevato.
  • Se l'angolo tra la linea e la "linea di raccolta" non è di 90 gradi o la linea di raccolta non raccoglie tutti i punti della linea proiettati in questa "linea di raccolta", ci sarà un punteggio più basso.
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.