views:

4055

answers:

4

I have an image in MATLAB:

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

And I've done some processing that resulted in a number of points that I want to highlight:

points = some_processing(im);

Where points is a matrix the same size as im with ones in the interesting points.

Now I want to draw a circle on the image in all the places where points is 1.

Is there any function in MATLAB that does this? The best I can come up with is:

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

This seems more than somewhat inelegant. Is there a way to draw circles similar to the line function?

+5  A: 

You could use the normal PLOT command with a circular marker point:

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

You can also adjust these other properties of the plot marker: MarkerEdgeColor, MarkerFaceColor, MarkerSize.

If you then want to save the new image with the markers plotted on it, you can look at this answer I gave to a question about maintaining image dimensions when saving images from figures.

NOTE: When plotting image data with IMSHOW (or IMAGE, etc.), the normal interpretation of rows and columns essentially becomes flipped. Normally the first dimension of data (i.e. rows) is thought of as the data that would lie on the x-axis, and is probably why you use x_p as the first set of values returned by the FIND function. However, IMSHOW displays the first dimension of the image data along the y-axis, so the first value returned by FIND ends up being the y-coordinate value in this case.

gnovice
You might want to add `hold off` to the code as well for sake of completeness.
Zaid
@gnovice: Are you sure about switching the `x_p` and `y_p` in the `plot` call?
Zaid
@Zaid: Yes, I added a note to my answer explaining why they need to be flipped.
gnovice
A: 

Hmm I had to re-switch them in this call:

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!

In reply to the comments:

x and y are created using the following code:

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;

it might be that the ConvexHull is the other way around and therefore the plot is different. Or that I made a mistake and it should be

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

However the documentation is not clear about which colum = x OR y: Quote: "Each row of the matrix contains the x- and y-coordinates of one vertex of the polygon. "

I read this as x is the first column and y is the second colum.

Ramon Fincken
How are you getting the values `x` and `y`? If you get them from the FIND command, you will likely have to flip them. You might not have to flip them if you found them by other means.
gnovice
A: 

Here's the method I think you need:

[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) 
Fred
The question is asking how to *draw circles* around the points, not change the value of the image at them.
gnovice
A: 

This file by Zhenhai Wang from Matlab Central's File Exchange does the 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
%----------------------------------------------------------------
Nathan Fellman