Erkennung eines Kreises in verrauschten Bilddaten

17

Ich habe ein Bild, das wie das folgende aussieht: Bildbeschreibung hier eingeben

Ich versuche den Radius (oder Durchmesser) des Kreises zu finden. Ich habe versucht, eine kreisförmige Hough-Transformation (über Matlabs imfindcircles(bw,[rmin rmax],'ObjectPolarity','bright')) und durch Anpassen an einen Kreis oder eine Ellipse (hausgemachte Funktion, die für weniger verrauschte Daten ziemlich gut funktioniert, siehe unten) zu verwenden.

Ich habe auch einige Bildbearbeitungen versucht, um einen klareren Kreis zu erhalten, siehe unten:

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

Bildbeschreibung hier eingeben

Wenn ich das verarbeitete Bild jedoch einer der beiden Techniken (Hough- und Kreis-Ellipsen-Anpassung) zuführe, gelingt es keinem von beiden, den Kreis auf angemessene Weise zu erkennen.

Hier ist ein Codeausschnitt des Kreisfinders, den ich geschrieben habe (matlab) [row col] = find (bw); Kontur = bwtraceboundary (bw, Zeile (1), Spalte (1)], 'N', Konnektivität, 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);

Alternative Ansätze werden geschätzt ...

bla
quelle
Hough Transformation sucht nach einem Kreis, nicht nach einer gefüllten Scheibe. Sie müssten zuerst die Kantenerkennung durchführen, um die gefüllte Disc in einen leeren Kreis umzuwandeln. Was sind die Eigenschaften Ihrer Kreise? Ist die Größe konstant? können sie ellipsen sein können die punkte unterschiedlich verteilt sein?
Endolith
Ich habe versucht (siehe bearbeitetes Beispiel), es ist entweder zu laut oder nicht kreisförmig genug? Darüber hinaus ist die Größe konstant und kann aufgrund von Kamerawinkelfehlern eine winzige Elliptizität aufweisen (obwohl es sich in Wirklichkeit um ein perfekt kreisförmiges Fenster handelt).
bla
Wenn die Größe und Form konstant ist, können Sie eine Kreuzkorrelation zwischen einer gefüllten Disc-Vorlage und dem ursprünglichen Punktbild
Endolith
Abgesehen von meiner Antwort denke ich, dass Sie versuchen, dies in einem zu späteren Stadium Ihrer Bildverarbeitungs-Pipe zu tun. Können Sie uns mehr über das Problem erzählen und einige frühere Schritte aufzeigen?
Andrey Rubshtein

Antworten:

13

Hier ist meine Lösung, sie kommt der Idee von @ Yoda nahe, aber ich habe einige Schritte geändert.

  • Markieren Sie alle Pixel so, dass sich mindestens 6 Pixel in ihrer 7x7-Nachbarschaft befinden
  • Entfernen Sie alle Kleckse, aber die größten
  • Füllen Sie die Löcher
  • Kantenerkennung anwenden
  • Finden Sie den Kreis mit der Hough-Transformation

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben

Hier ist der relevante Matlab-Code. Ich verwende Hough Transformation für Kreise .m-Datei in meinem Code.

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
Andrey Rubshtein
quelle
1
Was macht die Hough-Transformation hier, damit sie den blauen Kreis löst und findet? Projiziert es viele Kreise mit unterschiedlichen Radien an unterschiedlichen Positionen auf das Bild und findet es denjenigen, der am besten passt?
Spacey
@Mohammad, es ist der übliche Kreisdetektor. Es nutzt Binning und Voting.
Andrey Rubshtein
Sie können nach dem ersten Schritt in dieser Antwort auch die schnelle radiale Symmetrietransformation (FRST) verwenden.
Geniedesalpages
10

Es ist ziemlich einfach, dies mit der Bildverarbeitung zu tun. Das Folgende ist ein Proof of Concept in Mathematica . Sie müssen es in MATLAB übersetzen.

  • Trimmen Sie zuerst die Achsen und behalten Sie nur den Bildteil bei. Ich nenne diese Variable img.
  • Binarisieren Sie das Bild und erweitern Sie es, gefolgt von einer Füllungstransformation. Ich entferne auch kleine Streukomponenten, die nicht mit dem Hauptblob verbunden sind. Es sollte Ihnen ungefähr Folgendes geben:

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

  • Bestimmen Sie als Nächstes den Schwerpunkt dieses Blobs und den entsprechenden Plattenradius des Blobs (openCV und MATLAB verfügen alle über entsprechende Befehle, um dies zu tun).

    {center, radius} = 1 /. ComponentMeasurements[filled, {"Centroid", "EquivalentDiskRadius"}]
    
  • Das ist es! Zeichnen Sie nun das Originalbild und einen Kreis mit der obigen Mitte und dem Radius, um zu sehen, wie es passt:

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

Lorem Ipsum
quelle
Geniale Antwort! Können Sie bitte die Dilatation & Füllungstransformation erweitern?
Spacey
@ Mohammad Dilation ist eine grundlegende Operation und wird im Wiki-Artikel leicht erklärt. Die Filling-Transformation füllt "Löcher" oder mit anderen Worten Sätze von Pixeln aus, die von Pixeln mit höherem Wert umgeben sind. Siehe den Abschnitt "Weitere Informationen" hier
Lorem Ipsum
Entschuldigung, ich habe falsch geschrieben. Ich bin ein wenig mit Dilatationstransformationen vertraut und habe mich gefragt, ob Sie die 'Füllungstransformation' erweitern können. Welchen Regelsatz verwendet es genau? Ich kann anscheinend keine Informationen dazu finden. Vielleicht hat es einen anderen Namen?
Spacey
@yoda, danke für die Antwort, aber wenn du die Frage liest, wirst du bemerken, dass ich es mit Dilatation und Anpassung versucht habe. Das Bild, das erzeugt wird, bevor ich Kanten erkenne, ähnelt Ihrem. Ich bekomme etwas fit, es ist nicht genau. Das gleiche gilt für Ihre Passform. Sie können feststellen, dass der obere Teil des angepassten Kreises zu groß ist, vermutlich weil Sie den Rauschpunkt im oberen Teil über dem Kreis berücksichtigen. Ich habe auch versucht, eine Ellipse anzupassen (wie in der Frage angegeben). Das Problem ist, dass die Anpassung nicht gut genug ist. Ich denke, der vielleicht bessere Weg wäre, den besseren Teil des Kreises (einen Bogen) für die Anpassung zu verwenden.
bla
@nate Ich verstehe nicht, was du mit "oberer Teil des angepassten Kreises" und "besserer Teil des Kreises" meinst. Sie können verschiedene Metriken verwenden ... Begrenzungsrahmen, Hauptachsenlänge, Nebenachsenlänge, mittlerer Abstand vom Schwerpunkt, mittlerer Abstand vom Schwerpunkt usw. Es hängt alles davon ab, was Sie wollen.
Lorem Ipsum