游程平滑算法编程实现问题
小弟最近要用游程平滑算法对图像矩阵进行处理。但是费好大功夫还没想到该怎么实现这个算法:游程平滑算法是对同一扫描行上的黑像素点之间的距离进行检测,当两相邻黑像素点之间的空白游程长度小于门限值时,则将这两点之间的空白游程全部填黑.考虑到一条水平扫描线上的一段游程,L=(P1,P2,…,Pi,Pi+1,…,Pj-1,Pj,…,Pn);其中游程L1=(P1,…,Pi)和L3=(Pj,…,Pn)是1-游程(即黑像素游程),而L2=(Pi+1,…,Pj-1)是0-游程(即白像素游程).当L2的长度j-i-1小于设定的门限T时,则将两黑游程L1和L3连接起来即把游程L2的全部像素平滑成黑.以T=4的情况为例,在图1表示的平滑过程中,两个1-游程之间的0-游程长度为3,因而被平滑为1-游程,这样得到的连接起来的1-游程的长度为9.平滑前:1111100000111100011
平滑后:1111100000111111111图1 游程平滑举例貌似挺容易实现但是,我写着写着就进行不下去了:@(
S=size(I);
T=10;%门限设置
for i=0:S(1)
for j=0:S(2)
K(i,j)......
觉得是这样的结构,但是不会写啊。我的I矩阵是个二值化矩阵,0游程为黑像素游程,1游程为白像素游程。急啊,高手一定帮帮小弟啊,在线等、、、
给个例子,仅供参考。
clear;
clc;
k=;
len=length(k);
T=4;
head=1;
tail=1;
for i=2:len
if k(i)==0
tail=i+1;
if k(i+1)==1
if tail-head<=T
for j=head:tail
k(j)=1;
end
end
head=i+1;
tail=i+1;
end
end
end
例子中默认的起始和末尾的都是1,你看你自己的情况改吧
再来一个版本
clear allclc
I = [ 0 1 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0];
T = 4;
Idiff = diff(I);
index1 = find(Idiff == -1);
index2 = find(Idiff == 1);
if length(index1) == 0 | length(index2) == 0,
%%%全1或者全0的情况,根据自己需要单独处理一下
else
if length(index1) == length(index2)+1,
tt = index2 - index1(1:end-1);
tt = ;
index3 = find(tt >= T);
I(index1(index3)+1:index1(index3)+tt(index3)) = 1;
elseif length(index1) == length(index2)-1,
tt(1) = index2(1);
tt = ;
index3 = find(tt >= T);
for ii = 1:length(index3);
I(index1(index3(ii))+1:index1(index3(ii))+tt(index3(ii))) = 1;
end
elseif length(index1) == length(index2),
if index1(1)>index2(1),
if index2(1) >= T;
I(1:index2(1)) = 1;
end
tt = index2(2:end) - index1(1:end-1);
index3 = find(tt >= T);
for ii = 1:length(index3);
I(index1(index3(ii))+1:index1(index3(ii))+tt(index3(ii))) = 1;
end
if length(I)-index1(end) >= T,
I(index1(end):end) = 1;
end
elseif index1(1) < index2(1),
tt = index2 - index1;
index3 = find(tt >= T);
for ii = 1:length(index3);
I(index1(index3(ii))+1:index1(index3(ii))+tt(index3(ii))) = 1;
end
end
end
end
I 我的例子对头尾没有要求,这个问题麻烦就麻烦在于要对0或者1打头结尾的情况要分开讨论。
回复 #4 w89986581 的帖子
呵呵,尾巴的要求感觉好像不是很高,起头加个判断语句应该就可以了。 一个更快捷的方法:将I转化成字符串格式,分解成若干子字符串,判断零子字符串的长度是否满足T,满足则用等长的1字符串代替0字符串,最后再转化回数值数组。 太感谢各位的耐心解答了,特别是w89986581 主任,全收下了。。回去慢慢研究去:loveliness: 刚才试了一下:w89986581 主任的结果好像有点不对。不知道是不是我没用对,我把您的代码直接复制的到命令行出来是这样的结果:I =
Columns 1 through 18
0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Columns 19 through 23
1 1 1 1 0
如果合并1游程,在T=4的情况下结果应该是:
处理前I = [ 0 1 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0];
处理后I = [ 0 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0];
不知道我的理解对不对?希望您能给指正 哈哈,对不起.理解成大于门限的啦.请把>=T,都改成<=T:@L Columns 1 through 18
1 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0
Columns 19 through 23
0 0 0 1 1
再次对w89986581 主任的热心帮助表示衷心的感谢:victory:
快疯了,紧急求助w89986581 主任
您的程序我读了几遍,只是懂了个大概。令我意外的事,我刚才随机取了个数列它居然报错了按照你的意见把把>=T,都改成<=T
I = [ 0 1 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0];
T = 4;
Idiff = diff(I);
index1 = find(Idiff == -1);
index2 = find(Idiff == 1);
if length(index1) == 0 | length(index2) == 0,
%%%全1或者全0的情况,根据自己需要单独处理一下
coutinue;
else
if length(index1) == length(index2)+1,
tt = index2 - index1(1:end-1);
tt = ;
index3 = find(tt <= T);
I(index1(index3)+1:index1(index3)+tt(index3)) = 1;
elseif length(index1) == length(index2)-1,
tt(1) = index2(1);
tt = ;
index3 = find(tt <= T);
for ii = 1:length(index3);
I(index1(index3(ii))+1:index1(index3(ii))+tt(index3(ii))) = 1;
end
elseif length(index1) == length(index2),
if index1(1)>index2(1),
if index2(1) <= T;
I(1:index2(1)) = 1;
end
tt = index2(2:end) - index1(1:end-1);
index3 = find(tt <= T);
for ii = 1:length(index3);
I(index1(index3(ii))+1:index1(index3(ii))+tt(index3(ii))) = 1;
end
if length(I)-index1(end) <=T,
I(index1(end):end) = 1;
end
elseif index1(1) < index2(1),
tt = index2 - index1;
index3 = find(tt <= T);
for ii = 1:length(index3);
I(index1(index3(ii))+1:index1(index3(ii))+tt(index3(ii))) = 1;
end
end
end
end
I
这个本身没有问题,结果我也帖出来了。但是我换了一个I后就出错了
I=;
??? Index exceeds matrix dimensions.
就没有结果了
因为我对你的程序理解的不到位i,还是解决不了这个问题,希望主任不辛苦
不吝赐教,把这个问题给解决了。另外,如果要合并0游程做哪些修改呢?
最近是在笨的可以,本以为对~I进行处理就可以,但是有时结果也不对、、、
郁闷啊,再次对主任的热心帮助表示感谢 :@L :@L :@L 别叫主任,叫我同学:loveliness:
我自己先测试一下,呵呵.
clear all
I=;
T = 4;
Idiff = diff(I);
index1 = find(Idiff == -1);
index2 = find(Idiff == 1);
if length(index1) == 0 | length(index2) == 0,
%%%全1或者全0的情况,根据自己需要单独处理一下
coutinue;
else
if length(index1) == length(index2)+1,
tt = index2 - index1(1:end-1);
tt = ;
index3 = find(tt <= T);
for ii = 1:length(index3);
I(index1(index3(ii))+1:index1(index3(ii))+tt(index3(ii))) = 1;
end
elseif length(index1) == length(index2)-1,
if index2(1) <= T;
I(1:index2(1)) = 1;
end
tt = ;
index3 = find(tt <= T);
for ii = 1:length(index3);
I(index1(index3(ii))+1:index1(index3(ii))+tt(index3(ii))) = 1;
end
elseif length(index1) == length(index2),
if index1(1)>index2(1),
if index2(1) <= T;
I(1:index2(1)) = 1;
end
tt = index2(2:end) - index1(1:end-1);
index3 = find(tt <= T);
for ii = 1:length(index3);
I(index1(index3(ii))+1:index1(index3(ii))+tt(index3(ii))) = 1;
end
if length(I)-index1(end) <=T,
I(index1(end):end) = 1;
end
elseif index1(1) < index2(1),
tt = index2 - index1;
index3 = find(tt <= T);
for ii = 1:length(index3);
I(index1(index3(ii))+1:index1(index3(ii))+tt(index3(ii))) = 1;
end
end
end
end
I
[ 本帖最后由 w89986581 于 2007-6-11 21:37 编辑 ] 写了一个简单的,不知道速度如何,没有测试。另外,如果瓶颈在 cellfun 命令上,改用循环吧:a = ;
T = 4;
b = sprintf('%d',a);
=regexp(b,'0+');
g = cellfun(@length,f);
ind = g<T;
b(c(ind):d(ind)) = '1';
aa = str2num(b')'
注:str2num 不能换成 str2double,否则最后的结果连成一片,成为一个大整数了
[ 本帖最后由 eight 于 2007-6-11 21:55 编辑 ] 这下不报错了,而且那个矩阵全部被合并为1。如果想合并0游程,要做哪些更改呢?
我想先知道结果,然后好好研究高位高手的程序。。。 原帖由 花如月 于 2007-6-11 21:59 发表 http://www.chinavib.com/forum/images/common/back.gif
这下不报错了,而且那个矩阵全部被合并为1。如果想合并0游程,要做哪些更改呢?
我想先知道结果,然后好好研究高位高手的程序。。。
你是指我的程序还是?我的程序其运行结果跟你在 1 楼所要的一致
建议使用每个帖子右下角的“引用或者“回复”,而非整个页面的“新帖”、“回复”