matlab多值连通区域标记

来源:互联网 发布:金十数据日历桌面 编辑:程序博客网 时间:2024/05/21 15:46
请问多值连通区域应该如何标记?用bwlabel只能求二值的连通区域标记。
a=
[
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 1 3 1 1 1 1 1
1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
1 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
]
我想把这样的矩阵做连通区域标记,应该如何进行?

要注意的是,其中有一片被2包围的1要和其他的1标记不同。


Plain Text code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
I=[
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  
 1 1 2 2 2 2 2 2 2 2 1 1 1 1 1  
 1 1 2 1 1 1 1 1 1 2 1 1 3 1 1  
 1 1 2 1 1 1 1 1 1 2 1 1 3 1 1 
 1 1 2 1 1 1 1 1 1 2 1 1 3 1 1  
 1 1 2 2 2 2 2 2 2 2 1 1 1 1 1 
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  
];
[m,n]=size(I);
for i=1:m
    for j=1:n
        root(i,j)=(i-1)*n+j;
    end
end
for i=1:m
    for j=1:n
         if(i>1&&j<n)
             if(I(i-1,j+1)==I(i,j)) root(i,j)=root(i-1,j+1);
             end
         end
         if(j<n)
             if(I(i,j+1)==I(i,j)) root(i,j+1)=root(i,j);
             end
         end
         if(i<m)
             if(I(i+1,j)==I(i,j)) root(i+1,j)=root(i,j);
             end
         end
         if(i<m&&j<n)
             if(I(i+1,j+1)==I(i,j))  root(i+1,j+1)=root(i,j);
             end
         end
    end
end
root
a=unique(root)'
别让高能耗机房拖了企业发展的后腿
对我有用[1] 丢个板砖[0] 引用 | 举报 | 管理
#2 得分:0回复于: 2013-04-08 20:04:08
楼上解法可以实现label问题,不过有2个缺点:
1. label不是按顺序排列;
2. 2次循环跟图片尺寸有关,对于高分辨率图像效率比较低

采用另一种思路:
Plain Text code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
% a = [
% 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
% 1 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1
% 1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 1 3 1 1 1 1 1
% 1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 1 2 2 1 1 1 1 1 2 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 1 1 1
% 1 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
% 1 1 1 1 4 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
% 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
% 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
% ];
a = [   1 2 2 2 3
        1 2 1 2 1
        1 2 2 2 1
        1 4 1 1 1
        1 1 1 1 1];
maxa = max(a(:));
mina = max(min(a(:)),1);
result = zeros(size(a));
curnum = 0;
for i = mina : maxa
    curImg = bwlabel(a==i);
    for j = 1 : max(curImg(:))
        curImg(curImg==j) = curnum+j;
    end
    curnum = curnum+length(unique(curImg))-1;
    result = result+curImg;
end
result

为了测试,采用了比较小的矩阵,测试结果:
Plain Text code
?
1
2
3
4
5
6
7
result =
 
     1     3     3     3     4
     1     3     2     3     1
     1     3     3     3     1
     1     5     1     1     1
     1     1     1     1     1
专访邓凡平:Android开发路上的快速学习之道
对我有用[1] 丢个板砖[0] 引用 | 举报 | 管理
#3 得分:0回复于: 2013-04-09 09:56:33
楼上的想法确实不错,效率是要高好多啊,谢谢分享~~
免费领取CSDN积分大礼包
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
#4 得分:0回复于: 2013-04-09 10:43:07
引用 2 楼 libralibra 的回复:
楼上解法可以实现label问题,不过有2个缺点:
1. label不是按顺序排列;
2. 2次循环跟图片尺寸有关,对于高分辨率图像效率比较低

采用另一种思路:
Plain Text code?12345678910111213141516171819202122232425262728293031323334353637% a = [% 1 1 1 1 1 1……

你好,我在分割完图片以后,又遇到了一个问题就是分割完之后的区域太多了,有一些小区域没必要区分的也分出来了,怎么弄呢?详细图片如下:

PS:1、主要问题在于图中的高亮、灰色都要提取并且中间的两块黑色的也要提取,分割并标记。
    2、按照上述的分割思想,由于图中的高亮的部分中包含了许多的小色块,是的整体的连通区域多达1000多个,我需要吧这些个小色块合并到高亮区域;
    3、如果想第一步边缘检测再来分割、标记,但是边缘检测的结果并不是非常的好,所以边缘检测的方法不太合适。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
#5 得分:0回复于: 2013-04-09 11:31:17
我是使用 先膨胀 后腐蚀的办法 实现的,不知道 大神 有啥么 好方法(主要是 效果好)没有啊?
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
#6 得分:0回复于: 2013-04-09 16:15:24
引用 4 楼 ymqq1 的回复:
引用 2 楼 libralibra 的回复:楼上解法可以实现label问题,不过有2个缺点:
1. label不是按顺序排列;
2. 2次循环跟图片尺寸有关,对于高分辨率图像效率比较低

采用另一种思路:
Plain Text code?123456789101112131415161718192021222324252627282930313233343536……

针对你的要求和这个图像,你的思路有问题,处理先后错误了.
应该先二值,用形态学办法消除小黑点和那些小区域,
将label作为最后一步.
也就行: 读图->灰度化->阀值化->二值->去噪->连通域标记,按照这个顺序来
最好不要先标记,再去噪,这样你的工作量大了很多很多.

你贴个原图(未处理的),然后再贴一个需要的处理结果,用红色在第二张图中标记出你需要的区域,大家看看
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
#7 得分:0回复于: 2013-04-09 16:26:11
引用 6 楼 libralibra 的回复:
引用 4 楼 ymqq1 的回复:引用 2 楼 libralibra 的回复:楼上解法可以实现label问题,不过有2个缺点:
1. label不是按顺序排列;
2. 2次循环跟图片尺寸有关,对于高分辨率图像效率比较低

采用另一种思路:
Plain Text code?1234567891011121314151617181920212223242526272……

该图片的下载链接为:http://pan.baidu.com/share/link?shareid=367762&uk=1847919476
其实就是下面这个图片:

主要的要求是:
如下图:红色区域内是有用的区域,要分割出来各个部分,包括左右两个半月形的黑色部分也要分别标记。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
#8 得分:0回复于: 2013-04-09 16:29:24
我的思路是:
中值去噪(主要消除的是一些孤立的点)->分割->膨胀、腐蚀(主要用来消去图中高亮部分中的小洞)->标记
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
#9 得分:0回复于: 2013-04-09 16:52:43
引用 8 楼 ymqq1 的回复:
我的思路是:
中值去噪(主要消除的是一些孤立的点)->分割->膨胀、腐蚀(主要用来消去图中高亮部分中的小洞)->标记

用的步骤越少越好,拿到了目标区域,那2个黑色部分怎么标记用你原来的标记办法即可.或者对掩膜求反后操作都行.