作者YoursEver (银英传出webgame!?)
看板MATLAB
标题Re: [讨论] label矩阵
时间Tue Sep 20 10:45:06 2016
※ 引述《andgitisaac (AndGiTiSaaC)》之铭言:
: 请问各位前辈们
: 现在有个label矩阵
: L = [2 2 2 2 3;
: 2 3 2 3 3;
: 2 3 2 4 4;
: 2 2 2 4 4;
: 1 1 2 1 1];
: 但目前碰到的问题得把
: 即便是相同label
: 但没有连通的区域给分离(4连通)
: 也就是说L变成
: L = [2 2 2 2 3;
: 2 6 2 3 3;
: 2 6 2 4 4;
: 2 2 2 4 4;
: 1 1 2 5 5];
: 目前的作法是
: maxlabel = max(L(:))
: for n = 1:max(L(:))
: [bw, num] = bwlabel(L == n, 4)
: if num > 1
: for k = 2:num
: maxlabel = maxlabel + 1
: L(bw == k) = maxlabel
: end
: end
: end
: 但是由於label矩阵标签数非常多,200多组就要花快十秒
: 想请问前辈们有没有其他更好的做法
你的作法大概是 O(n^2),
所以理论上只要增加一个buffer,
写成 O(n) 的形式就能加速.
所以改成:
Total_num = 0;
Relabeled_L = zeros( size(L) );
for n=1:1:max( L(:) )
[bw_buffer, num] = bwlabel(L==n,4);
Relabeled_L( bw_buffer~0 ) = bw_buffer( bw_buffer~0 ) + Total_num;
%把bw_buffer得到的label,略过0的位置,平移前一个iteration的总label数
Total_num = Total_num + num;
%更新总label数
clear bw_buffer; clear num;
end
--
没仔细检查,如果有typo请见谅.
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.109.22.216
算的雇{迭뀠文章网址:
https://webptt.com/cn.aspx?n=bbs/MATLAB/M.1474339509.A.25F.html
1F:→ YoursEver: 回了才发现和前一篇sunev老大的写法是一样的. 09/20 10:58
2F:推 sunev: 但是原PO说变慢了,可能先profile分析一下瓶项在哪里 09/24 02:16
这我就不确定了,
因为我自己处理过一模一样要重新labelling的问题,
当时的经验是这样写才会快.
我的case是要在一个stage内,
处理 400*9张 400*9的小影像 + 400*9张800*9的小影像
靠i7, 64-bit Win7, 32GB ram, Matlab 2012/2013的机器,
平均约需4xx秒.
因此我对於原po所说的速度下降毫无头绪.
※ 编辑: YoursEver (218.161.51.131), 09/24/2016 07:40:26
以下是不负责猜测,
我的主要问题是: 有没有人知道Matlab的 for-loop 运作机制?
对於下面的这个for loop来说:
for i=1:1:max(L(:))
...
end
到底运作的机制是
(1) 先计算 bound = max( L(:) ),
再跑 for i=1:1:bound,
还是,
(2) 类似do-while的机制,
但,是在每一个iteration之初,检查是否 i<=max(L(:)),
会这样说是因为,
若照前篇原po和sunev的写法,
结构大致是:
for i=1:1:max(L(:))
...
L(bw>1)=L(bw>1)+maxlabel-1;
maxlabel=maxlabel+num-1;
...
end
换句话说,在for-loop的计算过程里,
max( L(:) )是一直被增加的,
因此,
若Matlab的机制是上面的(2),
那的确可能因为for-loop的中止条件一直後延,
而造成不必要的延宕.
用我的写法,另开一个array存重新labelling过後的资料,
就不会有这样的问题.
※ 编辑: YoursEver (218.161.51.131), 09/24/2016 08:05:42
3F:推 sunev: 应该是第一种 a=1;for i=1:mod(2*max(a),5),a=[a i];end,a 09/24 14:26
刚才测试了一下, 的确是第一种没错.
clear all;
L = [1:1:10];
for ii=1:2:max(L)
ii
L = [L, 10+ii];
[L]
end
最後跑完时,
ii = 9;
L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19];
那我就真的不知道为什麽原po会说速度变慢了.
※ 编辑: YoursEver (218.161.51.131), 09/24/2016 16:25:28
4F:推 andgitisaac: 首先先感谢大大的解释,很抱歉最近没有回版上看到前 09/27 20:18
5F:→ andgitisaac: 辈的後续发文。 09/27 20:19
6F:→ andgitisaac: 同时也相当感谢sunev大大在第一时间回覆我的疑问。 09/27 20:19
7F:→ andgitisaac: 当初在看了大大的buffer解释後,也觉得变慢很奇怪 09/27 20:20
8F:→ andgitisaac: 事情忙完後重新跑了一次程式,却发现时间确实有加快 09/27 20:21
9F:→ andgitisaac: 由於当初没有做更深的研究因此没多加注意 09/27 20:23
10F:→ andgitisaac: 过几天要再来实测高解析度的影像。 09/27 20:24
11F:→ andgitisaac: 相信是我一时不察所发生的错误,也再次感谢两位前辈 09/27 20:25
12F:→ andgitisaac: 的协助。谢谢! 09/27 20:25
13F:推 sunev: 如果瓶颈是bwlabel,num都不大,这种改写不会改善太多 09/28 11:41
14F:→ sunev: 但变慢应该是不至於。 09/28 11:41