如何在Matlab中找到二值图像中的所有连通分量?

2023-11-29

我一直在尝试使用二值图像中的 8 个邻居来查找所有连接的组件,而不使用函数“bwlabel”。

例如,我的输入矩阵是:

a =

     1     1     0     0     0     0     0
     1     1     0     0     1     1     0
     1     1     0     0     0     1     0
     1     1     0     0     0     0     0
     0     0     0     0     0     1     0
     0     0     0     0     0     0     0

我想要这样的东西:

a =

     1     1     0     0     0     0     0
     1     1     0     0     2     2     0
     1     1     0     0     0     2     0
     1     1     0     0     0     0     0
     0     0     0     0     0     3     0
     0     0     0     0     0     0     0

此图像中有 3 个相连的对象。


这是图像处理中的常见问题。有很多变化,例如洪水填充图像中的某个区域,或者查找哪些像素属于同一区域。一种常见的方法是使用深度优先搜索。这个想法是,从左到右、从上到下遍历图像,对于遇到的任何等于 1 的像素,将它们添加到堆栈中。对于堆栈中的每个像素,您从堆栈中弹出,然后查看该像素周围的相邻像素。添加到堆栈中的任何为 1 的像素。您需要保留一个附加变量,其中任何像素您已经访问过,您不将它们添加到堆栈中。当堆栈为空时,我们发现那些像素是整个区域,因此您可以使用唯一的 ID 来标记它们。然后重复此过程,直到用完图像中的区域。

因此,假设您的矩阵存储在A,这是基本算法:

  1. 初始化一个大小相同的数组A那是logical。这将记录我们检查或访问过哪些像素。还初始化输出数组B全部为零,为您提供您正在寻找的所有连接组件。任何最终为零的位置都不属于任何连接的组件。还要初始化一个 ID 计数器,用于跟踪每个连接组件的标签。

  2. 对于矩阵中的每个位置:

    A。如果位置是0,将此位置标记为已访问并继续。

    b.如果我们已经访问过该位置,则继续。

    C。如果我们还没有访问过该位置...请转到步骤#3。

  3. 将此未访问的位置添加到堆栈中。

    A。虽然这个堆栈不为空...

    b.从堆栈中弹出此位置

    C。如果我们访问过该位置,则继续。

    d.否则,将此位置标记为已访问,并使用连接的组件 ID 标记此位置。

    e.给定这个位置,查看 8 个相邻像素。

    F。删除此列表中那些已访问过、不等于 1 或超出矩阵范围的像素

    G。无论剩余位置如何,都将它们添加到堆栈中。

  4. 一旦堆栈为空,就增加计数器,然后返回到步骤 #2。

  5. 继续下去,直到我们访问完数组中的所有位置。

话不多说,这是代码。


%// Step #1
visited = false(size(A));
[rows,cols] = size(A);
B = zeros(rows,cols);
ID_counter = 1;

%// Step 2
%// For each location in your matrix...
for row = 1 : rows
    for col = 1 : cols
        %// Step 2a
        %// If this location is not 1, mark as visited and continue
        if A(row,col) == 0
            visited(row,col) = true;

        %// Step 2b
        %// If we have visited, then continue
        elseif visited(row,col)
            continue;

        %// Step 2c
        %// Else...
        else
            %// Step 3
            %// Initialize your stack with this location
            stack = [row col];

            %// Step 3a
            %// While your stack isn't empty...
            while ~isempty(stack)
                %// Step 3b
                %// Pop off the stack
                loc = stack(1,:);
                stack(1,:) = [];

                %// Step 3c
                %// If we have visited this location, continue
                if visited(loc(1),loc(2))
                    continue;
                end

                %// Step 3d
                %// Mark location as true and mark this location to be
                %// its unique ID
                visited(loc(1),loc(2)) = true;
                B(loc(1),loc(2)) = ID_counter;

                %// Step 3e
                %// Look at the 8 neighbouring locations
                [locs_y, locs_x] = meshgrid(loc(2)-1:loc(2)+1, loc(1)-1:loc(1)+1);
                locs_y = locs_y(:);
                locs_x = locs_x(:);

                 %%%% USE BELOW IF YOU WANT 4-CONNECTEDNESS
                 % See bottom of answer for explanation
                 %// Look at the 4 neighbouring locations
                 % locs_y = [loc(2)-1; loc(2)+1; loc(2); loc(2)];
                 % locs_x = [loc(1); loc(1); loc(1)-1; loc(1)+1];

                %// Get rid of those locations out of bounds
                out_of_bounds = locs_x < 1 | locs_x > rows | locs_y < 1 | locs_y > cols;

                locs_y(out_of_bounds) = [];
                locs_x(out_of_bounds) = [];

                %// Step 3f
                %// Get rid of those locations already visited
                is_visited = visited(sub2ind([rows cols], locs_x, locs_y));

                locs_y(is_visited) = [];
                locs_x(is_visited) = [];

                %// Get rid of those locations that are zero.
                is_1 = A(sub2ind([rows cols], locs_x, locs_y));
                locs_y(~is_1) = [];
                locs_x(~is_1) = [];

                %// Step 3g
                %// Add remaining locations to the stack
                stack = [stack; [locs_x locs_y]];
            end

            %// Step 4
            %// Increment counter once complete region has been examined
            ID_counter = ID_counter + 1;
        end
    end %// Step 5
 end   

通过你的示例矩阵,这就是我得到的B:

B =

     1     1     0     0     0     0     0
     1     1     0     0     2     2     0
     1     1     0     0     0     2     0
     1     1     0     0     0     0     0
     0     0     0     0     0     3     0
     0     0     0     0     0     0     0

在 4 个连通邻域中搜索

修改代码以在 4 个连通区域中搜索,即只有北、东、西和南,您看到的部分%// Look at the 8 neighbouring locations, 那是:

 %// Look at the 8 neighbouring locations
 [locs_y, locs_x] = meshgrid(loc(2)-1:loc(2)+1, loc(1)-1:loc(1)+1);
 locs_y = locs_y(:);
 locs_x = locs_x(:);

要以 4 连接方式进行搜索,您只需修改此代码以仅给出这些基本方向:

 %// Look at the 4 neighbouring locations
locs_y = [loc(2)-1; loc(2)+1; loc(2); loc(2)];
locs_x = [loc(1); loc(1); loc(1)-1; loc(1)+1];

其余代码保持不变。

为了匹配 MATLAB 的bwlabel功能

如果你想匹配 MATLAB 的输出bwlabel功能,bwlabel按列主序或 FORTRAN 顺序搜索连通分量。上面的代码按行专业或 C 顺序搜索。因此,您只需首先沿着列而不是行进行搜索,就像上面的代码所做的那样,您可以通过交换两者的顺序来完成此操作for循环。

具体来说,不要这样做:

for row = 1 : rows
    for col = 1 : cols
        ....
        ....

你会这样做:

for col = 1 : cols
    for row = 1 : rows
        ....
        ....

现在应该复制以下输出bwlabel.

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

如何在Matlab中找到二值图像中的所有连通分量? 的相关文章

  • 文章中的内联图像和标题 - 使标题的宽度与图像的宽度一致

    这是我的代码 div class image img src image jpg alt Image description p class caption This is the image caption p div 这是我的 CSS
  • 识别相似图像的库

    我想确定 2 张图像的相似程度 图像可能已被缩放 裁剪等 因此简单的像素比较将不起作用 我环顾四周 有很多关于这个主题的学术论文 但他们没有发布他们的代码 那么 您知道有一个可以比较图像的已发布库 适用于 Linux 和 Windows 吗
  • 直方图均衡结果

    I am trying to code histogram equalization by my self but the results are different from the built in function in matlab
  • 在Matlab中对字符进行分组并形成矩阵

    我有 26 个字符 A 到 Z 我将 4 个字符组合在一起 并用空格分隔以下 4 个字符 如下所示 abcd efgh ijkl mnop qrst uvwx yz 我的Matlab编码如下 str abcdefghijklmnopqrst
  • 如何将图像显示为缩略图

    我有一个QTreeView显示硬盘驱动器和目录 我也有一个QListView显示图像文件如下 但我想将图像显示为缩略图 如下所示 My code mainWidget mainWidget QWidget parent QWidget pa
  • 如何使网页中出现的图标闪烁/闪烁

    几天前我开始研究高级java 我知道太晚了 我被困在使图标 出现在任务栏上 闪烁的特定任务上 这种闪烁应该根据特定条件发生 这意味着可以使用以下方法来实现javascript 我已经搜索了一段时间了 但是有没有办法让图标每隔 1 秒左右出现
  • 如何去除给定图像中的噪声,使 ocr 输出完美?

    我已经对这个孟加拉文本图像进行了大津阈值处理 并使用 tesseract 进行 OCR 但输出非常糟糕 我应该应用什么预处理来消除噪音 我也想校正图像 因为它有轻微的倾斜 我的代码如下 import tesserocr from PIL i
  • numpy:大量线段/点的快速规则间隔平均值

    我沿着一维线有许多 约 100 万个 不规则间隔的点 P 这些标记线段 这样 如果点是 0 x a x b x c x d 则线段从 0 gt x a x a gt x b x b gt x c x c gt x d 等 我还有每个段的 y
  • 如何在JPanel中设置背景图片

    你好 我使用 JPanel 作为我的框架的容器 然后我真的想在我的面板中使用背景图片 我真的需要帮助 这是我到目前为止的代码 这是更新 请检查这里是我的代码 import java awt import javax swing import
  • 左对齐图像和居中文本在 div 内的同一级别?

    HTML br div class UpperTitle img src align left CableSolve Web Dashboard Version 0 1 1 div br CSS UpperTitle text align
  • OpenCV 错误:connectedComponents_sub1 中断言失败 (L.channels() == 1 && I.channels() == 1) [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我在 OpenCV python 中遇到以下错误 并用 google 搜索了很多 但无法解决 如果有人能为我提供一些线索
  • Matlab 图像数据的 hist 函数

    我是 Matlab 新手 我想制作自己的函数 与 imhist 显示图像数据的直方图 完成相同的工作 但我对此完全是新手 我不知道如何做开发这样的功能 我开始做一些东西 但它非常不完整 function output args myhist
  • 在Android内存中存储gif图像

    我对安卓还很陌生 我想将图像保存到内存中 然后从内存中检索图像并将其加载到图像视图中 我已使用以下代码成功将图像存储在内存中 void saveImage String fileName img cnt jpg File file new
  • 使用 ImageMagick/convert 创建半透明 PNG

    我有 PNG 文件 我想将整个图像转换为半透明 该图像将在 KML 文件中引用为 Google 地球 地图中使用的图标叠加层 使用 ImageMagick 向我建议了以下示例convert命令 但似乎都不起作用 第一个示例会导致错误 usr
  • Matlab:条形图中缺少标签

    使用 Matlab 2012 和 2013 我发现设置XTickLabel on a bar图表最多只能使用 15 个柱 如果条形较多 则标签会丢失 如下所示 绘制 15 个条形图 N 15 x 1 N labels num2str x d
  • Javascript - 检测 Youtube 默认缩略图

    有什么方法可以查看 Youtube 缩略图是否真的存在 或者 Youtube 只是用默认缩略图替换了它 例如 没有此缩略图的视频 http img youtube com vi G75WApUdYJ4 maxresdefault jpg h
  • 鼠标悬停时放大图像而不使用 Jquery 推送其他图像?

    当您将鼠标悬停在图像缩略图上 例如 Google 图片正在使用的缩略图 时 我正在尝试创建图像放大效果 但是 我遇到了一个问题 即放大的图像根据放大的图像的位置不断将另一张图像推到另一个位置 这是我到目前为止所拥有的
  • 使用 IE11 的工作程序使用 multipart/form-data 发送二进制数据

    我正在尝试发送multipart form data来自 IE 的工作人员 我已经使用 Chrome Firefox Safari 完成了此操作formData对象 不支持IE 我需要一个手动的 我发送的二进制数据是 crypto js 加
  • createImage(int width, int height) 的问题

    我有以下代码 作为游戏的一部分每 10 毫秒运行一次 private void gameRender if dbImage null createImage returns null if GraphicsEnvironment isHea
  • 获取向量幂的有效方法

    我编写了一个代码 在数值上使用勒让德多项式直至某个高 n 阶 例如 case 8 p 6435 x 8 12012 x 6 6930 x 4 1260 x 2 35 128 return case 9 如果向量x太长这会变得很慢 我发现说之

随机推荐

  • Nodejs:从视频缓冲区(不是文件路径)生成缩略图

    我有一个 Node API 它接受通过客户端 FormData 上传的视频文件 结果是req file object fieldname media originalname IMG 6288 MOV encoding 7bit mimet
  • Spring Security登录成功后重定向到上一页

    我知道这个问题之前已经被问过 但是我在这里面临一个特定的问题 我使用弹簧安全3 1 3 我的 Web 应用程序中有 3 种可能的登录情况 通过登录页面登录 好的 通过受限页面登录 也可以 通过非限制页面登录 不行 每个人都可以访问 产品 页
  • ASP.NET WEBAPI 文件上传,IE9 问题

    我使用 ASP NET WEBAPI 创建了一个文件上传方法 代码如下 DataContract public class FileDesc DataMember public string name get set DataMember
  • Fullcalendar 为每一天添加自定义按钮

    如何在 fullCalendar 中为每一天添加自定义按钮 为此 您最好的解决方案可能是日渲染回调允许您在日历上绘制每天的单元格之前添加额外的 HTML 例如这是一个超级简单的例子 dayRender function info info
  • JSF 验证。这可以简化吗?

    我有一个带有一堆字段的简单表单 它们每个都是必需的 并且每个都有不同的名称 city state 提交表单时 我检查每个字段是否为空并添加一个独特的信息对于上下文的每次验证 例如 城市为必填项 状态为必填项 我不能简单地在 jsp 上使用
  • 我们如何在GCP Composer环境(1.10.6)中使用SFTPToGCSOperator?

    这里我想在GCP的composer环境 1 10 6 中使用SFTPToGCSOperator 我知道存在限制 因为操作符仅出现在最新版本的气流中 而不出现在 Composer 最新版本 1 10 6 中 请参阅参考资料 https air
  • Notepad++ - 正则表达式:替换每行中第一次出现的字符组

    有人会知道可以使用正则表达式 在记事本 中 来替换每行中第一次出现的字符组 eg abcdefg ijkl m qsdflkj sdqlmkf jqsmdl to abcdefg ijkl m qsdflkj sdqlmkf jqsmdl
  • 调试发送程序指令时“事务模拟失败”(Solana Solidity)

    当尝试调用编译的程序时 solana solidity 我收到以下错误 Transaction simulation failed Error processing Instruction 0 Program failed to compl
  • 无法正确更新 DirectionalLight 阴影

    我有一个DirectionalLight在我的场景中 当我第一次创建灯光时 阴影覆盖了预期的区域 当调整视口大小 画布大小 时 我更新shadowCamera参数 右 左 上 下 以及灯光的位置和目标 但阴影仅覆盖更新前的区域 我必须设置什
  • 我如何获得特定类的 td nodeValue ?

    我有以下 html 表 table tr td img src name0 gif alt Name0 td td src name1 gif alt Name1 td td src name2 gif alt Name2 td td sr
  • 以编程方式创建属性 - 核心数据

    我有一个简单的 iphone 项目 其中包含一个简单的 xcdatamodel 它有一个实体 大约有3个属性 我想知道是否有一种方法可以以编程方式向实体添加属性 即 如果用户按下某种 添加 按钮 则会将一个简单的字符串属性添加到实体并保存
  • C# 操作/函数列表

    我有一个程序必须根据枚举执行一个函数 我想知道是否还有其他方法 enum FunctionType Addition 0 Substraction 1 Mutiplication 2 Division 3 void ExecuteFunct
  • Python 3.x 在矩阵中查找鞍点

    这是我的matrix 1 1 2 5 6 1 5 6 8 5 6 7 10 12 10 12 11 11 8 10 5 6 8 9 6 5 10 12 15 19 我想找到它鞍点 坐标 of 鞍点应该 2 0 2 2 0 4 所以我的问题是
  • 如何覆盖 NSTableHeaderView 的布局?

    我正在尝试为我的 NSTableView 生成自定义标头 我想更改标题文本的字体并删除边框和垂直分隔符 我当前的顶部和底部标题如下所示 有谁知道我该怎么做 更新 应用修复后 标题现在看起来像我想要的那样 实际上 mprudhom 和 Pro
  • 如何在重命名某些表/列的同时导入 mysql 转储而不导入其他表/列?

    我正在将遗留数据库导入到我们程序的新版本中 我想知道是否有一种方法可以不从转储中导入某些列 表 并在导入时重命名其他表 列 我知道理论上我可以编辑转储文件 但这似乎是一种黑客行为 到目前为止 我的编辑器都无法打开 1 3 GB 文件 是的
  • 保持方向变化时的项目选择

    我正在尝试恢复方向改变时动作模式的状态 但它不能正常工作 按照以下步骤顺序 在 3 和 4 中 选择已损坏 长按项目 项目突出显示 上下文操作栏显示标题显示 1 selected 看起来不错 将手机转为横向 没有变化 看起来不错 将手机转回
  • 有条件地跳过验证 JSF

    要求是有条件地跳过字段验证 当用户选择添加时 应验证表单字段并将值添加到表中 如果单击编辑 则应跳过表单字段验证 但应将 bean 值复制到输入字段
  • 是否可以检查集合或子集合是否存在?

    有没有办法检查nodejs的firestore中是否存在子集合 目前我正在使用doc exists对于文档 但我需要检查文档中是否存在子集合以便写入一些数据 马特乌斯的回答对我没有帮助 也许随着时间的推移它已经改变了 collection
  • requestAnimationFrame 未按预期工作

    我正在尝试在 React 中实现去抖动resize事件 使用requestAnimationFrame并编写了以下简单的CodePen https codepen io robloche pen RmLjZV 但 Chrome v75 Fi
  • 如何在Matlab中找到二值图像中的所有连通分量?

    我一直在尝试使用二值图像中的 8 个邻居来查找所有连接的组件 而不使用函数 bwlabel 例如 我的输入矩阵是 a 1 1 0 0 0 0 0 1 1 0 0 1 1 0 1 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0