精华内容
下载资源
问答
  • Matlab 连通分量处理, 二维和三维 (Matlab, Connected Component Process, 2D&3D) The code for your reference, which is used to remove the minor components: function Connect_Elimi = Connection_Judge_3D...

    Matlab 连通分量处理, 二维和三维 (Matlab, Connected Component Process, 2D&3D)

    The code for your reference, which is used to remove the minor components:

    function Connect_Elimi = Connection_Judge_3D(Binary_Img, reject_T)
        Connect_Elimi = Binary_Img;
        % find components
        CC = bwconncomp(Binary_Img);
        % component number
        C_number = CC.NumObjects;
        % pixel number
        numPixels = cellfun(@numel, CC.PixelIdxList);
        totalPixels_N = sum(numPixels);
        % remove minor components
        for k = 1:C_number
            cPixel_N = length( CC.PixelIdxList{k} );
            ratio = cPixel_N / totalPixels_N;
            if ratio  < reject_T
                Connect_Elimi(CC.PixelIdxList{k}) = 0;
            end
        end    



    展开全文
  • matlab 连通分量去除孤立点

    千次阅读 2019-06-25 17:09:27
    %显示最大连通区域, [~, max_id] = max(areas); max_rect = rects(max_id, :); % show the largest connected region % figure(2), % imshow(bw_img); % rectangle('position', max_rect, 'EdgeColor', 'r'); bw...
    src_img_name = 'haixing.png';
    img = imread(src_img_name);
    
    % get binary image
    gray_img = rgb2gray(img);
    T = graythresh(gray_img);
    bw_img = imbinarize(gray_img, T);
    
    % find the largest connected region
    img_reg = regionprops(bw_img,  'area', 'boundingbox');
    areas = [img_reg.Area];
    rects = cat(1,  img_reg.BoundingBox);
    
    figure(1),
    imshow(bw_img);
    for i = 1:size(rects, 1)
        rectangle('position', rects(i, :), 'EdgeColor', 'r');
    end
    
    %显示最大连通区域,
    [~, max_id] = max(areas);
    max_rect = rects(max_id, :);
    
    % show the largest connected region
    % figure(2), 
    % imshow(bw_img);
    % rectangle('position', max_rect, 'EdgeColor', 'r');
    
    bw_img2 = bwareaopen(bw_img,P);  %删除二值图像BW中面积小于P的对象,默认情况下conn使用8邻域
    figure;
    imshow(bw_img2);

    展开全文
  • Matlab中有bwlabel\bwboundaries两个连通分量标记函数 bwlabel(二维0-1) 作用:Label connected components in 2-D binary image 语法 L = bwlabel(BW) L = bwlabel(BW,conn) [L,n] = bwlabel(___) 说明 L...
    Matlab中有bwlabel\bwboundaries两个连通分量标记函数

    bwlabel(二维0-1)

    作用:Label connected components in 2-D binary image

    语法
    L = bwlabel(BW)
    L = bwlabel(BW,conn)
    [L,n] = bwlabel(___)

    说明

    L = bwlabel(BW)返回标签矩阵L,其中包含BW中找到的8个连接对象的标签。
    L = bwlabel(BW,conn)返回一个标签矩阵,其中conn指定连接,4或者8。
    [L,n] = bwlabel()也返回n,即BW中找到的连接对象的数量。

    对于bwlabel来说,其作用大致如下

    连通

    bwlabeln(多维)

    作用 Label connected components in binary image

    语法
    L = bwlabeln(BW)
    L = bwlabeln(BW,conn)
    [L,n] = bwlabeln(___)

    说明

    L = bwlabeln(BW) returns a label matrix, L, containing labels for the connected components in BW.

    L = bwlabeln(BW,conn) returns a label matrix, where conn specifies the connectivity.

    [L,n] = bwlabeln(___) also returns n, the number of connected objects found in BW.

    在这里插入图片描述

    bwboundaries

    意译为:跟踪二进制图像中的区域边界

    语法
    B = bwboundaries(BW)
    B = bwboundaries(BW,conn)
    B = bwboundaries(BW,conn,options)
    [B,L]= bwboundaries(___)
    [B,L,n,A] = bwboundaries(___)

    BW — Input binary image
    conn — Pixel connectivity ,8 (default) | 4
    options — Determine whether to search for both parent and child boundaries,‘holes’ (default) | ‘noholes’
    B — Row and column coordinates of boundary pixels(边界像素的行坐标和列坐标)
    L — Label matrix
    n — Number of objects found
    A — Parent-child dependencies between boundaries and holes(square, sparse, logical matrix.正方形,稀疏,逻辑矩阵)
    说明
    B = bwboundary (BW)在二值图像BW中,追踪物体的外部边界,以及物体内部的孔边界。bwboundary也向下延伸到最外层的对象(父对象)并跟踪其子对象(父对象完全包围的对象)。返回边界像素位置的单元格数组B。
    B = bwboundary (BW,conn)跟踪对象的外部边界,其中conn指定在跟踪父和子边界时使用的连接。
    B = bwboundary (BW,conn,options)跟踪对象的外部边界,其中的选项要么是“hole”,要么是“noholes”,指定是否希望包含其他对象内部的hole边界。
    [B,L]= bwboundaries()返回一个标签矩阵L,其中标记了对象和孔。
    [B,L,n,A] = bwboundaries()(_)返回找到的对象数量n和邻接矩阵A。

    例子

    //在图像上覆盖区域边界
    I = imread('rice.png');
    
    //Convert grayscale image to binary image using local adaptive thresholding.
    BW = imbinarize(I);
    
    //Calculate boundaries of regions in image and overlay the boundaries on the image.
    [B,L] = bwboundaries(BW,'noholes');
    
    imshow(label2rgb(L, @jet, [.5 .5 .5]))
    hold on
    for k = 1:length(B)
       boundary = B{k};
       plot(boundary(:,2), boundary(:,1), 'w', 'LineWidth', 2)
    end
    

    在这里插入图片描述

    //在图像上覆盖区域边界,并用区域号标注
    BW = imread('blobs.png');
    
    //Calculate boundaries of regions in the image.
    
    [B,L,N,A] = bwboundaries(BW);
    
    //Display the image with the boundaries overlaid. 
    //Add the region number next to every boundary (based on the label matrix). Use the zoom tool to read individual labels.
    
    imshow(BW); hold on;
    colors=['b' 'g' 'r' 'c' 'm' 'y'];
    for k=1:length(B),
      boundary = B{k};
      cidx = mod(k,length(colors))+1;
      plot(boundary(:,2), boundary(:,1),...
           colors(cidx),'LineWidth',2);
    
      %randomize text position for better visibility
      rndRow = ceil(length(boundary)/(mod(rand*k,7)+1));
      col = boundary(rndRow,2); row = boundary(rndRow,1);
      h = text(col+1, row-1, num2str(L(row,col)));
      set(h,'Color',colors(cidx),'FontSize',14,'FontWeight','bold');
    end
    

    在这里插入图片描述在这里插入图片描述

    //以红色显示对象边界,以绿色显示孔边界
    //Read binary image into workspace.
    
    BW = imread('blobs.png');
    //Calculate boundaries.
    
    [B,L,N] = bwboundaries(BW);
    //Display object boundaries in red and hole boundaries in green.
    
    imshow(BW); hold on;
    for k=1:length(B),
       boundary = B{k};
       if(k > N)
         plot(boundary(:,2), boundary(:,1), 'g','LineWidth',2);
       else
         plot(boundary(:,2), boundary(:,1), 'r','LineWidth',2);
       end
    

    在这里插入图片描述
    好用的网站:https://ww2.mathworks.cn/help/images/ref/bwboundaries.html?s_tid=doc_ta
    比买书有用多了,我买过一本matlab完全自学一本通,其实还不如这个网站来得直接。
    openCV上也有这样得功能函数。

    展开全文
  • 今天是算法数据结构专题的第36篇文章,我们一起来继续聊聊强连通分量分解的算法。在上一篇文章当中我们分享了强连通分量分解的一个经典算法Kosaraju算法,它的核心原理是通过将图翻转,以及两次递归来实现。今天介绍...

    340eb9cc266a60d4150b9091cd665b42.png

    今天是算法数据结构专题的第36篇文章,我们一起来继续聊聊强连通分量分解的算法。

    在上一篇文章当中我们分享了强连通分量分解的一个经典算法Kosaraju算法,它的核心原理是通过将图翻转,以及两次递归来实现。今天介绍的算法名叫Tarjan,同样是一个很奇怪的名字,奇怪就对了,这也是以人名命名的。和Kosaraju算法比起来,它除了名字更好记之外,另外一个优点是它只需要一次递归,虽然算法的复杂度是一样的,但是常数要小一些。它的知名度也更高,在竞赛当中经常出现。

    先给大家提个醒,相比于Kosaraju算法,Tarjan算法更难理解一些。所以如果你看完本文没有搞明白的话,建议可以阅读一下上一篇文章。这两个算法的效果和复杂度都是一样的,其实学会一个就可以,没必要死磕

    算法框架

    我们来思考一个问题,对于强连通分量分解的算法来说,它的核心原理是什么?

    如果你看过我们之前的文章,那么这个问题对你来说应该不难回答。既然是强连通分量,意味着分量当中每个点都可以互相连通。所以我们很容易可以想到,我们可以从一个点出发,找到一个回路让它再回到起点。这样途中经过的点就都是强连通分量的一部分。

    但是这样会有一个问题,就是需要保证强连通分量当中的每个点都被遍历到,不能有遗漏。针对这个问题我们也可以想到解法,比如可以用搜索算法去搜索它所有能够达到的点和所有的路径。但是这样一来,我们又会遇到另外一个问题。这个问题就是强连通分量之间的连通问题

    我们来看个例子:

    f80bb6e1e084897d2f7377d953ae8dbc.png

    在上面这张图当中如果我们从点1出发,我们可以达到图中的每一个点。但是我们会发现1,2,3是一个强连通分量,4,5,6是另外一个。当我们寻找1所在的强连通分量的时候,很有可能会把4,5,6这三个点也带进来。但问题是它们是自成分量的,并不应该算在1的强连通分量当中。

    我们整理一下上面的分析和思路可以发现强连通分量分解这个算法的核心其实就是解决这两个问题,就是完备性问题。完备意味着不能遗漏也不能冗余和错误,我们想明白核心问题所在之后就很容易搭建起思维框架,接下来我们再来看算法的描述会容易理解得多。

    算法细节

    Tarjan算法的第一个机制是时间戳,也就是在遍历的时候对每一个遍历到的点打上一个值。这个值表示这是第几个遍历的元素。

    这个应该很好理解,我们只需要维护一个全局的变量,在遍历的时候去让它自增就可以了。我们来写下Python代码给大家演示一下:

    stamp = 0
    stamp_dict = {}
    def dfs(u):
        stamp_dict[u] = stamp
        stamp += 1
        for v in Graph[u]:
            dfs(v)
    

    通过时间戳我们可以知道每个点被访问的顺序,这个顺序是正向顺序。举个例子,比如说假设u和v两个点,u的时间戳比v小。那么它们之间的关系只有两种可能,第一种是u能够连通到v,说明从u到v的链路可以走通。第二种是u不能连通到v,这种情况不论反向的从v到u能否连通都不具有讨论意义,因为它们一定不能互相连通。

    所以我们想要找到连通的通路还需要找到反向的路径,在Kosaraju算法当中我们是通过反向图来实现的。在Tarjan当中则采取了另外一种方法。因为我们已经知道各个点的时间戳了,我们完全可以通过时间戳来寻找反向的路径。什么意思呢?其实很简单,当我们在遍历u的时候如果遇到了一个比u时间戳更小的v,那么说明就存在一条反向的路径从u通向v。如果v这时候还没有出栈,意味着v是u的上游的话,那么也就说明存在一条路径从v通向u。这样就说明了u和v可以互相连通。

    既然找到了一对互相连通的u和v,那么我们需要把它们记录下来。但问题是我们怎么知道记录到什么时候为止呢?这个边界在哪里?Tarjan算法设计了另外一个巧妙的机制解决了这个问题。

    这个机制就是low机制,low[u]表示u这个点能够连通到的所有的点的时间戳的最小值。时间戳越小说明在搜索树当中的位置越高,也可以理解成u能够连通到的处在搜索树中最高的点。那么很明显了,这个点就是u这个点所在强连通分量所在搜索树某一棵子树的树根。

    这里可能有一点点绕,我们再来看张图:

    fd9db543b80c34bacadb5e9480b91b16.png

    图中节点所在的序号就是递归遍历的时间戳,我们可以发现对于图上的每个点来说它们的low值都是1。很明显1这个点在搜索树当中是2,3,4这三个点的祖先。也就是说这一个强连通分量的遍历是从1这个点开始的。当1这个点出栈的时候,意味着以1位树根的子树已经遍历完了,所有可能存在的强连通分量也都已经找完了。

    这就带来了另外一个问题,我们假设当前点是u,我们如何知道u这个点是否是图中1这样的树根呢?有没有什么办法可以标记出来呢?

    当然是有的,这样的点有一个特性就是它们的时间戳等于它们的low。所以我们可以用一个数组维护找到的强连通分量,当这些强连通分量能够遍历到的树根出栈的时候,把数组清空。

    我们把上面的逻辑整理一下就可以写出代码来了:

    scc = []
    stack = []
    
    def tarjan(u):
        dfn[u], low[u] = stamp, stamp
        stamp += 1
     stack.append(u)
        
        for v in Graph[u]:
            if not dfn[v]:
                tarjan(v)
                low[u] = min(low[u], low[v])
            elif v in stack:
             low[u] = min(low[u], dfn[v])
        
       if dfn[u] == low[u]:
            cur = []
            # 栈中u之后的元素是一个完整的强连通分量
            while True:
                cur.append(stack[-1])
                stack.pop()
                if cur[-1] == u:
                    break
            scc.append(cur)
    

    最后,我们来看一下之前讲过的经典例子:

    43561cd5220cc94dbacc6acc3dca76dd.png

    首先我们从1点开始,一直深搜到6结束,当遍历到6的时候,DFN[6]=4,low[6]=4,当6出栈时满足条件,6独立称为一个强连通分量。

    5a7952d9b32626fb551e7107f6e9ae05.png

    同理,当5退出的时候也同样满足条件,我们得到了第二个强连通分量。

    eba13d1ccf1f41fa935600e13f1aa55b.png

    接着我们回溯到节点3,节点3还可以遍历到节点4,4又可以连向1。由于1点已经在栈中,所以不会继续递归1点,只会更新low[4] = 1,同样当4退出的时候又会更新3,使得low[3] = 1。

    b27ec9d6ab4d2581cc7b56a00830bb26.png

    最后我们返回节点1,通过节点1遍历到节点2。2能连通的4点已经在栈中,并且DFN[4] > DFN[2],所以并不会更新2点。再次回到1点之后,1点没有其他点可以连通,退出。退出的时候发现low[1] = DFN[1],此时栈中剩下的4个元素全部都是强连通分量。

    317eba6b4834ef763714b5843e89d70d.png

    到这里,整个算法流程的介绍就算是结束了,希望大家都可以enjoy今天的内容。

    我是承志,衷心祝愿大家每天都有所收获。如果还喜欢今天的内容的话,请来一个三连支持吧~(点赞转发、转发

    - END -

    原文链接,求个关注

    算法数据结构 | 20行代码实现,使用Tarjan算法求解强连通分量mp.weixin.qq.com
    e0434d1f7d6db40d86c02b3517c2bc65.png
    展开全文
  • matlab学习——强连通分量

    千次阅读 2018-05-07 15:44:54
    最近motion graph相关实验,发现实现运动过渡需要构建运动图,而为了避免运动过渡陷入死胡同,需要对图结构进行裁剪,方法就是计算图模型的极大强联通分量,但是自己懒得去实现,所以就去搜了一下matlab中有无相关...
  • - PAGE PAGE 3 欢迎下载 该算法主要是仿照c中利用先深搜索算法求图的连通分量的算法改写的 该算法假设有20个点1号和24号相连2号和3号相连5号和67号相连8号和9号相连其他点都是孤立点 结果图如下 代码如下 clear N_...
  • %提取连通分量测试图像,用来检测食物中的外来物 I=im2double(imread('D:\Gray Files\9-18a.tif')); %获得图像大小 [M,N]=size(I); %存放腐蚀后的图像 %设定提取门限,根据经验设定 th=0.808; %将原图像根据上述门限...
  • 图像处理 形态学 腐蚀 膨胀 开闭运算 连通分量 注:原文:http://www.cnblogs.com/tornadomeet/archive/2012/03/20/2408086.html  形态学是提取图像特征的有力工具,针对二值图像和灰度图像的腐蚀、膨胀和重构的...
  • Matlab中bwlabel函数的使用 bwlabel 但bwlabel函数有个问题是,他只区分0和1两种情况,举个例子: a = 1 1 1 2 2 2 0 0 0 bwlabel(a,4) = 1 1 1 1 1 1 0 0 0 所以他判定一二行都是1,所以是联通的,无
  • 【转载】:Matlab 图像处理 形态学 腐蚀 膨胀 开闭运算 连通分量 形态学是提取图像特征的有力工具,针对二值图像和灰度图像的腐蚀、膨胀和重构的基本操作可以组合使用,以执行非常宽泛的任务。其练习代码和结果...
  •  本篇详细介绍利用基于HSV颜色模型的肤色提取与连通区域过滤实现图片的人脸定位,附带知识的介绍略烦多,附带Matlab程序代码,附测试结果。 预备知识 一、图像预处理 1.1 灰度化  在RGB模型中,...
  • matlab开发-tarjane

    2019-08-25 05:52:32
    matlab开发-tarjane。Tarjan的强连通分量算法
  • matlab开发-连接的组件分析无指向图。无向图的连通分量分析,带有阈值和连通性约束。
  • components()函数计算一个图(矩阵)的连通分量[ci sizes] = components(A) 返回矩阵的顶点分别属于哪一个连通分量的索引(Ci),以及每一个连通分量的大小(size),连通分量的个数即为max(components(A))...
  •   bwconncomp函数的作用是在一个二值图像中找出每一个连通分量,并返回一个结构体CC,CC中包含了图像及连通分量的一些属性。   笔者使用的MATLAB版本为2018a,且在该版本中,函数bwconncomp有两个(如下图所示)...
  • ③ 读取待识别数字,进行连通分量分割,确定需要识别数字个数 ④ 通过判别式进行分类 二、源代码 clear all clc close all % 选择训练数据、测试数据路径(即目录TrainData和TestData) TrainDatabasePath = ...
  • 文章《(来点有用的)MATLAB基于形态学的目标检测(一)简单图形统计》的演示代码。在一些例如裂纹测量、细胞...直接使用区域增长和连通分量计算,往往结果不好。而通过基本形态学的操作能在一定程度上解决这个问题。
  • PCA算法是基于图像重构的方法进行图像特征识别的。内有训练样本、多个测试图片以及文档说明。 识别步骤: ① 选择训练样本 ...③ 读取待识别数字,进行连通分量分割,确定需要识别数字个数 ④ 通过判别式进行分类
  • 对于S中的任何像素p,在S中连接p的像素的集合称为连通分量。其实一直对连通分量不是很了解。如果大家谁比较清楚的,望指点一二。如果仅有一个连通分量,S将被称为连通集。在一幅图像中,如果R是连通集,那么像素的...
  • ③ 读取待识别数字,进行连通分量分割,确定需要识别数字个数 ④ 通过判别式进行分类 二、源代码 clear all clc close all % 选择训练数据、测试数据路径(即目录TrainData和TestData) TrainDatabasePath = ...

空空如也

空空如也

1 2
收藏数 38
精华内容 15
关键字:

matlab连通分量

matlab 订阅