Pregunta

Tengo una imagen en MATLAB:

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

Y yo he hecho algún tipo de procesamiento que dio lugar a una serie de puntos que quiero destacar:

points = some_processing(im);

Donde points es una matriz del mismo tamaño que im con los de los puntos de interés.

Ahora quiero dibujar un círculo en la imagen en todos los lugares donde points es 1.

¿Hay alguna función en MATLAB que hace esto? Lo mejor que puedo llegar a decir:

[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)

Esto parece más que poco elegante. ¿Hay una manera de dibujar círculos similares a la función line?

¿Fue útil?

Solución

Se puede utilizar el con un circular punto marcador :

[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!

También puede ajustar estas otras propiedades del marcador de terreno: MarkerEdgeColor , MarkerFaceColor , MarkerSize .

Si a continuación desea guardar la nueva imagen con los marcadores representados en él, se puede ver en esta respuesta que he dado a una pregunta sobre el mantenimiento de dimensiones de imagen al guardar las imágenes de figuras.

Nota: Al trazar los datos de imagen con imshow (o IMAGEN , etc.), la interpretación normal de las filas y columnas se convierte esencialmente en volteado. Normalmente, la primera dimensión de los datos (es decir, filas) se considera como los datos que se encuentran en el eje x, y es probablemente por qué se utiliza x_p como el primer conjunto de valores devueltos por la Encuentre función. Sin embargo, imshow muestra la primera dimensión de los datos de imagen a lo largo de la eje y , por lo que el primer valor devuelto por FIND termina siendo el coordenada y valor en este caso.

Otros consejos

Este archivo por Zhenhai Wang de Matlab Intercambio de archivos de central hace el truco.

%----------------------------------------------------------------
% 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 <zhenhai@ieee.org>
%   Version 1.00
%   December, 2002
%----------------------------------------------------------------

divertido! Hay 6 respuestas aquí, ninguno da la solución obvia: la función rectangle

.

Desde el documentación :

  

Dibuje un círculo estableciendo la propiedad Curvatura a [1 1]. Dibujar el círculo de modo que llene el área rectangular entre los puntos (2,4) y (4,6). La propiedad de posición define el rectángulo más pequeño que contiene el círculo.

     

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

Así pues, en su caso:

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

A diferencia de la respuesta aceptada, estos círculos se escalan con la imagen, se puede acercar un siempre van a marcar todo el píxel.

Hmm que tenía que volver a cambiar en esta convocatoria:

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!

En respuesta a los comentarios:

x e y se crean utilizando el código siguiente:

temp_hull = stats_single_object(k).ConvexHull;
for k2 = 1:length(temp_hull)
   i = i+1;
     [x(i,1)] = temp_hull(k2,1);    
     [y(i,1)] = temp_hull(k2,2);    
 end;

podría ser que la ConvexHull es al revés, por lo que la trama es diferente. O que he cometido un error y debe ser

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

Sin embargo, la documentación no es clara acerca de que colum = X o Y: Cita: "Cada fila de la matriz contiene los ejes x e y las coordenadas de un vértice del polígono."

I leer esto como x es la primera columna e Y es la segunda colum.

En las nuevas versiones de MATLAB (tengo 2013b) el Sistema de herramientas de visión de computadora contiene la objeto Sistema vision.ShapeInserter que puede ser usado para dibujar formas en las imágenes. Aquí está un ejemplo de dibujar círculos amarillos de la documentación:

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);

Con MATLAB e Image Processing Caja de herramientas R2012a o posterior, puede utilizar el viscircles función para superponer fácilmente círculos sobre una imagen. He aquí un ejemplo:

% 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');

Además, la salida de la función imfindcircles que implementa la circular Hough transformar. La documentación en línea para ambas funciones (enlace de arriba) tiene ejemplos que muestran cómo encontrar los círculos en una imagen y la forma de mostrar los círculos detectados sobre la imagen.

Por ejemplo:

% 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');

Aquí está el método creo que es necesario:

[x_p, y_p] = find (points); 

% convert the subscripts to indicies, but transposed into a row vector
a = sub2ind(size(im), x_p, y_p)';

% assign all the values in the image that correspond to the points to a value of zero
im([a]) = 0; 

% show the new image
imshow(im) 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top