花如月 发表于 2007-6-9 20:49

游程平滑算法编程实现问题

小弟最近要用游程平滑算法对图像矩阵进行处理。但是费好大功夫还没想到该怎么实现这个算法:

游程平滑算法是对同一扫描行上的黑像素点之间的距离进行检测,当两相邻黑像素点之间的空白游程长度小于门限值时,则将这两点之间的空白游程全部填黑.考虑到一条水平扫描线上的一段游程,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游程为白像素游程。急啊,高手一定帮帮小弟啊,在线等、、、

spano 发表于 2007-6-9 22:54

给个例子,仅供参考。
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,你看你自己的情况改吧

w89986581 发表于 2007-6-9 22:56

再来一个版本

clear all
clc

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

w89986581 发表于 2007-6-9 22:57

我的例子对头尾没有要求,这个问题麻烦就麻烦在于要对0或者1打头结尾的情况要分开讨论。

spano 发表于 2007-6-9 22:59

回复 #4 w89986581 的帖子

呵呵,尾巴的要求感觉好像不是很高,起头加个判断语句应该就可以了。

w89986581 发表于 2007-6-9 23:06

一个更快捷的方法:将I转化成字符串格式,分解成若干子字符串,判断零子字符串的长度是否满足T,满足则用等长的1字符串代替0字符串,最后再转化回数值数组。

花如月 发表于 2007-6-10 10:54

太感谢各位的耐心解答了,特别是w89986581 主任,全收下了。。回去慢慢研究去:loveliness:

花如月 发表于 2007-6-10 11:29

刚才试了一下: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];
不知道我的理解对不对?希望您能给指正

w89986581 发表于 2007-6-10 21:34

哈哈,对不起.理解成大于门限的啦.请把>=T,都改成<=T:@L

花如月 发表于 2007-6-11 08:46

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:

花如月 发表于 2007-6-11 21:22

快疯了,紧急求助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进行处理就可以,但是有时结果也不对、、、
郁闷啊,再次对主任的热心帮助表示感谢

w89986581 发表于 2007-6-11 21:31

:@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 编辑 ]

eight 发表于 2007-6-11 21:52

写了一个简单的,不知道速度如何,没有测试。另外,如果瓶颈在 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 编辑 ]

花如月 发表于 2007-6-11 21:59

这下不报错了,而且那个矩阵全部被合并为1。如果想合并0游程,要做哪些更改呢?
我想先知道结果,然后好好研究高位高手的程序。。。

eight 发表于 2007-6-11 22:01

原帖由 花如月 于 2007-6-11 21:59 发表 http://www.chinavib.com/forum/images/common/back.gif
这下不报错了,而且那个矩阵全部被合并为1。如果想合并0游程,要做哪些更改呢?
我想先知道结果,然后好好研究高位高手的程序。。。

你是指我的程序还是?我的程序其运行结果跟你在 1 楼所要的一致

建议使用每个帖子右下角的“引用或者“回复”,而非整个页面的“新帖”、“回复”
页: [1] 2 3
查看完整版本: 游程平滑算法编程实现问题