【问题标题】:How can I draw a circle on an image in MATLAB?如何在 MATLAB 中的图像上画一个圆圈?
【发布时间】:2010-12-24 01:31:24
【问题描述】:

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

【问题讨论】:

    标签: image matlab plot geometry


    【解决方案1】:

    您可以将普通的PLOT 命令与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!
    

    您还可以调整绘图标记的这些其他属性:MarkerEdgeColorMarkerFaceColorMarkerSize

    如果您想保存带有标记的新图像,您可以查看this answer I gave,了解有关在从图形中保存图像时保持图像尺寸的问题。

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

    【讨论】:

    • 为了完整起见,您可能还想将hold off 添加到代码中。
    • @gnovice:您确定要在plot 通话中切换x_py_p
    • @Zaid:是的,我在回答中添加了一条注释,解释了为什么需要翻转它们。
    • 当您缩放图像时,点不会随之缩放 - 请记住这一点。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      好笑!这里有 6 个答案,没有一个给出明显的解决方案:rectangle 函数。

      来自documentation

      通过将曲率属性设置为 [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
      

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

      【讨论】:

        【解决方案4】:

        嗯,我不得不在这次通话中重新切换它们:

        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!
        

        回复cmets:

        x 和 y 使用以下代码创建:

        temp_hull = stats_single_object(k).ConvexHull;
        对于 k2 = 1:长度(temp_hull)
           我=我+1;
             [x(i,1)] = temp_hull(k2,1);
             [y(i,1)] = temp_hull(k2,2);
         结束;

        可能是 ConvexHull 是相反的,因此情节不同。或者我犯了一个错误,应该是

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

        但是文档并不清楚哪个列 = x OR y: 引用:“矩阵的每一行都包含多边形一个顶点的 x 和 y 坐标。”

        我认为 x 是第一列,y 是第二列。

        【讨论】:

        • 您如何获得xy 的值?如果你从 FIND 命令得到它们,你可能不得不翻转它们。如果您通过其他方式找到它们,您可能不必翻转它们。
        【解决方案5】:

        在较新版本的 MATLAB(我有 2013b)中,计算机视觉系统工具箱包含 vision.ShapeInserter System object,可用于在图像上绘制形状。以下是从文档中绘制黄色圆圈的示例:

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

        【讨论】:

          【解决方案6】:

          借助 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');
          

          【讨论】:

            【解决方案7】:

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

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

            【讨论】:

            • 问题是如何在点周围画圆,而不是改变它们的图像值。
            猜你喜欢
            • 1970-01-01
            • 2012-12-06
            • 2013-05-05
            • 2016-08-03
            • 1970-01-01
            • 2012-11-12
            • 1970-01-01
            • 2011-06-06
            • 1970-01-01
            相关资源
            最近更新 更多