精华内容
下载资源
问答
  • 无失真信源编码

    千次阅读 2018-12-27 22:07:26
    (1)信源编码:质量一定,如何提高信息传输速度(编码效率,压缩比) (2)信道编码:信道传输速度一定,如何提高信息传输质量(抗干扰能力) 信源编码:以提高通信有效性为目的的编码。通常通过压缩信源的冗余度来实现,...

    编码讨论的问题

    (1)信源编码:质量一定,如何提高信息传输速度(编码效率,压缩比)
    (2)信道编码:信道传输速度一定,如何提高信息传输质量(抗干扰能力)
    信源编码:以提高通信有效性为目的的编码。通常通过压缩信源的冗余度来实现,采用的一半方法是压缩每个信源符号的平均比特数或信源的码率(bit/符号),即同样多的信息用较少的码率传送,使单位时间内传送的平困信息量增加,从而提高通信的有效性。
    信道编码:是以提高信息传输的可靠性位目的的编码。通常通过增加信源的冗余度实现。采用的一半方法是增大码率/带宽。与信源编码正好相反。
    信源编码理论是信息论的一个重要分支,其理论基础是信源编码的两个定理:
    1.无失真信源编码定理
    2.限失真信源编码定理
    等长信源编码定理
    一个熵为 H(S) 的离散无记忆信源,若对信源长为N的符号序列进行等长编码,设码字是从r个符号集中选取l个符号组成。
    kraft不等式:对于字符集X={x1,x2,......xM}X=\left \{ x_1,x_2,......x_M \right \},将其编码成r进制码(即码符号集有r个,如二进制码就是码符号集有0和1),对应的码字集长度为{l1,l2,......lM}\left \{ l_1,l_2,......l_M \right \},必满足不等式,
    i=1Mrli1\sum_{i=1}^{M}r^{-l_i}\leq 1
    这表明:1.异前缀码必定满足kraft不等式。2.若一组数{l1,l2,......lM}\left \{ l_1,l_2,......l_M \right \}满足kraft不等式,则必定存在相应码长的异前缀码。
    单义可译定理:信源U存在单义可译码的充分必要条件是满足kraft不等式。

    主要码的种类

    非奇异码:每个信源符号对应的码字都不同
    唯一可译码:任意信源符号穿编出的码字都不同

    码率:码的信息传输率
    R=H(S)n=H(X)R=\frac{H(S)}{\overline{n}}=H(X)
    H(S)是信源符号的熵,即平均一个符号含有的信息量(bit);n\overline{n}是是平均码长;X是码符号集
    平均码长界限定理:若一个离散无记忆信源S有熵H(S),编成r进制码,则总可以找到一种无失真编码,构成单义可译码,使平均码长l\overline{l}满足:
    H(S)logrl<H(S)logr+1\frac{H(S)}{logr}\leq \overline{l}< \frac{H(S)}{logr}+1
    无失真(变长)信源编码定理,香农第一定理:离散无记忆信源S的熵为H(S),对其进行N次扩展,构成扩展信源SNS^{N},其熵H(SN)=NH(S)H(S^N)=NH(S)对其进行r进制编码。总可以找到一种无失真编码方法,构成单义可译码,使得信源S中每个符号sis_i所需要的平均码长l\overline{l}满足
    (1)
    H(S)logrl<H(S)logr+1N\frac{H(S)}{logr}\leq \overline{l}< \frac{H(S)}{logr}+\frac{1} {N}
    且,当N->++\infty时,有limN>+l=H(S)\underset{N->+\infty}{lim}\overline{l}=H_(S)
    推导:设L为扩展信源SNS^{N}的平均码长,l=LN\overline{l}=\frac{\overline{L}}{N}为单个信源S的平均码长,根据平均码长界限定理有:
    H(SN)logrL<H(SN)logr+1\frac{H(S^N)}{logr}\leq \overline{L}< \frac{H(S^N)}{logr}+1
    NH(S)logrL<NH(S)logr+1\frac{NH(S)}{logr}\leq \overline{L}< \frac{NH(S)}{logr}+1
    H(S)logrl<H(S)logr+1N\frac{H(S)}{logr}\leq \overline{l}< \frac{H(S)}{logr}+\frac{1} {N}
    (2)定义变长码编码速率R=llogrR=\overline{l}*logr,编码效率η=H(S)R=H(S)nlogr\eta=\frac{H(S)}{R}=\frac{H(S)}{\overline{n}logr}

    展开全文
  • 无失真信源编码实验,包括用C++编写的程序、实验报告、实验指导书。
  • 无失真信源编码定理课程部分讲解ppt和pdf 无失真信源编码定理课程部分讲解ppt和pdf
  • [实验]无失真信源压缩编码

    千次阅读 2018-03-19 20:09:04
    实验一 无失真信源压缩编码此文系后续整理,懒得copy,对应的方法可以根据需要可以直接下载代码,附件:...

    实验一 无失真信源压缩编码


    此文系后续整理,懒得copy,对应的方法可以根据需要可以直接下载代码,附件:

    https://download.csdn.net/download/weixin_40744915/10296130

    https://download.csdn.net/download/weixin_40744915/10296133

    https://download.csdn.net/download/weixin_40744915/10296135

    https://download.csdn.net/download/weixin_40744915/10296154


    目录

    一、实验目的及要求... 1

    二、任务分析及方案选择... 1

    (一)Huffman编码... 1

    (二)游程编码... 1

    (三)算术编码... 2

    (四)字典码... 3

    三、实验原理及过程... 5

    (一)Huffman编码实现信源无失真压缩... 5

    (二)游程编码与Huffman编码结合实现信源无失真压缩... 13

    (三)字典码实现信源无失真压缩... 18

    四、实验结果分析与思考... 20

    (一)Huffman编码实现信源无失真压缩... 20

    (二)游程编码与Huffman编码结合实现信源无失真压缩... 23

    (三)字典码实现信源无失真压缩... 24

    五、实验小结... 27

     


     


    一、实验目的及要求

    1、对文本信源,寻求最佳压缩方案,现完整的无失真压缩的编译码算法,完成对文本文件的压缩及解压。

    2、构建性能分析模块,实现对信源熵的统计、压缩后的传输率(bits/symbol),以及恢复文本的完整情况进行分析。

    二、任务分析及方案选择

    香农第一定理从理论上给出了进行无失真信源压缩的理论极值,并论证了理想最佳信源编码的存在性,也就是说,总能找到某种合适的编码方法使编码后信源的信息传输率任意逼近信源的信息熵而不存在任何失真,这样的无失真信源编码在数据压缩技术中又称为熵编码。典型的代表有霍夫曼编码、游程编码、算术编码和字典码,霍夫曼编码主要适用于多元独立的信源,游程编码和算术编码主要使用与二元信源及具有一定相关性的有记忆信源,字典码针对信源的统计特性未知时有较好的性能。本次实验给定的是一个大小较小、无记忆文本文件,所以Huffman编码是应该一个比较合适的方案,下面具体进行原理分析与比较:

    (一)Huffman编码

    Huffman编码是一种即时码,二元Huffman编码步骤如下:

    (1)将q个信源符号按递减概率排列起来,设

    (2)用0和1码符号分别分配给概率最小的两个信源符号,并将这两个概率最小的信源符号合并成一个新符号,并用这两个最小概率之和作为新符号的概率,从而得打只包含个符号的新信源,作为原信源的缩减信源;

    (3)把缩减信源的符号仍按照概率大小递减排列,再将其最后两个概率最小的符号合并成一个新符号,依次递推,直至缩减信源最后只剩下两个符号为止。将这最后两个符号分别用0和1码表示,最后他们俩的概率之和为1。然后从最后一级缩减信源开始,依照编码路径从后向前返回,就得出各个信源符号所对应的码符号序列,即对应的码字。

    但Huffman编码得到的码并非唯一的,因为每次对缩减信源最后两个概率最小的符号,用0还是1表示可以是任意的,所以可能得到码长相同但码字不同的码;另外当缩减信源中缩减合并后的符号的概率与其他信源符号相同时,概率次序也不一定,所以其Huffman编码并不唯一。但由于平均码长没变,所以有相同的编码效率。

    后续将给出实验(一)中给出具体过程及步骤。

    (二)游程编码

    游程编码又称“运行长度编码”或“行程编码”,是一种统计编码,该编码属于无损压缩编码,是栅格数据压缩的重要编码方法。对于二元信源,其输出只有两个符号,‘0’或‘1’。连续出现‘1’符号或者连续出现‘0’符号的个数称为这一段的游程长度,这个游程长度是一个随机变量,可取值从1……无穷,且‘0’和‘1’游程一定是交替出现的。用自然数标记游程长度的这种映射是可逆的,无失真的,而且游程长度越长以及长游程频繁出现时压缩效率就会越高。

    同样,由于通过游程的映射变换已经减弱了原来二元序列符号间的相关性,并把它变成了多元序列,这样可以在游程编码的基础上进行其他的变长编码方式,就能进一步压缩信源,提高通信效率。当然要首先测定‘0’游程长度和‘1’游程长度的概率分布,即以游程长度为元素,构造一个新的多元信源进行霍夫曼编码,得到不同游程长度映射的码字,就可以将游程序列变换成码字序列,使信源得到进一步压缩。若二元序列的概率特性已知,由于二元序列和映射所得的游程序列是一一对应的,就可以计算出游程序列的概率特性,根据信息熵的定义分别计算‘0’游程长度信源和‘1’游程长度信源的熵,以及平均游程长度,原信源的二元序列是由‘0’游程和‘1’游程交替出现而组成的,所以原二元序列的熵等于两个游程长度信源熵之和除以它们的平均游程长度之和,即游程变换后的信源信息熵没有变,当‘0’游程和‘1’游程的编码效率都很高时,采用游程编码的编码效率也很高。因此要想编码效率尽可能高,应该尽量提高熵值较大的游程的编码效率。

    因此,在后续将给出游程编码和Huffman编码结合的无失真压缩编码,具体在实验(二)中给出具体过程及步骤。

    (三)算术编码

    虽然Huffman编码是最佳码,但是对于二元信源,必须对二元信源的N次扩展信源进行Huffman编码时,才能使得平均码长接近信源的熵,编码效率才高。必须要计算出所有N长信源序列的概率分布,并构造相应的完整的码树,所以较为复杂。算术编码可以无需计算出所有N长信源序列的概率分布及编出码表,可以直接对输入的信源符号序列进行编码输出,对于很长的信源符号序列来说是一个简单有效的编码方法。算术编码的基本原理是将编码的消息表示成实数0和1之间的一个间隔(Interval),消息越长,编码表示它的间隔就越小,表示这一间隔所需的二进制位就越多。

    算术编码用到两个基本的参数:符号的概率和它的编码间隔。信源符号的概率决定压缩编码的效率,也决定编码过程中信源符号的间隔,而这些间隔包含在0到1之间。编码过程中的间隔决定了符号压缩后的输出。

    给定事件序列的算术编码步骤如下:

    (1)编码器在开始时将“当前间隔” [ L, H) 设置为[0,1)。

    (2)对每一事件,编码器按步骤a和b进行处理

    a.编码器将“当前间隔”分为子间隔,每一个事件一个。

    b.个子间隔的大小与下一个将出现的事件的概率成比例,编码器选择子间隔对应于下一个确切发生的事件相对应,并使它成为新的“当前间隔”。

    (3)最后输出的“当前间隔”的下边界就是该给定事件序列的算术编码。

    设Low和High分别表示“当前间隔”的下边界和上边界,CodeRange为编码间隔的长度,LowRange(symbol)和HighRange(symbol)分别代表为了事件symbol分配的初始间隔下边界和上边界。上述过程的实现可用伪代码描述如下:

    set Low to 0

    set High to 1

    while there are inputsymbols do

        take a symbol

        CodeRange = High – Low

        High = Low + CodeRange *HighRange(symbol)

        Low = Low + CodeRange * LowRange(symbol)

    end of while

    output Low

    算术码解码过程用伪代码描述如下:

    get encoded number

    do

        find symbol whose range straddles theencoded number

        output the symbol

        range = symbo.LowValue – symbol.HighValue

        substracti symbol.LowValue from encodednumber

        divide encoded number by range

    until no more symbols

    由于算术编码可以对于输入的信源符号序列不需计算概率,只需要计算累积分布函数即可进行编码输出,因此编码效率很高。当信源符号序列很长时,平均码长接近信源的信源熵。由于算数编码的效率高、编译码速度快,因此在图像压缩等方面有广泛应用,在方案设计部分给出了其实现的伪代码,由于算术编码有关信源符号序列的累积分布函数的计算是将累积分布函数写成二进位的小数,取小数后的l位(若后面有尾数,就进位到第l位)得到的,所以这样根据二进位小数截去位数可能对于精度有一定影响;算术编码也是一种对错误很敏感的编码方法,如果有一位发生错误就会导致整个消息译错,这是算术编码在实际应用中需要考虑的问题。

    (四)字典码

    Huffman编码、游程编码、算术编码都是基于统计思想的编码方法,但当统计参数发生了变化的时候,这种静态的统计编码就会产生性能下降。因此在1980年代提出了自适应或者半自适应的动态方法,对于工程实践中无法测定信源的统计概率或者产生统计失配时,具有较好的性能。1977-1978年由以色列的研究人员Ziv和Lempel提出的,习惯称为LZ码,由于把已经编码的字符串存储作为字典使用,又称为字典码。典型的字典码是上述二人于1977、1978年提出的LZ-77码、LZ-78码,以及1984年由韦尔奇改进的LZW码,随后又出现了对LZ码和LZW码的改进或变形的多种字典码,如LZSS码,LZRW1-4码,LZP1-4码等。这类字典码,编译简捷,易于软件实现,使其得到广泛的应用。LZ码是一种通用编码方法,就是指在信源概率统计特性不知或不存在时,对信源进行编码,而且使编码效率仍为很高的一种码。

    我们先举例说明字典码的思想。设A,B两人约定在用完全相同的字典下互相通信,A将信文中的每个单词用二元标识符(a,b)代替,a,b是表示单词所在字典中的页数和在此页的位置次序,当逐个单词被替代后,就将标识符序列发给B。B收到标识符序列后可按标识符恢复单词和信文。标志符号的个数显然少于单词符号个数,就实现了文本压缩的目的。另外若对字符序列进行压缩编码,其效率要高于对单个字符的压缩。而且字符串越长,平均码长越短。在压缩编码中又常把字符串或字符序列称为数据流。

    LZ-77编码算法的主要思想是把已输入的数据流存储起来,作为字典使用。编码器为输入流开设一个滑动窗口,其长可达几千字节,将输入的数据存在窗内,做字典使用,窗口右侧是待编码数据流的缓存器,长只有几十字节。用三元标识(K,Ɩ,d)给数据编码,K是窗内从尾自又向左搜索的字符位数,称为移位数,Ɩ是窗内可以与窗外有相同符号的字符串的长,称为匹配串长度,d是窗外已找到匹配的串的后面串的首字符。以自然对数2.71828182845为例:

    (1)开始时,窗内是空的,要输入当前位置的2,窗内没有与2匹配的串,故K,Ɩ皆为0,把2编码为(0,0,2),输入2。下面输入的数据为.718也与2的情况相同,窗内只有刚输入的2,没有与.718分别相匹配的串,故只能将.718分别编码为(0,0,.),(0,0,7),(0,0,1),(0,0,8),分别将其输入窗内。

    (2)现窗内已有2.718存入,当前位置是e的小数第4位2,在窗内从尾由右向左搜索到第5位处(包括小数点),有窗内左边的第5个数字2与当前位置2相同,即匹配串长Ɩ为1,当前位置2后面的串的首字符为8,得K=5,Ɩ=1,故编码为(5,1,8),表示窗内字典从右向左第5位有一个长为1的匹配串“2”和当前位置的数据串“2”相匹配,后面串的首字符为8,并将28同时输入。

    (3)现窗内字典为2.71828,当前输入数据为1,编码器在窗内从尾自右向左搜索,移动4位,搜索到长度Ɩ=4的与当前位置相匹配的串:1828,下面串的首位为4,故编码为(4,4,4)。将18284输入窗内;

    (4)由于字典内没有与5,9,0相匹配的串,故均是0移位,0匹配串长的无匹配字符,编码为(0,0,5),(0,0,9),(0,0,0),并将5,9,0输入窗内。

    (5)在窗内搜索到第4位,有“45”与当前位置45匹配,串长Ɩ=2,后续段首字符为2。故编码为(4,2,2)。并又将452输入窗内。以下重复上述步骤,可逐步将数据流编码并输入窗内。所有的标识(K,Ɩ,d)序列就是所得的压缩编码序列。

    LZ-77码的译码器要有一个与编码器字典窗口等长的缓存器,可以边译码,边建立译码字典,即编码字典不用传送,译码器可自动生成。这种码隐含了假设条件:输入数据产生模式是相距很近的。

    因此,在后续将字典码的无失真压缩编码,具体在实验(三)中给出具体过程及步骤。

    三、实验原理及过程

    (一)Huffman编码实现信源无失真压缩

    1、构建Huffman编码树的过程:

    (1)创建n个初始化的Huffman树,每个树只包含单一的叶节点,叶节点纪录对应的字母和该字母出现的频率(weight);

    (2)按照weight从小到大对其进行所有的Huffman树进行排序,取出其中weight最小的两棵树,构造一个新的Huffman树,新的Huffman树的weight等于两棵子树的weight之和,然后再加入到原来的Huffman树数组当中;

    (3)反复上面的2中的操作,直到该数组当中只剩下一棵Huffman树,那么最后剩下来的那棵Huffman树就是我们构造好的Huffman编码树;

    2、文本压缩过程:

    (1)对需要被压缩的文件以二进制方式读入,然后以byte为单位读取里面的值,然后将其转为int值,一共有[0~255]共256个值,遍历文件所有的byte,统计出现每个值的次数,作为后面叶子节点的权重(weight);

    (2)使用上面统计的每个字符对应的权重,构造对应的Huffman编码树,然后分配每个字符对应的Huffman编码;

    (3)在压缩文件的开始处,将每个字符及其对应的权重(weight)以二进制的方式保存到压缩文件中去,这样在对压缩文件解压是就可以根据源文件中每个字符出现的频率去构造相应的Huffman树,便于对压缩文件进行解压缩的操作;

    (4)遍历文件的每一个byte,然后以步骤(2)中生成的Huffman编码,将该字节替换为编码后对应的01组合;

    (5)将步骤(4)中生成的编码后的字符串,每8位作为一个单位,转为相应的byte,然后以二进制的方式写入到压缩文件中;

    python实现如下:

    def compress(inputfilename,outputfilename):

        """

        压缩文件,参数有

        inputfilename:被压缩的文件的地址和名字

        outputfilename:压缩文件的存放地址和名字

        """

        #1. 以二进制的方式打开文件

        f = open(inputfilename,'rb')

        filedata = f.read()

        # 获取文件的字节总数

        filesize = f.tell()

        print('原文件大小为:%d' % filesize)

     

        # 2. 统计 byte的取值[0-255] 的每个值出现的频率

        # 保存在字典 char_freq中

        char_freq = {}

        for x in range(filesize):

            tem = filedata[x]

            if tem in char_freq.keys():

                char_freq[tem] = char_freq[tem] + 1

            else:

                char_freq[tem] = 1

     

        # 3. 开始构造原始的huffman编码树 数组,用于构造Huffman编码树

        list_hufftrees = []

        for x in char_freq.keys():

            # 使用 HuffTree的构造函数 定义一棵只包含一个叶节点的Huffman树

            tem = HuffTree(0, x, char_freq[x],None, None)

            # 将其添加到数组 list_hufftrees 当中

            list_hufftrees.append(tem)

     

        # 4. 步骤2中获取到的 每个值出现的频率的信息

        # 4.1. 保存叶节点的个数

        length = len(char_freq.keys())

        output = open(outputfilename, 'wb')

     

        # 一个int型的数有四个字节,所以将其分成四个字节写入到输出文件当中

        a4 = length&255

        length = length>>8

        a3 = length&255

        length = length>>8

        a2 = length&255

        length = length>>8

        a1 = length&255

        output.write(six.int2byte(a1))

        output.write(six.int2byte(a2))

        output.write(six.int2byte(a3))

        output.write(six.int2byte(a4))

     

        # 4.2 每个值 及其出现的频率的信息

        # 遍历字典 char_freq

        for x in char_freq.keys():

            output.write(six.int2byte(x))

            #

            temp = char_freq[x]

            # 同样出现的次数 是int型,分成四个字节写入到压缩文件当中

            a4 = temp&255

            temp = temp>>8

            a3 = temp&255

            temp = temp>>8

            a2 = temp&255

            temp = temp>>8

            a1 = temp&255

            output.write(six.int2byte(a1))

            output.write(six.int2byte(a2))

            output.write(six.int2byte(a3))

            output.write(six.int2byte(a4))

       

        # 5. 构造huffman编码树,并且获取到每个字符对应的 编码

        tem = buildHuffmanTree(list_hufftrees)

        value =tem.traverse_huffman_tree(tem.get_root(),'',char_freq)

     

        freq_percent = []

        code_len = []

        for i in range(0, len(value), 3):

           freq_percent.append(value[i+1]/float(filesize))

            code_len.append(len(value[i+2]))

       

        # 计算平均码长

        sum_code_len = sum(np.array(freq_percent) *np.array(code_len))

        print('平均码长:',sum_code_len)

     

        # 计算信源熵

        info_entropy = sum([x*-math.log(x,2) for xin freq_percent])

        print('信源熵:',info_entropy,'bits/symbol')

     

        # 计算编码效率

        #code_eff = info_entropy/sum_code_len

        #print('编码效率:',code_eff)

        # print(tem)

        # time.sleep(1000)

       

        # 6. 开始对文件进行压缩

        code = ''

        for i in range(filesize):

            key = filedata[i]

            code = code + char_freq[key]

            out = 0

            while len(code)>8:

                for x in range(8):

                    out = out<<1

                    if code[x] == '1':

                        out = out|1

                code = code[8:]

                output.write(six.int2byte(out))

                out = 0

     

        # 处理剩下来的不满8位的code

        output.write(six.int2byte(len(code)))

        out = 0

        for i in range(len(code)):

            out = out<<1

            if code[i]=='1':

                out = out|1

        for i in range(8-len(code)):

            out = out<<1

        # 把最后一位给写入到文件当中

        output.write(six.int2byte(out))

     

        # 6. 关闭输出文件,文件压缩完毕

        output.close()

    3、文本解压缩过程:

    (1)以二进制读的方式,独处压缩文件中保存的被压缩文件中的每个值出现的频率

    (2)使用每个值及其对应的权重,构造对应的Huffman编码树,然后分配每一个字符对应的Huffman编码;

    (3)接着以二进制的方式读取压缩文件的内容;

    (4)使用步骤(3)中读取出来的压缩后的字符串还原Huffman编码树进行解压缩:

    a.初始指针指向编码树的根节点root;

    b.循环取出压缩文件中的字符串,如果值为0,则为父节点的左孩子;如果值为1,则为父节点的右孩子;

    c.判断指针所指向的是否是叶子节点。如果是叶子节点,则将该叶子节点对应的字符写入解压缩文件中,并将指针重置为编码树的root节点;如果不是叶子节点,继续循环步骤b;

    d.直至压缩文件中的字符被取完,此时解压缩工作完毕,解压缩文件中已经均为对应的解码字符。

    python实现如下:

    defdecompress(inputfilename, outputfilename):

        """

        解压缩文件,参数有

        inputfilename:压缩文件的地址和名字

        outputfilename:解压缩文件的存放地址和名字

        """

        # 读取文件

        f = open(inputfilename, 'rb')

        filedata = f.read()

        #print(filedata)

        # 获取文件的字节总数

        cf_filesize = f.tell()

        print('压缩文件大小:%d'% cf_filesize)

     

        # 1. 读取压缩文件中保存的树的叶节点的个数

        # 一下读取 4个 字节,代表一个int型的值

        a1 = filedata[0]

        a2 = filedata[1]

        a3 = filedata[2]

        a4 = filedata[3]

        j = 0

        j = j | a1

        j = j << 8

        j = j | a2

        j = j << 8

        j = j | a3

        j = j << 8

        j = j | a4

     

        leaf_node_size = j

     

     

        # 2. 读取压缩文件中保存的相信的原文件中 [0-255]出现的频率的信息

        # 构造一个 字典 char_freq 一遍重建 Huffman编码树

        char_freq = {}

        for i in range(leaf_node_size):

            c = filedata[4 + i * 5 + 0]

     

            # 同样的,出现的频率是int型的,读区四个字节来读取到正确的数值

            a1 = filedata[4 + i * 5 + 1]

            a2 = filedata[4 + i * 5 + 2]

            a3 = filedata[4 + i * 5 + 3]

            a4 = filedata[4 + i * 5 + 4]

            j = 0

            j = j | a1

            j = j << 8

            j = j | a2

            j = j << 8

            j = j | a3

            j = j << 8

            j = j | a4

     

            char_freq[c] = j

     

        # 3. 重建huffman 编码树,和压缩文件中建立Huffman编码树的方法一致

        list_hufftrees = []

        for x in char_freq.keys():

            tem = HuffTree(0, x, char_freq[x],None, None)

            list_hufftrees.append(tem)

     

        tem = buildHuffmanTree(list_hufftrees)

        tem.traverse_huffman_tree(tem.get_root(),'', char_freq)

     

        # 4. 使用步骤3中重建的huffman编码树,对压缩文件进行解压缩

        output = open(outputfilename, 'wb')

        code = ''

        currnode = tem.get_root()

        for x in range(leaf_node_size * 5 + 4,cf_filesize):

            c = filedata[x]

            # c = six.byte2int(filedata[x])

            for i in range(8):

                if c & 128:

                    code = code + '1'

                else:

                    code = code + '0'

                c = c << 1

     

            while len(code) > 24:

                if currnode.isleaf():

                    tem_byte = six.int2byte(currnode.get_value())

                    output.write(tem_byte)

                    currnode = tem.get_root()

     

                if code[0] == '1':

                    currnode = currnode.get_right()

                else:

                    currnode = currnode.get_left()

                code = code[1:]

     

        # 4.1 处理最后 24位

        sub_code = code[-16:-8]

        last_length = 0

        for i in range(8):

            last_length = last_length << 1

            if sub_code[i] == '1':

                last_length = last_length | 1

     

        code = code[:-16] + code[-8:-8 +last_length]

     

        while len(code) > 0:

            if currnode.isleaf():

                tem_byte =six.int2byte(currnode.get_value())

                output.write(tem_byte)

                currnode = tem.get_root()

     

            if code[0] == '1':

                currnode = currnode.get_right()

            else:

                currnode = currnode.get_left()

            code = code[1:]

     

        if currnode.isleaf():

            tem_byte =six.int2byte(currnode.get_value())

            output.write(tem_byte)

            currnode = tem.get_root()

     

        # 4. 关闭文件,解压缩完毕

        output.close()

        # 读取文件

        f = open(outputfilename, 'rb')

        filedata = f.read()

        #print(filedata)

        # 获取文件的字节总数

        df_filesize = f.tell()+4

        print('解压缩文件大小:%d'% df_filesize)

        f.close()

     

        result = cf_filesize / df_filesize

        print('压缩率为:%f' % result )

    (二)游程编码与Huffman编码结合实现信源无失真压缩

    编程思想:通过游程的映射变换已经减弱了原来二元序列符号间的相关性,并把它变成了多元序列,这样可以在游程编码的基础上进行Huffman编码,进一步压缩信源,提高通信效率。所以,在实现过程中,先对原文件进行游程编码,并存放在中间文件中,然后对得到的游程长度文件进行Huffman编码。

    实现如下:

    while(!feof(ifp))//将游程编码写进中间文件

        {

            fread(&ch2,1,1,ifp);

            if(ch2==ch1)

                count++;

            else

            {

                if(count>=3)

                {

                    fwrite(&ch,1,1,ofp1);

                    fwrite(&ch1,1,1,ofp1);

                    fwrite(&count,1,1,ofp1);

                }

                else

                {

                    if(count==1)

                        fwrite(&ch1,1,1,ofp1);

                    else if(count==2)

                    {

                        fwrite(&ch1,1,1,ofp1);

                        fwrite(&ch1,1,1,ofp1);

                    }

     

                }

                ch1=ch2;

                count=1;

            }

            filelength++;

            if(filelength==Filelength)

                break;

        }

        if(count>=3)

        {

            fwrite(&ch,1,1,ofp1);

            fwrite(&ch1,1,1,ofp1);

            fwrite(&count,1,1,ofp1);

        }

        else

        {

            if(count==1)

                fwrite(&ch1,1,1,ofp1);

            else if(count==2)

            {

                fwrite(&ch1,1,1,ofp1);

                fwrite(&ch1,1,1,ofp1);

            }

        }

        fclose(ifp);

        fclose(ofp1);

       ofp1=fopen("C:\\Users\\Administrator\\Documents\\pythonexercise\\untitled\\c\\combined\\combined\\combined\\1.txt","rb");

        Filelength=0;//Filelength为中间文件的字节长度

        while(!feof(ofp1))

        {

            fread(&c,1,1,ofp1);

            huffmannode[c].weight++;

            Filelength++;

        }

        Filelength=Filelength-1;

        huffmannode[c].weight--;//结点下标为ASCII码值

        n=0;

        for(i=0;i<256;i++)

            if(huffmannode[i].weight!=0)

        {

            huffmannode[i].ch=(unsigned char)i;

            n++;//n表示字符出现的种类数

           huffmannode[i].lchild=huffmannode[i].rchild=huffmannode[i].parent=-1;

        }

        m=2*n-1;//哈弗曼树结点总数

        j=0;

        for(i=0;i<256;i++)

            if(huffmannode[i].weight!=0)

        {

            huffmannode[j]=huffmannode[i];

            j++;

        }

        for(i=n;i<m;i++)

           huffmannode[i].lchild=huffmannode[i].rchild=huffmannode[i].parent=-1;

        for(i=n;i<m;i++)

        {

            s1=select(huffmannode,i-1);

            huffmannode[i].lchild=s1;

            huffmannode[s1].parent=i;

            s2=select(huffmannode,i-1);

            huffmannode[i].rchild=s2;

            huffmannode[s2].parent=i;

           huffmannode[i].weight=huffmannode[s1].weight+huffmannode[s2].weight;

        }

        coding(huffmannode,n);

        fseek(ofp1,0,SEEK_SET);

        fwrite(&Filelength,4,1,ofp);//将源文件长度写入目标文件,以便解压

        fseek(ofp,8,SEEK_SET);

        codes[0]=0;

        filelength=0;

        while(!feof(ofp1))//将中间文件每个字符的编码所对应的字符写入目标文件

        {

            filelength++;

            fread(&c,1,1,ofp1);

            for(i=0;i<n;i++)

                if(c==huffmannode[i].ch)break;

            strcat(codes,huffmannode[i].code);

            while(strlen(codes)>=8)

            {

                for(i=0;i<8;i++)

                {

                    if(codes[i]=='1')

                        c=(c<<1)|1;

                    else

                        c=c<<1;

                }

                fwrite(&c,1,1,ofp);

                lengenth++;

                strcpy(codes,codes+8);

            }

     

            if(filelength==Filelength)

                break;

        }

        if(strlen(codes)>0)//最后有多余的编码补0

        {

            strcat(codes,"00000000");

            for(i=0;i<8;i++)

            {

                if(codes[i]=='1')

                    ch1=(ch1<<1)|1;

                else

                    ch1=ch1<<1;

            }

            fwrite(&ch1,1,1,ofp);

            lengenth++;

        }

           // lengenth代表源文件的字符的编码所对应的字符个数,源文件编码区的字符个数

        lengenth=lengenth+8;

        fseek(ofp,4,SEEK_SET);

        fwrite(&lengenth,4,1,ofp);

        fseek(ofp,lengenth,SEEK_SET);

        fwrite(&n,4,1,ofp);//n代表哈弗曼叶子总数

        count=0;

        for(i=0;i<n;i++)

        {

           fwrite(&(huffmannode[i].ch),1,1,ofp);

                  //把哈弗曼叶子结点所带的字符写进目标文件

            ch1=huffmannode[i].Length;

            fwrite(&ch1,1,1,ofp);//把哈弗曼叶子结点所带字符的编码位数写进目标文件

            if(huffmannode[i].Length%8!=0)

               for(j=huffmannode[i].Length%8;j<8;j++)

               strcat(huffmannode[i].code,"0");

            while(huffmannode[i].code[0]!=0)

            {

                ch1=0;

                for(j=0;j<8;j++)

                {

                    if(huffmannode[i].code[j]=='1')

                        c=(c<<1)|1;

                    else

                        c=c<<1;

                }

                strcpy(huffmannode[i].code,huffmannode[i].code+8);

                count++;

                fwrite(&c,1,1,ofp);

                         //把哈弗曼结点所带的字符的编码所对应的字符写入目标文件

            }

        }

    (三)字典码实现信源无失真压缩

    编程思想:LZ77算法的主要思路是构造一个三元组(off, len, c),其中off表示窗口中匹配的字符串相对于窗口右边界的位移,len表示可以进行匹配的字符串的长度,c表示需要下一个输出的字符。对一串已经储存在文本中的字符串进行LZ77编码,将三元组输出到一个编码文件中,最后只要我们向压缩时那样维护好滑动的窗口,随着三元组的不断输入,我们在窗口中找到相应的匹配串,缀上后继字符 c 输出(如果 off和 len 都为 0 则只输出后继字符c即可还原出原始数据,同样的,将解码后的字符串也输出到一个文本中。

    //字符串的匹配

    int match(char *s,intsn,char *t,int tn)

    {

        int i=0,j=0,k;

        while(i<sn&&j<tn)

        {

            if(s[i]==t[j])

            {

                i++;

                j++;

            }

            else

            {

                i=i-j+1;

                j=0;

            }

        }

        if(j>=tn)

            k=i-tn;

        else k=-1;              //k是可以匹配的字符串的位置

        return k;

    }

     

    void code(char *array,intcount1,CODE *code_file,int *pcount2)

    {

        int window_start=0,window_end=0;

        *pcount2=0;

        if(count1>0)

        {

            code_file[0].off=0;

            code_file[0].len=0;

            code_file[0].c=array[0];

            (*pcount2)++;        //对字符串第一个字符进行编码输出

        }

        int i=1,j=1,k1=0,k2=0;

        for(;i<count1;i++)

        {

            if(i<window_length)

                window_end=i;      //更新窗口右边界

            else window_end=window_length;

            for(j=1,k1=0,k2=0;;j++)

            {

                k1=k2;

                k2=match(array+i-window_end,window_end,array+i,j);     //匹配结果返回

                if(k2<0)  //没有匹配的

                {

                   code_file[*pcount2].off=window_end-k1;

                                //存在可以编码的情况的话,off值为当前字符相对于右窗口的位移

                   if((code_file[*pcount2].len=j-1)==0)

                                //在出现新字符的情况下,将off置为0

                        code_file[*pcount2].off=0;

                   code_file[*pcount2].c=array[i+j-1];

                                //输出需要输出的下一位不能匹配的字符

                    (*pcount2)++;//指针移动

                    i=i+j-1;//更新i

                    break;

                }

            }

        }

    }

     

    void decode(CODE*code_file,int count2,char *array,int *pcount3)

    {

        *pcount3=0;

        int i=0,j=0;

        for(;i<count2;++i)

        {

            if(code_file[i].len==0)

            {

                array[*pcount3]=code_file[i].c;

                ++(*pcount3);

            }

            else

            {

                for(j=0;j<code_file[i].len;++j)

                {

                   array[*pcount3+j]=array[*pcount3-code_file[i].off+j];

                }

                array[*pcount3+j]=code_file[i].c;

                *pcount3=*pcount3+code_file[i].len+1;

            }

        }

    }

    四、实验结果分析与思考

    (一)Huffman编码实现信源无失真压缩

    实验结果如下:

    图1 Huffman编码的python实现(test1.txt)

    图2 Huffman编码的python实现(test2.txt)

    由实验结果可知,Huffman编码的信源熵接近于平均码长,对于只有英文字符的test1.txt文件的压缩效果要比既包含中文字符又包含英文字符的test2.txt文件好,英文字符较少,Huffman编码后的平均码长也较短。从运行效果上来看,压缩的比例不是非常满意,压缩率很低,对于test1.txt文件的压缩节省了约43%的存储空间,压缩比达到了1.75倍;但是对于中文字符和英文字符共存的test2.txt文件,只节省了5%的存储空间,压缩比也很低。Huffman编码对于中文的压缩是将一个中文字符分化为两个ASCII编码,于是本质上就将中文压缩转化为单字节的压缩算法,算法从物理上割裂了中文编码蕴含的语义信息,压缩效率上有一定的降低。但是这种将汉字重新形成基于“中文字符”的Huffman压缩算法利于实现,在解压缩的完整性上也有一定的优点,还是具有一定的可观性。

    在此次压缩算法的实现过程中,遇到过不少难题。由于Huffman编码在压缩文件中存储的编码信息为各个字符的频率信息和编码信息,在解码的时候对于相同频率的字符出现时,如果没有按照与压缩时按照相同的顺序排列,会在译码时出现一定的错误;发现其中一个字符与文件结尾表示EOF有相同的编码,导致解码过程不稳定,出现一些小问题。如下图所示,如果在解码过程中不加以保证相同频率字符的排序时,相同频率的字符可能会在解码出现解码错误。

    图3 解压缩未正确排序结果

     

    4 错误原因

    4 原则上,该程序可以对任意格式的文件进行压缩,如jpg图像,如下图所示:

    图5图像压缩与解压缩效果

    压缩效果却并不理想,如下图所示:

    图6图像压缩与解压缩性能

    思考:应该可以采用动态哈夫曼树的编码来对大文件的压缩进行优化,从而达到更优的压缩率。确定一个初始哈夫曼树,然后根据当前处理过的字符动态的调整哈夫曼树的结构,解压过程同样根据解压过的字符调整哈夫曼树结构。压缩与解压的时间效率有待提高,本程序在压缩及解压过程中对硬盘进行了大量的读写,使速度受到影响,可以通过缓冲带还实现提速,即构造内存缓冲区,每次读写多个字符,既而进行处理。

    (二)游程编码与Huffman编码结合实现信源无失真压缩

    实验结果如下:

    图7游程编码+ Huffman编码的无失真信源压缩编码实现(test1.txt)

    图8游程编码+ Huffman编码的无失真信源压缩编码实现(test2.txt)

    经过游程编码后再进行Huffman编码的压缩效果比只进行Huffman编码的效果略好,因为文件中还是有很多字符的出现频率为1,2的字符,他们的码长可以达到13位,连续的‘0’字符和‘1’字符长度可以达到4或5,经过游程编码后降为3位,有所降低但压缩效果也没有特别明显,只比单纯的Huffman编码略好一点。

    (三)字典码实现信源无失真压缩

    实验结果如下:

    图9基于字典码的无失真信源压缩编码(test1.txt)

    图10基于字典码的无失真信源压缩编码(test2.txt)

    由实验结果可知,基于字典码的无失真信源压缩编码比Huffman编码和游程编码+Huffman编码的效果要好很多,压缩性能提升了一倍。字典码不依赖于信源的概率分布,也不必知道有关信源的统计特性,编码方法简单,又能达到很高的压缩编码效率,python的zlib函数库就是使用的LZ77的一种变种,性能也非常好。

    图11 python中zlib函数对文本压缩效果

    下表对实验中用到的Huffman编码、游程编码+Huffman编码、字典码和zlib编码性能进行了对比,可以发现字典码的效果最好,但不管哪种方法,中文文本的压缩效果都不如英文文本的压缩效果好,主要原因是一个中文字符相当于2个ASCII编码,于是本质上就将中文压缩转化为单字节的压缩算法,算法从物理上割裂了中文编码蕴含的语义信息,压缩效率上有一定的降低。如果想要得到较好的中文文本压缩效果,需要利用好中文文本中数据编码和汉字大字符的特点,以提高中文文本中重复字符串不长导致的压缩比远低于英文文本的缺点。

    表1 无失真信源压缩编码性能对比

     

    test1文件压缩率

    test2文件压缩率

    Huffman编码

    1.759605

    1.054758

    游程编码+Huffman编码

    1.78

    1.11

    字典码

    2.90833

    2.0583

    zlib编码

    2.486436

    1.586691

    图12无失真信源压缩编码性能对比

    查阅文献,发现可以从以下几个方面改进字典码对于中文文本的压缩效果:

    1、直接以汉字字符进行读取,而不对读取的编码进行重编码,不破坏汉字本来所蕴含的语义信息。

    2、动态自适应编码输出长度,使编码输出长度岁字典长度增大而增大。字典越大,字典中的长字符串会越多,字典对于文本的自适应性增强,压缩效果应该会提高。

    3、重建字典,程序开始压缩时记录输入字节数和输出字节数,程序每压缩一定数量的字节,统计一次压缩率,如果新的压缩率比旧的压缩率大则重建字典,否则,将新的压缩率赋值给旧的压缩率。

    另外,斯坦福大学的研究者在刚提交的论文中提出,循环神经网络捕捉长期以来关系的优势可以被用于文件的无损压缩任务中。J. Rissanen 提出了算术编码,这是一个实现已知分布熵边界的有效方法。对于未知分布的数据源(如文本和 DNA),他还设计了算术编码的自适应变体,它可以通过尝试学习条件 k-gram 模型的分布来进行压缩。尽管这种过程的复杂度会随 k 的变化而呈指数级增长,通常上下文会被限制在 k=20 符号。这会导致压缩比例的显著损失,因为模型无法捕捉长期依赖关系。

    我们都知道基于循环神经网络的模型善于捕捉长期依赖关系,同时可以较准确地预测下一个字母/单词,在这一研究的论文中,研究人员首先分析和理解了已知熵情况下,合成数据集上 RNN 和算术编码方法的表现,其目的是对各种 RNN 结构的能力和极限进行直观的理解。然后设计了压缩器 DeepZip,包含两个主要模块:基于 RNN 的概率评估器和算术编码模块,具体的实现参见https://web.stanford.edu/class/cs224n/reports/2761006.pdf一文。基于对此前在合成数据集上测试的经验,研究人员使用了文本压缩模型和基因组数据集,包含 128 个单元的 DeepZip 模型压缩效果很好。

    图 7 包含 128 个单元的 DeepZip 模型与 GZIP、适应性算术编码-CABAC 的表现对比

    图 8 包含 128 个单元的 DeepZip 模型在实际数据集上的表现

    五、实验小结

    对实验中用到的Huffman编码、游程编码+Huffman编码、字典码和zlib编码性能进行了对比,可以发现字典码的效果最好,但不管哪种方法,中文文本的压缩效果都不如英文文本的压缩效果好,主要原因是一个中文字符相当于2个ASCII编码,于是本质上就将中文压缩转化为单字节的压缩算法,算法从物理上割裂了中文编码蕴含的语义信息,压缩效率上有一定的降低。如果想要得到较好的中文文本压缩效果,需要利用好中文文本中数据编码和汉字大字符的特点,以提高中文文本中重复字符串不长导致的压缩比远低于英文文本的缺点,并给出了几点改进意见。


    展开全文
  • 无失真信源编码 单义可译码 码字非奇异,码字序列非奇异。 单义可译定理——克拉夫不等式 非延长码(即时码,在无失真信源编码中,常采用此码) 延长码:部分码字是其它码字的前缀。100是10的延长码,01就不是001...

    无失真信源编码

    单义可译码

    码字非奇异,码字序列非奇异。

    在这里插入图片描述

    单义可译定理——克拉夫不等式

    在这里插入图片描述

    非延长码(即时码,在无失真信源编码中,常采用此码)

    延长码:部分码字是其它码字的前缀。100是10的延长码,01就不是001的延长码。接收端接收到一个完整的码字后,不能立即译码,还需要等待下一个码字开始接收后才能判断是否译码。

    非延长码一定是单义可译的

    单义可译的不一定是非延长码

    平均码长

    在这里插入图片描述

    码率

    在这里插入图片描述

    平均码长界定定理

    在这里插入图片描述
    在这里插入图片描述

    香农第一定理

    无记忆

    在这里插入图片描述

    有记忆

    在这里插入图片描述

    在这里插入图片描述

    霍夫曼编码(计算题)(最佳码)

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    r元霍夫曼码

    在这里插入图片描述

    编码效率(平均码长)

    在这里插入图片描述

    展开全文
  • PAGE PAGE I 毕业论文基本要求 1毕业论文的撰写应结合专业学习选取具有创新价值和实践意义的论题 2论文篇幅一般为8000字以上最多不超过15000字 3论文应观点明确中心突出论据充分数据可靠层次分明逻辑清楚文字流畅...
  • 无失真变长编码及其 MATLAB实现 我最近阅读了一篇关于无失真变长编码的期刊文献 通过阅读这篇文章我学到了更多关 于信源编码的知识以及几种编码方法的 MATLAB实现过程 这篇文章主要介绍了无失真变长编码的两种编码...
  • 信源编码与信道编码

    2016-04-25 23:31:00
    具体而言就是针对信源输出符号序列的统计特性来寻找某种方法,把信源输出符号序列变换为最短的码字序列,使后者的各码元所荷载的平均信息量最大,同时又能保证无失真的恢复原来的符号序列。 2.信道编码的作用与内含...

    1.信源编码的作用与内含:

      信源编码是一种以提高通信有效性而对信源符号进行的变换,或者说为了减少或者消除信源剩余度而进行的信源符号变换。具体而言就是针对信源输出符号序列的统计特性来寻找某种方法,把信源输出符号序列变换为最短的码字序列,使后者的各码元所荷载的平均信息量最大,同时又能保证无失真的恢复原来的符号序列。

    2.信道编码的作用与内含:

      信道编码:由于信道有噪声和干扰或信道有某种约束会使接受的消息发生差错,因此要通过信道编码来提高传输可靠性。因为信道编码是通过冗余符号来实现的,所以会使传输有效性降低。(ps:香农第二定理:只要信息传输速率不大于信道容量,就存在高可靠性传输。)

     

    转载于:https://www.cnblogs.com/liugl7/p/5433267.html

    展开全文
  • 具体说,就是针对信源输出符号序列的统计特性来寻找某种方法,把信源输出符号序列变换为短的码字序列,使后者的各码元所载荷的平均信息量,同时又能保证无失真地恢复原来的符号序列。信源编码。对信源输出的信号进行...
  • 无失真信源编码理论是信息论的理论基础,主要运用在离散信源或数字信号的研究,如文本、表格及工程图纸等信源,对其进行无失真地数据压缩,且完全能够无失真地可逆恢复。 本文首先在于讲述无失真信源编码的运用...
  • 第五章信源编码(一)

    千次阅读 2016-10-20 22:42:56
     无失真编码  香农码、费诺码和哈夫曼码  限失真信源编码定理  常用的信源编码方法  无失真  游程编码、算术编码  限失真  量化、预测和变换编码  三大极限定理  无失真...
  • 信源编码是一种以提高通信...具体说,就是针对信源输出符号序列的统计特性来寻找某种方法,把信源输出符号序列变换为最短的码字序列,使后者的各码元所载荷的平均信息量最大,同时又能保证无失真地恢复原来的符号序列。
  • 内容包含基本概念,信息度量,信道,信源无失真编码
  • 在上—讲中我们讲过,数据压缩可分为无失真压缩和有 失真压缩两大类,采用无失真编码压缩过的数据可以原原本 本地恢复出来,也就是说,解压缩得到的数据与原始数据完全 相同。由于无失真编码方法的这一特性使其在...
  • 具体说,就是针对信源输出符号序列的统计特性来寻找某种方法,把信源输出符号序列变换为最短的码字序列,使后者的各码元所载荷的平均信息量最大,同时又能保证无失真地恢复原来的符号序列。  一、数字电视的信源...
  • 信息论与编码

    2019-02-24 14:59:37
    本书全面地介绍了Shannon信息论的基本理论:信息的统计度量、Shannon三大编码定理以及对应的三类编码无失真信源编码、限失真信源编码及信道编码。全书共分7章,主要内容包括绪论,信源信源熵,无失真信源编码、限...
  • 信息论基础教材习题答案 第2章 信息的度量 第3章 离散信源无失真编码第4章 离散信道的信道容量
  • 霍夫曼编码及香农编码信源编码主要可分为无失真信源编码和限失真信源编码无失真信源编码主要适用于离散信源或数字信号,如文本、表格及工程图纸等信源,它们要求进行无失真地数据压缩,要求完全能够无失真地可逆...
  • 主要内容包括信息的基本概念、离散信源及其测度、离散信道及其信道容量、波形信源和波形信道、无失真信源编码定理、有噪信道编码定理、保真度准则下的信源编码无失真信源编码等。仅供复习参考。
  • 内容 课时 第一章:信息论与信息论方法概述 5 第二章:预备知识 5 ...第四章:无失真信源编码 5 第五章:信道与信道容量 10 第六章:信道编码 5 第七章:率失真函数与信源失真编码 5 复习考试 10
  • 内容 课时 第一章:信息论与信息论方法概述 5 第二章:预备知识 5 ...第四章:无失真信源编码 5 第五章:信道与信道容量 10 第六章:信道编码 5 第七章:率失真函数与信源失真编码 5 复习考试 10
  • C语言实现香农编码

    2013-06-25 12:52:59
    信息论奠基人——香农,他给出了香农三大定理:无失真信源编码定理,信道编码定理,限失真的信源编码定理。信源编码的研究落后于信道编码无失真信源编码定理由香农在1948年给出,并有相应的香农编码。1952年,...
  • 第二章 信源信源熵 第三章 无失真信源编码 第四章 限失真信源编码 第五章 信道编码
  • 算术编码与LZ编码 第九讲 算术编码 前面所讨论的无失真编码,都是建立在信源符号与码字一一对应的基础上,这种编码方法通常称为块码或分组码,此时信源符号一般是多元的。 如果要对二元序列进行编码,则需采用合并...
  • huffman编码

    千次阅读 2018-05-15 13:29:21
    实验原理1.Huffman编码1)HuffmanCoding(霍夫曼编码)是一种无失真编码的编码方式,Huffman编码是可编长编码(VLC)的一种。 2)Huffman编码基于信源的概率统计模型,它的基本思路是:出现概率大的信源符号编短码,...
  • 本课程主要讲解香农信息论的基本理论、基本概念和基本方法,以及编码的理论和实现原理。 介绍信息的统计度量,离散信源,离散信道和信道容量;...然后介绍无失真信源编码、限失真信源编码,以及信道编码等。
  • 全书分7章,在介绍了有关信息度量的基础上,重点讨论了信道容量、率失真函数,以及无失真信源编码、限失真信源编码、信道编码和密码学中的理论知识及其实现原理在各章的最后还附有内容小结和大量习题,书后附有部分...
  • 编码后可无失真还原信源信息 熵编码是利用信息的统计冗余进行数据压缩的无损编码方法 利用信源符号的概率特性,使编码后的信息尽可能接近信源的熵 H.264码流结构(如NAL Unit、Slice Header等)的解析中,大多使用定...
  • MATLAB实现霍夫曼编码

    2017-12-26 19:41:43
    本文介绍了无失真编码算法的构造,霍夫曼编码的规则和特点,同时分析了对信源进行优化的方法,最后通过MATLAB仿真来讨论比较二元霍夫曼编码、三元霍夫曼编码以及信源扩展编码的效率,来实现霍夫曼码的优化构造。

空空如也

空空如也

1 2 3 4 5
收藏数 97
精华内容 38
关键字:

信源无失真编码