Как я могу нарисовать круг на изображении в MATLAB?

У меня есть изображение в MATLAB:

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

И я сделал некоторую обработку, которая привела к ряду моментов, которые я хочу выделить:

points = some_processing(im);

Где points — матрица того же размера, что и im, с единицами в интересных точках.

Теперь я хочу нарисовать круг на изображении во всех местах, где points равно 1.

Есть ли в MATLAB функция, которая это делает? Лучшее, что я могу придумать, это:

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

Это кажется более чем несколько неэлегантным. Есть ли способ рисовать круги, похожие на функцию line?


person Nathan Fellman    schedule 07.12.2009    source источник


Ответы (7)


Вы можете использовать обычную команду PLOT с круговой маркер:

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

Вы также можете настроить эти другие свойства маркера графика: MarkerEdgeColor, MarkerFaceColor, MarkerSize.

Если вы затем хотите сохранить новое изображение с нанесенными на него маркерами, вы можете посмотреть этот ответ я дал на вопрос о сохранении размеров изображения при сохранении изображений из рисунков.

ПРИМЕЧАНИЕ. При построении данных изображения с помощью IMSHOW (или IMAGE и т. д. .), обычная интерпретация строк и столбцов по существу переворачивается. Обычно первое измерение данных (т. е. строки) считается данными, лежащими на оси X, и, вероятно, поэтому вы используете x_p в качестве первого набора значений, возвращаемых НАЙТИ. Однако IMSHOW отображает первое измерение данных изображения по оси Y, поэтому первое значение, возвращаемое функцией FIND, оказывается в данном случае значением координаты Y.

person gnovice    schedule 07.12.2009
comment
Вы также можете добавить hold off в код для полноты картины. - person Zaid; 07.12.2009
comment
@gnovice: Вы уверены в переключении x_p и y_p в вызове plot? - person Zaid; 07.12.2009
comment
@Zaid: Да, я добавил примечание к своему ответу, объясняющее, почему их нужно перевернуть. - person gnovice; 07.12.2009
comment
При масштабировании изображения точка не будет масштабироваться вместе с ним — имейте это в виду. - person Hanmyo; 13.02.2011

Этот файл от Zhenhai Wang из файлового обмена Matlab Central. делает свое дело.

%----------------------------------------------------------------
% 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
%----------------------------------------------------------------
person Nathan Fellman    schedule 29.08.2010

Забавный! Здесь есть 6 ответов, ни один из которых не дает очевидного решения: функция rectangle.

Из документации:

Нарисуйте круг, установив для свойства Curvature значение [1 1]. Нарисуйте круг так, чтобы он заполнил прямоугольную область между точками (2,4) и (4,6). Свойство Position определяет наименьший прямоугольник, содержащий круг.

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

Итак, в вашем случае:

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

В отличие от принятого ответа, эти круги будут масштабироваться вместе с изображением, вы можете увеличивать масштаб, и они всегда будут отмечать весь пиксель.

person Cris Luengo    schedule 26.12.2017

Хм, мне пришлось переключить их в этом звонке:

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!

В ответ на комментарии:

x и y создаются с использованием следующего кода:

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;

может быть, что ConvexHull наоборот, и поэтому сюжет другой. Или что я ошибся и так и должно быть

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

Однако в документации не ясно, какой столбец = x OR y: Цитата: «Каждая строка матрицы содержит x- и y-координаты одной вершины многоугольника».

Я прочитал это как x - первый столбец, а y - второй столбец.

person Ramon Fincken    schedule 08.12.2009
comment
Как вы получаете значения x и y? Если вы получите их с помощью команды НАЙТИ, вам, вероятно, придется их перевернуть. Возможно, вам не придется переворачивать их, если вы нашли их другими способами. - person gnovice; 08.12.2009

В более новых версиях MATLAB (у меня 2013b) панель инструментов системы компьютерного зрения содержит vision.ShapeInserter Системный объект, который можно использовать для рисования фигур на изображениях. Вот пример рисования желтых кругов из документации:

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);
person buzjwa    schedule 17.05.2015

С MATLAB и Image Processing Toolbox R2012a или новее вы можете использовать viscircles Функция легкого наложения кругов на изображение. Вот пример:

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

Кроме того, ознакомьтесь с функцией imfindcircles, реализующей круговое преобразование Хафа. В онлайн-документации для обеих функций (ссылки выше) есть примеры, показывающие, как находить круги на изображении и как отображать обнаруженные круги поверх изображения.

Например:

% 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');
person Bruno Pop-Stefanov    schedule 19.05.2015

Вот метод, который, я думаю, вам нужен:

[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) 
person Fred    schedule 02.02.2010
comment
Вопрос заключается в том, как рисовать круги вокруг точек, а не изменять значение изображения в них. - person gnovice; 02.02.2010