声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 4996|回复: 34

[编程技巧] 游程平滑算法编程实现问题

[复制链接]
发表于 2007-6-9 20:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

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

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

评分

1

查看全部评分

回复
分享到:

使用道具 举报

发表于 2007-6-9 22:54 | 显示全部楼层
给个例子,仅供参考。
clear;
clc;
k=[1 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 0 1 0 1];
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,你看你自己的情况改吧
发表于 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 = [tt,length(I)-index1(end)];
        index3 = find(tt >= T);
        I(index1(index3)+1:index1(index3)+tt(index3)) = 1;
    elseif length(index1) == length(index2)-1,
        tt(1) = index2(1);
        tt = [tt,index1 - index2(2:end)];
        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
发表于 2007-6-9 22:57 | 显示全部楼层
我的例子对头尾没有要求,这个问题麻烦就麻烦在于要对0或者1打头结尾的情况要分开讨论。
发表于 2007-6-9 22:59 | 显示全部楼层

回复 #4 w89986581 的帖子

呵呵,尾巴的要求感觉好像不是很高,起头加个判断语句应该就可以了。
发表于 2007-6-9 23:06 | 显示全部楼层
一个更快捷的方法:将I转化成字符串格式,分解成若干子字符串,判断零子字符串的长度是否满足T,满足则用等长的1字符串代替0字符串,最后再转化回数值数组。

评分

1

查看全部评分

 楼主| 发表于 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];
不知道我的理解对不对?希望您能给指正
发表于 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 = [tt,length(I)-index1(end)];
        index3 = find(tt <= T);
        I(index1(index3)+1:index1(index3)+tt(index3)) = 1;
    elseif length(index1) == length(index2)-1,
        tt(1) = index2(1);
        tt = [tt,index1 - index2(2:end)];
        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=[0 0 1 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 1 1];
??? Index exceeds matrix dimensions.
就没有结果了

  因为我对你的程序理解的不到位i,还是解决不了这个问题,希望主任不辛苦
不吝赐教,把这个问题给解决了。另外,如果要合并0游程做哪些修改呢?
最近是在笨的可以,本以为对~I进行处理就可以,但是有时结果也不对、、、
郁闷啊,再次对主任的热心帮助表示感谢
发表于 2007-6-11 21:31 | 显示全部楼层
:@L :@L :@L 别叫主任,叫我同学:loveliness:
我自己先测试一下,呵呵.


clear all
I=[0 0 0 0 0 0 0 1 1 1 0 1 0 1 0 0 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0 1 1 0 0 0 0 0 1];
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 = [tt,length(I)-index1(end)];
        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 = [index2(2:end) - index1];
        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 编辑 ]
发表于 2007-6-11 21:52 | 显示全部楼层
写了一个简单的,不知道速度如何,没有测试。另外,如果瓶颈在 cellfun 命令上,改用循环吧:
  1. a = [1 1 1 1 1 0 0 0 0 0 1 1 1 1 0 0 0 1 1];
  2. T = 4;
  3. b = sprintf('%d',a);
  4. [c,d,e,f]=regexp(b,'0+');
  5. g = cellfun(@length,f);
  6. ind = g<T;
  7. b(c(ind):d(ind)) = '1';
  8. aa = str2num(b')'
复制代码


注:str2num 不能换成 str2double,否则最后的结果连成一片,成为一个大整数了

[ 本帖最后由 eight 于 2007-6-11 21:55 编辑 ]
 楼主| 发表于 2007-6-11 21:59 | 显示全部楼层
这下不报错了,而且那个矩阵全部被合并为1。如果想合并0游程,要做哪些更改呢?
我想先知道结果,然后好好研究高位高手的程序。。。
发表于 2007-6-11 22:01 | 显示全部楼层
原帖由 花如月 于 2007-6-11 21:59 发表
这下不报错了,而且那个矩阵全部被合并为1。如果想合并0游程,要做哪些更改呢?
我想先知道结果,然后好好研究高位高手的程序。。。


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

建议使用每个帖子右下角的“引用或者“回复”,而非整个页面的“新帖”、“回复”
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-5-3 12:24 , Processed in 0.343286 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表