it-swarm.com.de

Wie kann ich in MATLAB einen Kreis auf ein Bild zeichnen?

Ich habe ein Bild in MATLAB:

im = rgb2gray(imread('some_image.jpg');
% normalize the image to be between 0 and 1
im = im/max(max(im));

Und ich habe einige Arbeiten durchgeführt, die zu einer Reihe von Punkten geführt haben, die ich hervorheben möchte:

points = some_processing(im);

Wobei points eine Matrix ist, die die gleiche Größe wie im hat, mit einer in den interessanten Punkten.

Jetzt möchte ich an allen Stellen, an denen points 1 ist, einen Kreis auf das Bild zeichnen.

Gibt es eine Funktion in MATLAB, die das macht? Das Beste, was ich mir einfallen lassen kann, ist:

[x_p, y_p] = find (points);

[x, y] = meshgrid(1:size(im,1), 1:size(im,2))
r = 5;

circles = zeros(size(im));

for k = 1:length(x_p)
    circles = circles + (floor((x - x_p(k)).^2 + (y - y_p(k)).^2) == r);
end

% normalize circles
circles = circles/max(max(circles));

output = im + circles;

imshow(output)

Dies scheint mehr als etwas unelegant. Gibt es eine Möglichkeit, Kreise ähnlich der Funktion line zu zeichnen?

11
Nathan Fellman

Sie können den normalen PLOT Befehl mit einem kreisförmigen Markierungspunkt verwenden:

[x_p,y_p] = find(points);
imshow(im);         %# Display your image
hold on;            %# Add subsequent plots to the image
plot(y_p,x_p,'o');  %# NOTE: x_p and y_p are switched (see note below)!
hold off;           %# Any subsequent plotting will overwrite the image!

Sie können auch diese anderen Eigenschaften des Plotmarkers anpassen: MarkerEdgeColor , MarkerFaceColor , MarkerSize .

Wenn Sie dann das neue Bild mit den eingezeichneten Markierungen speichern möchten, können Sie diese Antwort, die ich gegeben habe eine Frage zur Beibehaltung der Bildabmessungen beim Speichern von Bildern aus Zahlen anzeigen.

HINWEIS: Beim Zeichnen von Bilddaten mit IMSHOW (oder IMAGE usw.) wird die normale Interpretation von Zeilen und Spalten im Wesentlichen umgedreht. Normalerweise wird die erste Dimension von Daten (d. H. Zeilen) als Daten betrachtet, die auf der X-Achse liegen würden. Aus diesem Grund verwenden Sie x_p wahrscheinlich als erste Gruppe von Werten, die von der Funktion FIND zurückgegeben werden. IMSHOW zeigt jedoch die erste Dimension der Bilddaten entlang der y-Achse an, sodass der erste von FIND zurückgegebene Wert in diesem Fall der y-Koordinatenwert ist.

20
gnovice

Diese Datei von Zhenhai Wang aus dem Dateiaustausch von Matlab Central erledigt den Trick. 

%----------------------------------------------------------------
% H=CIRCLE(CENTER,RADIUS,NOP,STYLE)
% This routine draws a circle with center defined as
% a vector CENTER, radius as a scaler RADIS. NOP is 
% the number of points on the circle. As to STYLE,
% use it the same way as you use the rountine PLOT.
% Since the handle of the object is returned, you
% use routine SET to get the best result.
%
%   Usage Examples,
%
%   circle([1,3],3,1000,':'); 
%   circle([2,4],2,1000,'--');
%
%   Zhenhai Wang <[email protected]>
%   Version 1.00
%   December, 2002
%----------------------------------------------------------------
2
Nathan Fellman

Lustig! Hier gibt es 6 Antworten, keine gibt die naheliegende Lösung an: die rectangle-Funktion.

Aus der Dokumentation :

Zeichnen Sie einen Kreis, indem Sie die Curvature-Eigenschaft auf [1 1] setzen. Zeichnen Sie den Kreis so, dass er den rechteckigen Bereich zwischen den Punkten (2,4) und (4,6) ausfüllt. Die Eigenschaft Position definiert das kleinste Rechteck, das den Kreis enthält.

pos = [2 4 2 2];
rectangle('Position',pos,'Curvature',[1 1])
axis equal

Also in deinem Fall:

imshow(im)
hold on
[y, x] = find(points);
for ii=1:length(x)
  pos = [x(ii),y(ii)];
  pos = [pos-0.5,1,1];
  rectangle('position',pos,'curvature',[1 1])
end

Im Gegensatz zur akzeptierten Antwort werden diese Kreise mit dem Bild skaliert. Sie können die Ansicht vergrößern und immer das gesamte Pixel markieren. 

1
Cris Luengo

Mit MATLAB und Image Processing Toolbox R2012a oder neuer können Sie die Funktion viscircles verwenden, um Kreise leicht über ein Bild zu legen. Hier ist ein Beispiel:

% Plot 5 circles at random locations
X = Rand(5,1);
Y = Rand(5,1);
% Keep the radius 0.1 for all of them
R = 0.1*ones(5,1);
% Make them blue
viscircles([X,Y],R,'EdgeColor','b');

Schauen Sie sich auch die imfindcircles -Funktion an, die die Hough-Kreis-Transformation implementiert. In der Online-Dokumentation für beide Funktionen (Links oben) finden Sie Beispiele, wie Kreise in einem Bild gesucht werden und wie die erkannten Kreise über dem Bild angezeigt werden.

Zum Beispiel:

% Read the image into the workspace and display it.
A = imread('coins.png');
imshow(A)

% Find all the circles with radius r such that 15 ≤ r ≤ 30.
[centers, radii, metric] = imfindcircles(A,[15 30]);

% Retain the five strongest circles according to the metric values.
centersStrong5 = centers(1:5,:);
radiiStrong5 = radii(1:5);
metricStrong5 = metric(1:5);

% Draw the five strongest circle perimeters.
viscircles(centersStrong5, radiiStrong5,'EdgeColor','b');
0

In neueren Versionen von MATLAB (I have 2013b) enthält die Computer Vision System Toolbox das vision.ShapeInserter System-Objekt , mit dem Formen auf Bildern gezeichnet werden können. Hier ein Beispiel für das Zeichnen gelber Kreise aus der Dokumentation:

yellow = uint8([255 255 0]); %// [R G B]; class of yellow must match class of I
shapeInserter = vision.ShapeInserter('Shape','Circles','BorderColor','Custom','CustomBorderColor',yellow);
I = imread('cameraman.tif'); 
circles = int32([30 30 20; 80 80 25]); %// [x1 y1 radius1;x2 y2 radius2]
RGB = repmat(I,[1,1,3]); %// convert I to an RGB image
J = step(shapeInserter, RGB, circles);
imshow(J);
0
buzjwa

Hmm, ich musste sie in diesem Aufruf umschalten:

k = convhull(x,y);
figure;
imshow(image);         %# Display your image
hold on;            %# Add subsequent plots to the image
plot(x,y,'o');  %# NOTE: x_p and y_p are switched (see note below)!
hold off;           %# Any subsequent plotting will overwrite the image!

Antwort auf die Kommentare:

x und y werden mit folgendem Code erstellt:

temp_hull = stats_single_object (k) .ConvexHull; 
 für k2 = 1: Länge (temp_hull) 
 i = i + 1; 
 [x (i, 1)] = temp_hull ( k2,1); 
 [y (i, 1)] = temp_hull (k2,2); 
 Ende;

es kann sein, dass der ConvexHull umgekehrt ist und daher die Darstellung anders ist. Oder dass ich einen Fehler gemacht habe und es sollte sein

[x (i, 1)] = temp_hull (k2,2); 
 [y (i, 1)] = temp_hull (k2,1);

Die Dokumentation ist jedoch nicht klar, welche Spalte = x OR y: Zitat: "Jede Zeile der Matrix enthält die x- und y-Koordinaten eines Scheitelpunkts des Polygons."

Ich lese dies, da x die erste Spalte und y die zweite Spalte ist.

0
Ramon Fincken