博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
讨论:一种基于状态位图的SPIHT改进算法(2)——编解码程序
阅读量:2397 次
发布时间:2019-05-10

本文共 5369 字,大约阅读时间需要 17 分钟。

 

根据上一篇文章提及的改进算法步骤,编写了如下主要代码,其他的相关程序,例如childMat()、coef_DOL()、SnOut()、fracnum2bin()等函数的代码,请参阅我之前发布的SPIHT算法过程详解与Matlab实现的文章,主要代码如下:

function RecIm=spiht(Im,imDim,codeDim,decodeDim)

global rMat cMat

% ----- 起始时间 ----- %

strtime=cputime;

[rMat,cMat]=size(Im);

% ----- 小波分解 ----- %
DecIm=mywavedec2(Im,imDim);
% ----- M_SPIHT Coding ----- %
[T,SnList,RnList]=spihtcoding(DecIm,codeDim);
% ----- M_SPIHT Decoding ----- %
DecodeMat=spihtdecoding(T,SnList,RnList,decodeDim);
% ----- 小波重构 -----%
RecIm=mywaverec2(DecodeMat,imDim,decodeDim);

% ----- 运行时间 ----- %

runtime=cputime-strtime

function [T,SnList,RnList]=spihtcoding(DecIm,codeDim)

% 函数 SPIHTCODING() 是SPIHT算法的编码主程序
% 输入参数:DecIm   ——小波分解系数矩阵;
%          imDim   ——小波分解层数;
%          codeDim ——编码级数。
% 输出参数:T —— 初始阈值,T=2^N,N=floor(log2(max{|c(i,j)|})),c(i,j)为小波系数矩阵的元素
%          SnList —— 排序扫描输出位流

global Mat rMat cMat

% Mat是输入的小波分解系数矩阵,作为全局变量,在编码的相关程序中使用
% rMat、cMat是Mat的行、列数,作为全局变量,在编码、解码的相关程序中使用

%-----------------------%

% ----- Threshold ----- %
%-----------------------%
Mat=DecIm;
MaxMat=max(max(abs(Mat)));
N=floor(log2(MaxMat));
T=2^N;
% 公式:N=floor(log2(max{|c(i,j)|})),c(i,j)为小波系数矩阵的元素

%----------------------------------%

% ----- Output Intialization ----- %
%----------------------------------%
SnList=[];
RnList=[];
FlagCoef=zeros(rMat,cMat);
FlagDch=zeros(rMat/2,cMat/2);
FlagLch=zeros(rMat/2,cMat/2);
FlagLch(1,1)=1;
scanorder=listorder(rMat/2,cMat/2,1,1);
%-------------------------%
% ----- Coding Loop ----- %
%-------------------------%
for d=1:codeDim
    Sn=[];
    Rn=[];
    % 对系数C(0,0)单独编码
    if FlagCoef(1,1)==1
        [biLSP,Np]=fracnum2bin(abs(Mat(1,1)),N);
        Rn=[Rn,biLSP(Np)];
    else
        [isImt,Sign]=SnOut([1 1],N);
        if isImt
            Sn=[Sn,1,Sign];
            FlagCoef(1,1)=1;
        else
            Sn=[Sn,0];
        end
    end
    % 扫描 FlagDch
    for i=1:rMat*cMat/4
        rD=scanorder(i,1);
        cD=scanorder(i,2);
        if FlagDch(rD,cD)==1
            chO=coef_DOL(rD,cD,'O');
            row=size(chO,1);
            for j=1:row
                rO=chO(j,1);
                cO=chO(j,2);
                if FlagCoef(rO,cO)==1
                    [biLSP,Np]=fracnum2bin(abs(Mat(rO,cO)),N);
                    Rn=[Rn,biLSP(Np)];
                else
                    [isImt,Sign]=SnOut([rO,cO],N);
                    if isImt
                        Sn=[Sn,1,Sign];
                        FlagCoef(rO,cO)=1;
                    else
                        Sn=[Sn,0];
                    end
                end
            end
        end
    end
    % 扫描 FlagLch
    for i=1:rMat*cMat/4
        rL=scanorder(i,1);
        cL=scanorder(i,2);
        if FlagDch(rL,cL)==0
            chD=coef_DOL(rL,cL,'D');
            isImt=SnOut(chD,N);
            if isImt
                Sn=[Sn,1];
                FlagDch(rL,cL)=1;
                chO=coef_DOL(rL,cL,'O');
                row=size(chO,1);
                for j=1:row
                    rO=chO(j,1);
                    cO=chO(j,2);
                    [isImt,Sign]=SnOut([rO,cO],N);
                    if isImt
                        Sn=[Sn,1,Sign];
                        FlagCoef(rO,cO)=1;
                    else
                        Sn=[Sn,0];
                    end
                end
                chL=coef_DOL(rL,cL,'L');
                if isempty(chL)
                    FlagLch(rL,cL)=0;
                else
                    isImt=SnOut(chL,N);
                    if isImt
                        Sn=[Sn,1];
                        FlagLch(rL,cL)=1;
                        chO=coef_DOL(rL,cL,'O');
                        row=size(chO,1);
                        for j=1:row
                            rO=chO(j,1);
                            cO=chO(j,2);
                            FlagLch(rO,cO)=1;
                        end
                    else
                        Sn=[Sn,0];
                    end
                end
            else
                Sn=[Sn,0];
            end
        end
    end
    N=N-1;
    SnList=[SnList,Sn,7];  
    RnList=[RnList,Rn,7];
    % 数字‘7’作为区分符,区分不同编码级的Rn、Sn位流
end

function DecodeMat=spihtdecoding(T,SnList,RnList,decodeDim)

% 函数 SPIHTDECODING() 是SPIHT算法的解码主程序
% 输入参数:T —— 初始阈值,T=2^N,N=floor(log2(max{|c(i,j)|})),c(i,j)为小波系数矩阵的元素
%          SnList —— 排序扫描输出位流
%          RnList —— 精细扫描输出位流
%          decodeDim —— 解码级数
% 输出参数:DecodeMat —— 解码后重构的小波系数矩阵

global rMat cMat
% rMat、cMat是Mat的行、列数,作为全局变量,在编码、解码的相关程序中使用

%-------------------------------------------%

% ----- Decoding Input Initialization ----- %
%-------------------------------------------%
N=log2(T);
% 获取初始阈值的指数-N
DecodeMat=2^(N-decodeDim)*rand(rMat,cMat);
% 初始化重构矩阵为一个随机矩阵,其元素最大值小于最高级解码阈值的二分之一
% 这样就可以保证未被扫描赋值的区域有一定的灰度,避免重构图像出现色块

Sn=[];

FlagCoef=zeros(rMat,cMat);
FlagDch=zeros(rMat/2,cMat/2);
FlagLch=zeros(rMat/2,cMat/2);
FlagLch(1,1)=1;
scanorder=listorder(rMat/2,cMat/2,1,1);
%-------------------------%
% ----- Decoding Loop ----- %
%-------------------------%
for d=1:decodeDim
    [Sn,SnList]=getflow(SnList);
    [Rn,RnList]=getflow(RnList);
    % 对系数C(1,1)单独编码
    if FlagCoef(1,1)==1
        [DecodeMat,Rn]=decRefine(DecodeMat,Rn,N,1,1);
    else
        if Sn(1)==1
            Sn(1)=[];
            if Sn(1)==1
                Sn(1)=[];
                DecodeMat(1,1)=1.5*2^N;
            else
                Sn(1)=[];
                DecodeMat(1,1)=-1.5*2^N;
            end
            FlagCoef(1,1)=1;
        else
            Sn(1)=[];
            DecodeMat(1,1)=0;
        end
    end
    % 扫描 FlagDch
    for i=1:rMat*cMat/4
        rD=scanorder(i,1);
        cD=scanorder(i,2);
        if FlagDch(rD,cD)==1
            chO=coef_DOL(rD,cD,'O');
            row=size(chO,1);
            for j=1:row
                rO=chO(j,1);
                cO=chO(j,2);
                if FlagCoef(rO,cO)==1
                    [DecodeMat,Rn]=decRefine(DecodeMat,Rn,N,rO,cO);
                else
                    if Sn(1)==1
                        Sn(1)=[];
                        if Sn(1)==1
                            Sn(1)=[];
                            DecodeMat(rO,cO)=1.5*2^N;
                        else
                            Sn(1)=[];
                            DecodeMat(rO,cO)=-1.5*2^N;
                        end
                        FlagCoef(rO,cO)=1;
                    else
                        Sn(1)=[];
                        DecodeMat(rO,cO)=0;
                    end
                end
            end
        end
    end
    % 扫描 FlagLch
    for i=1:rMat*cMat/4
        rL=scanorder(i,1);
        cL=scanorder(i,2);
        if FlagDch(rL,cL)==0
            if Sn(1)==1
                Sn(1)=[];
                FlagDch(rL,cL)=1;
                chO=coef_DOL(rL,cL,'O');
                row=size(chO,1);
                for j=1:row
                    rO=chO(j,1);
                    cO=chO(j,2);
                    if Sn(1)==1
                        Sn(1)=[];
                        if Sn(1)==1
                            Sn(1)=[];
                            DecodeMat(rO,cO)=1.5*2^N;
                        else
                            Sn(1)=[];
                            DecodeMat(rO,cO)=-1.5*2^N;
                        end
                        FlagCoef(rO,cO)=1;
                    else
                        Sn(1)=[];
                        DecodeMat(rO,cO)=0;
                    end
                end
                chL=coef_DOL(rL,cL,'L');
                if isempty(chL)
                    FlagLch(rL,cL)=0;
                else
                    if Sn(1)==1
                        Sn(1)=[];
                        FlagLch(rL,cL)=1;
                        chO=coef_DOL(rL,cL,'O');
                        row=size(chO,1);
                        for j=1:row
                            rO=chO(j,1);
                            cO=chO(j,2);
                            FlagLch(rO,cO)=1;
                        end
                    else
                        Sn(1)=[];
                    end
                end
            else
                Sn(1)=[];
            end
        end
    end
    N=N-1;
end
我使用的是Matlab r2007b,小波分解用的是自己编写的Haar二维小波分解程序。对一幅64*64的Girl灰度图像进行SPIHT编码、解码,程序给运行结果:
1、按照我前天的文章《多级树集合分裂(SPIHT)算法的过程详解和Matlab实现(2)数学表述》介绍的SPIHT算法步骤编写的程序来进行编、解码,3级小波分解和重构,7级编码,7级解码,程序运行时间是:
runtime = 6.8281
2、按照本文所提到的改进算法编写的上述程序来编、解码,同样是3级小波分解和重构,7级编码,7级解码,程序运行时间是:
runtime = 9.5313
编解码速度反而下降了,这里的原因是什么呢?欢迎有兴趣的朋友发表评论或者Email交流!

你可能感兴趣的文章
@90后程序员,“颜值即正义”的现在,程序员应该如何更新穿搭?
查看>>
程序员须知:必须建立个人知识库,它的重要性你需要了解一下!
查看>>
C/C++知识分享番外:如何申请一个腾讯地图用户Key?
查看>>
程序员提高编程技术最有效的一件事?了解一下,迅速提升自己!
查看>>
程序员找工作时,大公司 VS 小公司,应该如何做出正确的选择?
查看>>
适合编写C语言代码的编程软件有哪些?大学生赶紧行动起来!
查看>>
即将步入2020年,程序员如何在新的一年更进一步?你需要这样做
查看>>
编程萌新注意:别再这样问问题了!学会这样快速定位错误内容
查看>>
C/C++编程笔记:经典游戏植物大战僵尸游戏辅助,源码送上
查看>>
从Socket编程看HTTP服务器设计
查看>>
Java SPI机制原理和使用场景
查看>>
Mysql explain-type使用详解
查看>>
Ocean设计思路和架构设计
查看>>
RPC框架(一) - Java自带的RMI
查看>>
缓存篇(一)- Guava
查看>>
缓存篇(二)- JetCache
查看>>
缓存篇(三)- Spring Cache框架
查看>>
MySQL基本原理和使用技巧
查看>>
别踩坑!使用MySQL唯一索引请注意
查看>>
Java8新特性学习(一)- 开篇介绍
查看>>