如何在 MATLAB 中在图像上画圆?

发布于 2024-08-14 00:05:27 字数 790 浏览 1 评论 0原文

我在 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功能画圆的方法?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

不打扰别人 2024-08-21 00:05:27

您可以使用普通的 PLOT 命令和 < a href="http://www.mathworks.com/access/helpdesk/help/techdoc/ref/lineseriesproperties.html#Marker" rel="nofollow noreferrer">圆形标记点:

[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< /code>, MarkerFaceColor标记大小

如果您想保存带有标记的新图像,您可以查看 我给出的这个答案是关于在保存图形图像时维护图像尺寸的问题。

注意:使用 绘制图像数据时IMSHOW (或 IMAGE 等.),行和列的正常解释本质上被翻转了。通常,数据的第一个维度(即行)被认为是位于 x 轴上的数据,这可能就是您使用 x_p 作为 FIND 函数。但是,IMSHOW 沿 y 轴 显示图像数据的第一个维度,因此在这种情况下,FIND 返回的第一个值最终是 y 坐标值

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.

清眉祭 2024-08-21 00:05:27

此文件,作者: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
%----------------------------------------------------------------

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
%----------------------------------------------------------------

有趣的!这里有 6 个答案,但没有一个给出明显的解决方案:矩形函数。

来自文档

通过将 Curvature 属性设置为 [1 1] 来绘制圆。绘制圆,使其填充点 (2,4) 和 (4,6) 之间的矩形区域。 Position 属性定义包含圆的最小矩形。

pos = [2 4 2 2];
矩形('位置',pos,'曲率',[1 1])
轴相等

因此,在您的情况下:

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

与接受的答案相反,这些圆圈将随图像缩放,您可以放大,它们将始终标记整个像素。

Funny! There are 6 answers here, none give the obvious solution: the rectangle function.

From the documentation:

Draw a circle by setting the Curvature property to [1 1]. Draw the circle so that it fills the rectangular area between the points (2,4) and (4,6). The Position property defines the smallest rectangle that contains the circle.

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

So in your case:

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

As opposed to the accepted answer, these circles will scale with the image, you can zoom in an they will always mark the whole pixel.

权谋诡计 2024-08-21 00:05:27

嗯,我必须在这次调用中重新切换它们:

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 是第二列。

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.

一江春梦 2024-08-21 00:05:27

在较新版本的 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);

In newer versions of MATLAB (I have 2013b) the Computer Vision System Toolbox contains the vision.ShapeInserter System object which can be used to draw shapes on images. Here is an example of drawing yellow circles from the documentation:

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);
迷离° 2024-08-21 00:05:27

通过 MATLAB and Image Processing Toolbox R2012a 或更高版本,您可以使用 viscircles< /code>函数可以轻松地将圆圈覆盖在图像上。这是一个示例:

% 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< /a> 实现霍夫循环变换的函数。这两个函数的在线文档(上面的链接)提供了示例,展示了如何在图像中查找圆圈以及如何在图像上显示检测到的圆圈。

例如:

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

With MATLAB and Image Processing Toolbox R2012a or newer, you can use the viscircles function to easily overlay circles over an image. Here is an example:

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

Also, check out the imfindcircles function which implements the Hough circular transform. The online documentation for both functions (links above) have examples that show how to find circles in an image and how to display the detected circles over the image.

For example:

% 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');
孤芳又自赏 2024-08-21 00:05:27

这是我认为你需要的方法:

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

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) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文