使用 MATLAB 分离图像中两个重叠的圆

2023-12-11

如何使用 MATLAB 将下图中两个相连的圆分开?我尝试过使用imerode,但这并没有给出好的结果。腐蚀不起作用,因为为了腐蚀得足以将圆圈分开,线条会消失或被破坏。在其他起始图片中,圆和线重叠,因此隔离重叠的对象也不起作用。

该图像显示了通过以下方式识别的对象bwboundaries,每个物体涂上不同的颜色。正如您所看到的,两个浅蓝色圆圈连接在一起,我想将它们分开,产生两个单独的圆圈。谢谢


我建议您使用圆形霍夫变换imfindcircles。但是,您需要图像处理工具箱的版本 8,该版本从 R2012a 及更高版本开始提供。如果您没有这个,那么不幸的是,这将不起作用:(...但让我们假设您确实有它。但是,如果您使用的是早于 R2012a 的东西,他/她的 Dev-iL上面的评论链接到 MATLAB 文件交换上的一些代码,这些代码很可能是在圆形霍夫变换可用之前创建的:http://www.mathworks.com/matlabcentral/fileexchange/9168-detect-circles-with-various-radii-in-grayscale-image-via-hough-transform/


这是霍夫变换的一个特例,您试图在图像中找到圆圈而不是直线。这样做的好处是,即使圆是部分完成或重叠的,您也能够找到圆。

我将拍摄您上面提供的图像并对其进行一些后期处理。我将把图像转换为二进制,并删除边框,边框是白色的,包含标题。我还将填充由此产生的任何洞,以便所有对象都填充为纯白色。执行此步骤后,还会产生一些残余量化噪声,因此我将使用一个 3 x 3 方形元素的小开口。之后,我将使用 3 x 3 方形元素来闭合形状,因为我发现形状中有明显的间隙。所以:

因此,直接从您发布的位置读取您的图像:

im = imread('http://s29.postimg.org/spkab8oef/image.jpg'); %// Read in the image
im_gray = im2double(rgb2gray(im)); %// Convert to grayscale, then [0,1]
out = imclearborder(im_gray > 0.6); %// Threshold using 0.6, then clear the border
out = imfill(out, 'holes'); %// Fill in the holes
out = imopen(out, strel('square', 3));
out = imclose(out, strel('square', 3));

这是我得到的图像:

enter image description here

现在,应用圆形霍夫变换。其一般语法是:

[centres, radii, metric] = imfindcircles(img, [start_radius, end_radius]);

img将是包含您的形状的二值图像,start_radius and end_radius将是您想要找到的圆的最小和最大半径。执行圆形霍夫变换,以便找到此范围(以像素为单位)内的任何圆形。输出是:

  1. centres:返回(x,y)检测到的每个圆的中心位置
  2. radii:每个圆的半径
  3. metric:圆的纯度的度量。值越高意味着形状更有可能是圆形,反之亦然。

我搜索了半径在 30 到 60 像素之间的圆。所以:

[centres, radii, metric] = imfindcircles(out, [30, 60]);

然后我们可以通过组合来展示检测到的圆以及半径plot and viscircles。所以:

imshow(out);
hold on;
plot(centres(:,1), centres(:,2), 'r*'); %// Plot centres
viscircles(centres, radii, 'EdgeColor', 'b'); %// Plot circles - Make edge blue

结果如下:

enter image description here

正如您所看到的,即使重叠的圆圈朝向顶部,圆形霍夫变换也能够检测到该形状中的两个不同的圆圈。


编辑 - 2014 年 11 月 16 日

您希望确保在执行此操作之前将对象分开bwboundaries。这做起来有点棘手。我能看到你这样做的唯一方法就是你甚至不使用bwboundaries完全并且自己做这件事。我假设您在完成所有这些操作后想要单独分析每个形状的属性,所以我建议您迭代您拥有的每个圆圈,然后将每个圆圈放在一个新的空白图像上,执行regionprops调用该形状,然后将其附加到一个单独的数组中。您还可以通过一个单独的数组来跟踪所有圆,该数组一次将一个圆添加到该数组中。

完成所有圆后,您将获得一个结构数组,其中包含您找到的所有测量圆的所有测量属性。您将使用仅包含上方圆圈的数组,然后使用它们并将它们从原始图像中删除,这样您就只得到线条。然后你再打一个电话regionprops在此图像上获取线条信息并将其附加到最终的结构数组中。

这是我上面概述的过程的第一部分:

num_circles = numel(radii); %// Get number of circles
struct_reg = []; %// Save the shape analysis per circle / line here

%// For creating our circle in the temporary image
[X,Y] = meshgrid(1:size(out,2), 1:size(out,1));

%// Storing all of our circles in this image
circles_img = false(size(out));

for idx = 1 : num_circles %// For each circle we have...        
    %// Place our circle inside a temporary image    
    r = radii(idx);
    cx = centres(idx,1); cy = centres(idx,2);
    tmp = (X - cx).^2 + (Y - cy).^2 <= r^2;        

    % // Save in master circle image
    circles_img(tmp) = true;

    %// Do regionprops on this image and save    
    struct_reg = [struct_reg; regionprops(tmp)]; 
end

上面的代码可能有点难以理解,但是让我们慢慢看一下。我首先计算出我们有多少个圆,这只是看看我们检测到了多少个半径。我保留一个单独的数组,称为struct_reg这将附加一个regionprops struct对于图像中的每个圆圈和线条。我用meshgrid以确定(X,Y)相对于包含我们的形状的图像进行坐标,以便我可以在每次迭代时在空白图像上绘制一个圆圈。为此,您只需找到相对于每个圆中心的欧几里得距离,并将像素设置为true仅当该位置的距离小于r。执行此操作后,您将只创建一个圆圈并将其全部过滤掉。然后你会使用regionprops在此圈子上,将其添加到我们的circles_img数组,其中仅包含圆圈,然后继续处理其余的圆圈。

至此,我们就已经保存了所有的圈子。这是什么circles_img到目前为止看起来像:

enter image description here

您会注意到绘制的圆圈很干净,但原始图像中的实际圆圈有点锯齿状。如果我们尝试用这个干净的图像删除圆圈,您将在边界上得到一些残留像素,并且您不会完全删除圆圈本身。为了说明我的意思,如果我尝试使用以下命令删除圆圈,这就是您的图像的样子circles_img通过它自己:

enter image description here

……不太好吧?

如果你想完全去除圆圈,那么通过进行形态学重建imreconstruct您可以在其中使用此图像作为种子图像,并指定原始图像是我们正在处理的图像。形态重建的工作本质上是洪水填充。您指定种子像素、要处理的图像以及工作imreconstruct从这些种子开始,用白色进行洪水填充,直到我们到达种子像素所在的对象的边界。因此:

out_circles = imreconstruct(circles_img, out);

因此,我们得到了最终重建的圆形图像:

enter image description here

伟大的!现在,使用它并从原始图像中删除圆圈。一旦你这样做了,运行regionprops再次在这最终图像上并附加到您的struct_reg多变的。显然,在执行此操作之前保存原始图像的副本:

out_copy = out;
out_copy(out_circles) = false;
struct_reg = [struct_reg; regionprops(out_copy)];

只是为了便于讨论,这就是删除圆圈后图像的样子:

enter image description here

现在,我们已经分析了所有的形状。请记住我已经完成了完整的regionprops打电话是因为我不知道你在分析中到底想要什么......所以我决定给你一切。


希望这可以帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 MATLAB 分离图像中两个重叠的圆 的相关文章

  • 在 MATLAB 中重命名文件

    我正在尝试以编程方式重命名工作目录中的文件a temp txt to b hello txt 您建议如何这样做 MATLAB中有一个简单的文件重命名函数吗 我认为您正在寻找 MOVEFILE
  • Matlab 字段名索引[重复]

    这个问题在这里已经有答案了 所以我有一个包含多个表的元胞数组 我试图访问表的第一个列名称 c table1 table2 table3 以下两行都给了我错误 fieldnames c 1 1 fieldnames c 1 1 Error i
  • MATLAB 特征函数

    我很好奇哪里可以找到完整的描述FEATURE功能 它接受哪些论点 没有找到文档 我只听说过memstats and getpid 还要别的吗 gt gt which feature built in undocumented 注意 更完整的
  • 如何检查图像的特定像素是否透明?

    有什么方法可以检查 PNG 图像的选定 x y 点是否透明 根据 Jeff 的回答 您的第一步是创建 PNG 的画布表示 下面创建一个与图像宽度和高度相同的离屏画布 并在其上绘制图像 var img document getElementB
  • 如何在 C# 中将位图图像转换为黑白图像? [复制]

    这个问题在这里已经有答案了 可能的重复 在 c 中将图像转换为黑白或棕褐色 https stackoverflow com questions 4624998 convert image to black white or sepia in
  • 如何在 Matlab 中将数组打印到 .txt 文件?

    我才刚刚开始学习Matlab 所以这个问题可能非常基本 我有一个变量 a 2 3 3 422 6 121 9 4 55 我希望将值输出到 txt 文件 如下所示 2 3 3 422 6 121 9 4 55 我怎样才能做到这一点 fid f
  • Matlab:如何更改矩阵的存储方式?从 1x1x3 到 1x3?

    我目前有 val 1 0 7216 val 2 0 7216 val 3 0 7216 但我想要 0 7216 0 716 0 721 我可以做什么样的操作来做到这一点 The reshape函数将在这里解决问题 Arrange the e
  • OpenCV:如何使用图像计算相机和物体之间的距离?

    我是 OpenCV 的新手 我正在使用以下公式来计算距离 distance to object mm focal length mm real height of the object mm image height pixels obje
  • GrabCut - bgdModel 和 fgdModel 为空 - 断言错误

    我正在尝试使用 OpenCV2 1 C 中的 GrabCut 算法进行图像分割 这是我的代码 Mat rgbWorkImage imread argv 1 Mat mask mask Scalar 0 Mat bgdModel fgdMod
  • 自动跟踪算法

    我正在尝试写一个simple跟踪例程来跟踪电影中的某些点 本质上我有一系列 100 帧长的电影 在黑暗背景上显示一些亮点 我每帧有大约 100 150 个点 它们在电影的过程中移动 我想跟踪它们 所以我正在寻找一些有效的 但可能不会过度实施
  • 减少非常大图像的文件大小,而不改变图像尺寸

    考虑一个处理可能非常大的 PNG 文件上传的应用程序 所有上传的文件必须存储到磁盘以供以后检索 但是 PNG 文件的大小最大可达 30 MB 但磁盘存储限制规定每个文件的最大大小为 1 MB 问题是获取文件大小高达 30 MB 的输入 PN
  • 如何使用 MATLAB 的 substruct 函数创建表示使用“end”的引用的结构?

    我想使用substruct http www mathworks com help matlab ref substruct html函数创建一个结构体以供使用subsref 目的是使用索引字符串subsref而不是通常的 符号 因为我正在
  • 找到图像特征宽度的正确方法和Python包

    输入是一个在黑色背景上带有彩色 抱歉 垂直线的光谱 给定该带的近似 x 坐标 用 X 标记 我想找到该带的宽度 我对图像处理不熟悉 请引导我前往正确的方法图像处理和Python图像处理package也能起到同样的作用 我认为 PIL Ope
  • 有效地绘制大时间序列(matplotlib)

    我正在尝试使用 matplotlib 在同一轴上绘制三个时间序列 每个时间序列有 10 6 个数据点 虽然生成图形没有问题 但 PDF 输出很大 在查看器中打开速度非常慢 除了以栅格化格式工作或仅绘制时间序列的子集之外 还有其他方法可以获得
  • 在matlab中绘制给定区域内(两个圆之间)的向量场

    我想在 Matlab 中绘制下面的向量场 u cos x x 0 y y 0 v sin x x 0 y y 0 我可以在网格中轻松完成 例如 x 和 y 方向从 2 到 2 x 0 2 y 0 1 x y meshgrid 2 0 2 2
  • Python 中的 Lanczos 插值与 2D 图像

    我尝试重新缩放 2D 图像 灰度 图像大小为 256x256 所需输出为 224x224 像素值范围从 0 到 1300 我尝试了两种使用 Lanczos 插值来重新调整它们的方法 首先使用PIL图像 import numpy as np
  • ROC曲线和libsvm

    给定一条 ROC 曲线plotroc m see here http www csie ntu edu tw cjlin libsvmtools roc curve for binary svm 理论问题 如何选择要使用的最佳阈值 编程问题
  • 给定协方差矩阵,在Matlab中生成高斯随机变量

    Given a M x M期望的协方差 R 以及所需数量的样本向量 N计算一个N x M高斯随机向量 X在普通 MATLAB 中 即不能使用r mvnrnd MU SIGMA cases 不太确定如何解决这个问题 通常你需要一个协方差并且意
  • @(t)在Matlab中是什么意思? [复制]

    这个问题在这里已经有答案了 正如标题所示 考虑到下面的上下文 t 在 Matlab 中到底意味着什么 computeNumericalGradient 是一个函数 cofiCostFunc 也是一个接受一堆参数的函数 问题是 t 对 cof
  • 使用强光混合模式时突出显示伪影

    我正在 iPhone 应用程序中使用顶部图像的 HardLight 混合模式混合两个图像 它看起来像这样 UIGraphicsBeginImageContext size sourceImage drawInRect rectangle b

随机推荐

  • 在 javascript 服务器端连接 MySQL,无需使用 Node.js

    我有一个与服务器一起运行的 JavaScript 应用程序 例如nginx or eclipse local server 我想知道是否可以将其与mysql服务器数据库连接 我知道他们有很多npm packages for nodejs应用
  • jQuery:取消绑定事件处理程序以稍后再次绑定它们

    有谁知道如何取消绑定事件处理程序集 但记住它们以便稍后再次绑定它们 有什么建议么 项目的数据中有一个事件元素 这应该可以开始 您可以在解除绑定之前读取元素并将处理程序存储在数组中 如果您需要更多帮助 请发表评论 我通过阅读 fn clone
  • NLTK导入错误

    我是 Python 和 NLTK 的新手 我一直在尝试寻找解决问题的方法 但尚未找到解决方案 希望有人可以帮助我 我目前运行的是 64 位 Windows 8 我已按照 NLTK 网站上的说明进行操作 http www nltk org i
  • 如何在 FileOpen 对话框中禁用 Shell 扩展

    我说的是 Windows shell 扩展 我有一个 shell 扩展 它可以显示我的自定义文件类型的特定属性 例如 filetype 当然 这会导致我的 shell 扩展 dll 被加载到 explorer exe 进程中 但现在如果我在
  • 是否应该谨慎使用 FirebaseDatabase.getInstance()?

    例如 当我在 android 中使用 SQLiteDatabase 时 打开 关闭大量 SQLiteDatabase 助手通常不是一个好主意 相反 最好创建一种单例 以确保只打开 1 个数据库 假设我有一个带有静态方法的类 它执行大量需要
  • 如何在Android中使用自定义日历视图以及如何设置提醒提醒?

    我需要制作一个 Android 应用程序来显示日历控件 我曾试图在Android提供的默认小部件中找到这样的控件 但没有找到 如何在Android应用程序中集成日历控件 我还希望日历能够添加特定日期的事件和提醒 在计时器中同时播放 2 个声
  • 如何使用numpy将RGB图像转换为基于颜色的one-hot编码3d数组?

    简而言之 我想做的与这个问题类似 将 RGB 图像转换为索引图像 但我想要获取 n 通道图像 而不是 1 通道索引图像 其中img h w 是一个one hot编码向量 例如 如果输入图像是 0 0 0 255 255 255 索引 0 分
  • MediaCodec 编码视频底部有绿条且色度搞砸

    我开始了一个项目Grafika并对其进行了修改 我有一个框架 与原始框架没有太大不同 它可以捕获来自Camera并同时以不同的分辨率将其连续编码为视频 MediaCodec 用于编码 配置为使用COLOR FormatSurface为了让我
  • 当使用“all one word”时,有什么方法可以使 html 文本换行吗? [复制]

    这个问题在这里已经有答案了 可能的重复 有没有办法在 div 中自动换行 我有这个 css 和 html 问题 我有一个描述 我想将其放入一个 100 像素宽的框中 并且我希望文本沿着页面向下流动 我设置了一个这样的div div styl
  • SVG 在 Firefox 中完全不可见

    在将其标记为重复之前 我们已经确保宽度和高度设置正确 我将其描述为不可见 因为尽管它占用了正确的空间 甚至以正确的尺寸加载到图像上 但图像的内容在网站 网络选项卡以及直接查看 SVG 时都是空的 基本上 无论我们如何显示或查看它 实际的 S
  • OpenGL-ES 2.0 中未声明 glMapBuffer

    我正在 ubuntu 10 10 中通过使用 kronos 和 pvrsd kNow 代码进行 Opengl es 2 0 include
  • 懒惰、贪婪和所有格量词之间有什么区别?

    以下量词在场景 速度等方面有何不同 and 全部匹配0或1次 and 全部匹配0次或多次 and 全部匹配1次或多次 and are greedy and are 不情愿 懒惰 and are 所有格 谁能帮助我理解这些术语的含义 为什么同
  • 使用 Web 客户端 DownloadFileAsync 多个文件

    描述使用 webclient 的 DownloadFileAsync 下载多个文件 并利用文本文件作为 URL 输入进行下载 Problem我使用的方法根本不会下载文件 只是运行 什么也不做 它填充列表数组 然后退出程序而不下载单个文件 我
  • 节点removeListener不起作用

    尝试使用以下代码删除侦听器 var EventEmitter require events EventEmitter var emitter new EventEmitter emitter on message function text
  • iOS PencilKit 无法绘图

    我正在尝试使用 PencilKit 但无法在应用程序中绘制任何内容 我设置我的代码如下 import UIKit import PencilKit class DrawingViewController UIViewController v
  • 使用 Terraform 的 helm_release,如何设置数组或列表值?

    例如 根据Drupal 的 helm 图表文档 默认值accessModes is ReadWriteOnce 其在 YAML 中转换为以下内容 accessModes ReadWriteOnce 使用 Terraform 时舵释放资源 以
  • .NET Web浏览器控制和Dispose()

    我知道这是一个热门话题 有很多问题和答案 但我仍然没有找到以下问题的解决方案 我有一个多选项卡应用程序 每个选项卡上都有一个 Webbrowser 控件 由于网络浏览器为每个新选项卡占用更多内存 并且它们不会在选项卡关闭时释放此内存 因此我
  • fullcalendar - 如何使用 ajax 加载日历上的所有事件

    我想在页面加载时使用 Ajax 加载完整日历中的所有事件 我收到来自 Ajax 的响应 但该事件未添加到完整日历中 这是我的 jquery 代码 calendar fullCalendar theme true header left pr
  • 如何在 MATLAB 中填充两条直线和一条不直的曲线之间的区域(该区域不是多边形)

    使用 matlab 的 FILL 函数创建一个由直边多边形限定的填充区域 不幸的是 这在上图中留下了一个小的白色区域 因为我想要填充的区域的边界不是直边多边形 而是在左侧有一个弯曲的边界 我有一条曲线 几乎是抛物线 但不完全是 我想填充两条
  • 使用 MATLAB 分离图像中两个重叠的圆

    如何使用 MATLAB 将下图中两个相连的圆分开 我尝试过使用imerode 但这并没有给出好的结果 腐蚀不起作用 因为为了腐蚀得足以将圆圈分开 线条会消失或被破坏 在其他起始图片中 圆和线重叠 因此隔离重叠的对象也不起作用 该图像显示了通