Rilevamento di un cerchio in dati di immagine rumorosi


17

Ho un'immagine che assomiglia a quella qui sotto: inserisci qui la descrizione dell'immagine

Sto cercando di trovare il raggio (o diametro) del cerchio. Ho provato a utilizzare la trasformazione circolare di Hough (tramite matlab imfindcircles(bw,[rmin rmax],'ObjectPolarity','bright')) e adattandomi a un cerchio o un'ellisse (funzione fatta in casa che funziona abbastanza bene per i dati meno rumorosi, vedi sotto).

Ho anche provato un po 'di elaborazione delle immagini per ottenere un cerchio più chiaro, ad esempio, vedi sotto:

se = strel('disk', 2);
bw = imdilate(bw, se);
bw = bwareaopen(bw,100000); 
bw =  edge(bw); 

inserisci qui la descrizione dell'immagine

Tuttavia, quando fornisco l'immagine elaborata a entrambe le tecniche (adattamento di Hough e circle \ ellisse) nessuna delle due riesce a rilevare il cerchio in modo decente.

Ecco uno snippet di codice del cercatore di cerchi che ho scritto (matlab) [riga col] = trova (bw); contour = bwtraceboundary (bw, row (1), col (1)], 'N', connettività, num_points);

    x = contour(:,2);
    y = contour(:,1);

    % solve for parameters a, b, and c in the least-squares sense by
    % using the backslash operator
    abc = [x y ones(length(x),1)] \ -(x.^2+y.^2);
    a = abc(1); b = abc(2); c = abc(3);

    % calculate the location of the center and the radius
    xc = -a/2;
    yc = -b/2;
    radius  =  sqrt((xc^2+yc^2)-c);

Saranno apprezzati approcci alternativi ...


La trasformazione Hough cerca un cerchio, non un disco pieno. dovresti prima fare il rilevamento dei bordi per convertire il disco pieno in un cerchio vuoto. quali sono le proprietà delle tue cerchie? la dimensione è costante? possono essere ellissi? i punti possono essere distribuiti in modo diverso?
endolith

Ho provato (vedi esempio modificato), è troppo rumoroso o non abbastanza circolare? Inoltre, le dimensioni sono costanti e possono presentare un'ellitticità minima (sebbene in realtà sia una finestra perfettamente circolare) a causa di un errore dell'angolo della telecamera.
Bla

se la dimensione e la forma sono costanti, potresti provare qualcosa come la correlazione incrociata di un modello di disco riempito con l'immagine del punto originale
endolith

Accanto alla mia risposta, penso che potresti provare a farlo in una fase troppo successiva della tua pipe di elaborazione delle immagini. Potresti dirci di più sul problema e mostrare alcuni passaggi precedenti?
Andrey Rubshtein,

Risposte:


13

Ecco la mia soluzione, è vicina all'idea di @ Yoda, ma ho cambiato alcuni passaggi.

  • Contrassegna tutti i pixel in modo tale che ci siano almeno 6 pixel nel loro vicinato 7x7
  • Rimuovi tutti i BLOB, ma il più grande
  • Riempi i buchi
  • Applica il rilevamento dei bordi
  • Trova la cerchia usando la trasformazione di Hough

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

Ecco il codice Matlab pertinente. Sto usando Hough Transform per i cerchi .m file nel mio codice.

function FindCircle()
    close all;
    im = imread('C:\circle.png');
    im = im(:,:,2);

    ims = conv2(double(im), ones(7,7),'same');
    imbw = ims>6;
    figure;imshow(imbw);title('All pixels that there are at least 6 white pixels in their hood');

    props = regionprops(imbw,'Area','PixelIdxList','MajorAxisLength','MinorAxisLength');
    [~,indexOfMax] = max([props.Area]);
    approximateRadius =  props(indexOfMax).MajorAxisLength/2;

    largestBlobIndexes  = props(indexOfMax).PixelIdxList;
    bw = false(size(im));
    bw(largestBlobIndexes) = 1;
    bw = imfill(bw,'holes');
    figure;imshow(bw);title('Leaving only largest blob and filling holes');
    figure;imshow(edge(bw));title('Edge detection');

    radiuses = round ( (approximateRadius-5):0.5:(approximateRadius+5) );
    h = circle_hough(edge(bw), radiuses,'same');
    [~,maxIndex] = max(h(:));
    [i,j,k] = ind2sub(size(h), maxIndex);
    radius = radiuses(k);
    center.x = j;
    center.y = i;

    figure;imshow(edge(bw));imellipse(gca,[center.x-radius  center.y-radius 2*radius 2*radius]);
    title('Final solution (Shown on edge image)');

    figure;imshow(im);imellipse(gca,[center.x-radius  center.y-radius 2*radius 2*radius]);
    title('Final solution (Shown on initial image)');

end

1
Cosa sta facendo qui la trasformazione di Hough che la risolve e trova il cerchio blu? Proietta molti cerchi di raggi diversi in posizioni diverse sull'immagine e trova quello che si adatta meglio?
Spacey,

@Mohammad, è il solito rivelatore di cerchi. Utilizza il binning e il voto.
Andrey Rubshtein l'

Puoi anche utilizzare la Trasformazione della simmetria radiale rapida (FRST) dopo il primo passaggio di questa risposta.
Geniedesalpages

10

È abbastanza semplice farlo utilizzando l'elaborazione delle immagini. Quanto segue è una dimostrazione del concetto in Mathematica . Dovrai tradurlo in MATLAB.

  • Innanzitutto, tagliare gli assi e mantenere solo la parte dell'immagine di esso. Chiamo questa variabile img.
  • Binarizza l'immagine e dilatala, seguita da una trasformazione di riempimento. Rimuovo anche i piccoli componenti vaganti che non sono collegati al BLOB principale. Dovrebbe darti qualcosa di simile al seguente:

    filled = Binarize@img ~Dilation~ 3 // FillingTransform // DeleteSmallComponents
    

  • Quindi, trova il centroide di questo BLOB e il raggio equivalente del disco del BLOB (openCV, MATLAB hanno tutti comandi equivalenti per farlo)

    {center, radius} = 1 /. ComponentMeasurements[filled, {"Centroid", "EquivalentDiskRadius"}]
    
  • Questo è tutto! Ora traccia l'immagine originale e un cerchio con il centro e il raggio sopra per vedere come si adatta:

    Show[img, Graphics[{Red, Circle[center, radius]}]]
    


Risposta fantastica! Puoi ampliare la trasformazione di dilatazione e riempimento?
Spacey,

@Mohammad dilatazione è un funzionamento di base e sarebbe facilmente spiegabile con l'articolo wiki. La trasformazione di riempimento riempie i "buchi" o, in altre parole, insiemi di pixel circondati da pixel di valore superiore. Vedi la sezione "Ulteriori informazioni" qui
Lorem Ipsum

Ah scusa, ho digitato male. Ho una certa familiarità con la trasformazione di dilatazione, in realtà mi chiedevo se potessi espandere la "trasformazione di riempimento". Quale set di regole sta usando esattamente? Non riesco a trovare informazioni correlate a questo. Forse prende un altro nome?
Spacey,

@yoda, grazie per la risposta, ma se leggi la domanda noteresti che ho provato la dilatazione e l'adattamento. L'immagine prodotta prima di rilevare i bordi è simile alla tua. Mi sento in forma, non è preciso. Lo stesso vale per la tua vestibilità, puoi vedere che la parte superiore del cerchio montato è troppo grande, presumibilmente perché prendi in considerazione il punto rumoroso sulla parte superiore sopra il cerchio. Ho anche provato a montare un'ellisse (come indicato nella domanda), il problema è che l'adattamento non è abbastanza buono. Penso che forse un modo migliore sarebbe usare la parte migliore del cerchio (un arco) per adattarsi.
Bla

@nate Non capisco cosa intendi per "parte superiore del cerchio montato" e "parte migliore del cerchio". Puoi utilizzare metriche diverse ... riquadro di delimitazione, lunghezza dell'asse maggiore, lunghezza dell'asse minore, distanza media dal centroide, distanza mediana dal centroide, ecc. Tutto dipende da ciò che desideri.
Lorem Ipsum,
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.