精华内容
下载资源
问答
  • 哈夫曼编码实现图像压缩,是自己整理的讲稿,希望对大家有用
  • 哈夫曼编码压缩图像

    千次阅读 2020-06-15 10:09:47
    最近在上图像处理的课,要完成的一些作业就顺便分享到这上面来了。本来是编辑好了,就贴代码就好了,但由于新手操作,一放代码就出问题导致心态崩了。所以就不讲原理了,试试看代码怎么放吧。真的难受,我打了这么多...

    最近在学相关的东西,本来是编辑好了贴代码就行了,但由于新手操作,一放代码就出问题导致心态崩了。所以就不讲原理了,试试看代码怎么放吧。枯了。

    原理就看下图吧。(感觉变糊了)
    在这里插入图片描述

    代码思路大概就是,我认为只有出现在最后两位最小的概率值需要加码字0或者1。所以就可以正向直接求每一个概率值的码字。比如说第一个概率a1,排序后判断是否是最后一个,是的话就加一个码字0;如果是倒数第二个,就加码字1;如果两种情况都不是,就保持码字不变。

    值得注意的是代码中出现的(find(S(j,:)==loc)==L)、(find(S(j,:)==loc)==L-1)其实是想要找到当前求的概率的位置,其实就是想要实现(find(ai)==L-1)。但是由于每次最后两个概率相加之后都要重新排序,所以a1的位置不可能总是在第一个(即ai不可能总是在第i个),所以每次排序都要记下排序前ai的位置loc(第一次排序的位置就是i),然后根据这个loc来判断下一次排序后ai的位置是否在最后两个。

    loc:第一次排序时是i,因为哈夫曼编码先将概率从大到小排序;当不是第一次时,就是上一次排序的位置

    find(S(j,:)==loc):S保存的是每次排序前的位置,所以这一命令可以找到排序后,即当前该概率值ai的位置

    find(S(j,:)==loc)==L:判断是否在最后一个

    下面就是写的代码(尝试了几次,不知道怎么办我就只能贴图了):

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

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

    展开全文
  • 2 用于图像压缩,可根据图像的像素直方图来进行图像压缩,如PNG格式图像压缩使用的算法就包括哈夫曼编码,在编码过程中并未舍弃信息故哈夫曼编码是一种无损压缩方式。 3.哈夫曼解码 即给定由哈夫曼编码的结果10 11 ...

    图一

    1.基本概念

    • (1).路径:一棵树中,从一个结点到另一个结点所经过的所有结点,称为两个结点之间的路径,如上图,GB的路径为G->F->B
    • (2).路径长度:从一个结点到另一个结点所经过的“边”的数量称为两个结点之间的路径长度。如上图,GB的路径为G->F->B经过两条边,故路径长度为2
    • (3).结点的带权路径长度:指树的根结点到该结点的路径长度与该结点权重的乘积。如上图:结点B带权路径长度2x15=30
    • (4).树的带权路径长度:指一棵树中,所有叶子结点的带权路径长度之和。如上图,该树的带全路径长度Weighted Path Length(WPL))为2x19+2x15+2x12+2x8=108
    • (5).哈夫曼树:哈夫曼树(Huffman Tree)是在叶子结点和权重确定的情况下,带权路径长度最小的二叉树1

    2.哈夫曼树介绍

    • (1).哈夫曼树是由麻省理工学院的哈夫曼博士于1952年发明的。
    • (2).哈夫曼树的构造过程

      如上图,给定四个结点A:19,B:15,C:12,D:8(结点名称:权重),其构造过程是,先从结点中选权重值最小的两个结点,其根结点权重记为两结点之和作为新结点加入队列中,再从队列中选择两个最小的结点组成树,重复此过程直至队列中仅剩1个元素时构造完成,最后使得权重大的离根结# 一.数据编码之哈夫曼编码
      点进,权重小的结点离根结点远。过程如下图:

    在这里插入图片描述

    3.哈夫曼编码过程

        计算机存储传递数据时,只能处理10,因此需要对数据进行编码,以使用二进制来存储和传输。最常见的如ASCII码,如字符AASCII码表示为01000001ASCII码是一种等长编码,也就是任何字符的编码长度都相等,容易设计读写方便,缺点是效率低,浪费带宽。哈夫曼编码实现的两个特点:
    1).任何一个字符编码,都不是其他字符编码的前缀。
    2).信息编码的总长度最小。
        等长编码时,如ABCD的ascii编码为01000001 01000010 01000011 01000100总共需要32bit。若让不同的字符对应不同长度的编码,如A:0,B:00,C:01,D:1ABCD的编码为0 00 01 1长度为6bit,比32bit小的多,对于存储和传输很有优势。但是前述的不等长编码有个问题,如0001可能是ABD/AAAD/BC等,因此不定长编码不能随便设计,如果一个字符的编码恰好是另一个字符编码的前缀,就会导致上述起义问题。
        哈夫曼编码也是一种不等长编码。如图1中,假设有ABCD四个字符,其出现的频率分别为19,15,12,8,哈夫曼编码的设计过程为,先把这4个字符当做6个叶子结点,把字符出现次数当做结点的权重,以此来生成一颗哈夫曼树,哈夫曼树的每一个结点包括左、右两个分支,二进制的每一位有0、1两种状态,我们可以把这两者对应起来,结点的左分支当做0,结点的右分支当做1,这样一来,从哈夫曼树的根结点到每一个叶子结点的路径,都可以等价为一段二进制编码,则ABCD可编码为10 11 01 00,从哈夫曼树的构造过程可知哈夫曼树不是唯一的,故哈夫曼编码也不是唯一的。
        任何一个字符编码,都不是其他字符编码的前缀: 因为哈夫曼是从叶子节点开始构造,构造到根节点的,而且构造时,都是计算两个权值的节点的和再与其他叶子节点再生成一个父节点来组成一个新的树。并且不允许任何带有权值的节点作为他们的父节点。这也保证了所有带有权值的节点都被构造为了叶子节点。然后最后编码的时候是从根节点开始走到叶子节点而得出的编码。在有权值的节点又不会出现在任何一条路的路途中的情况,只会出现在终点的情况下,因此不会出现01代表一个字母011又代表一个字母。可知哈夫曼树不是唯一的,故哈夫曼编码也不是唯一的。
        信息编码的总长度最小哈夫曼树的重要特性,就是所有叶子结点的(权重 X 路径长度)之和最小。放在信息编码的场景下,叶子结点的权重对应字符出现的频次,结点的路径长度对应字符的编码长度。所有字符的(频次 X 编码长度)之和最小,自然就说明总的编码长度最小。2
        用于图像压缩,可根据图像的像素直方图来进行图像压缩,如PNG格式图像压缩使用的算法就包括哈夫曼编码,在编码过程中并未舍弃信息故哈夫曼编码是一种无损压缩方式。

    3.哈夫曼解码

    即给定由哈夫曼编码的结果10 11 01 00通过解码来恢复原数据ABCD。给定哈夫曼树,由哈夫曼编码开始01右来寻找叶子结点以完成解码。00即路径G->E->C00表示C
    参考:
    1.https://blog.csdn.net/qq_29519041/article/details/81428934#commentBox
    2.https://www.zhihu.com/people/ye-lan-feng-yu-sheng

    展开全文
  • 图像编码哈夫曼压缩编码
  • 本实例是用Matlab编写的对图像进行无损压缩的.m文件,里面要处理的文件是comp你可以换成你想要压缩的文件,功能不是很强的,但很实用,供初级人员学习用
  • (2)将彩色图像的像素 R、G、B 值作为独立符号,进行哈夫曼编码和解码,计算熵和码字平均码长。 (3)将彩色图像的像素 R、G、B 值作为联合符号,进行哈夫曼编码和解码,计算熵和码字的平均码长。
  • 哈夫曼编码,又称为霍夫曼编码,是一种字符编码。 在计算机数据压缩处理中,霍夫曼编码使用变长编码表()对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现几率的方法得到的,出现...

    有损压缩

    概念

    按照压缩方法是否丢失信息分为有损压缩和无损压缩,有损压缩解压缩后的数据与原始数据完全相同。 解压缩后获得的数据是原始数据的副本,是一种不可逆压缩。

    主要算法

    消除编码冗余: 哈夫曼编码和算术编码。
    消除像素间冗余:LZW编码,位平面编码,行程编码和无损预测编码。

    哈夫曼编码

    定义

    哈夫曼编码,又称为霍夫曼编码,是一种字符编码。

    在计算机数据压缩处理中,霍夫曼编码使用变长编码表()对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现几率的方法得到的,出现几率高的字母使用较短的编码,反之出现几率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。

    性质

    • 可变字长编码(VLC)
    • 源符号出现的频率越高,使用的代码字长越少。
    • 一致的编码方法(也称为“熵编码方法”),用于数据的无损压缩。

    信息熵

    英文entoropy,反映图像中的平均信息量。

    定长和变长编码比较

    定长编码:fixed length coding (FLC),如定长一字节或者定长二字节
    变长编码:virable length coding(VLC)

    示例

    SymbolProbabilityFLCVLC1VLC2VLC3
    K1/20001110
    L1/401101101
    P1/8101101001
    C1/811111010

    对 KLKPLCKK 用上述四个方式编码

    方式表示编码长度length
    FLC00 01 00 10 11 00 002*8 =16 bits
    VLC10 10 0 110 10 111 0 01+2+1+3+2+3+2 = 14 bits
    VLC2111 110 111 10 110 0 111 1113+3+3+2+3+1+3+3 = 21 bits
    VLC30 1 0 01 1 10 0 01+1+1+2+1+2+1+1 = 10 bits

    总结 根据最后编码长度,VLC3 的长度最短,符合出现概率高的字母使用较短的编码,因此是哈夫曼码。

    信息熵:反映图像中的平均信息量,用H(entoropy)表示,小于等于Lavg(average length)

    示例

    在这里插入图片描述

    生成哈夫曼编码

    在这里插入图片描述

    展开全文
  • 哈夫曼编码是一种根据词频变化的变长二进制编码方式,多用于压缩算法。将信源符号按出现概率从大到小排列,然后选2个最小的结合,依次类推,直到剩下2个符号为止。使用哈夫曼编码,结果不唯一,平均码长相同,接近信源...

    5.1 Python图像处理之图像编码-哈夫曼编码

    1 算法原理

    哈夫曼编码是一种根据词频变化的变长二进制编码方式,多用于压缩算法。将信源符号按出现概率从大到小排列,然后选2个最小的结合,依次类推,直到剩下2个符号为止。使用哈夫曼编码,结果不唯一,平均码长相同,接近信源熵,方法容易简单。但是对于接近等概率分布的信源编码效率低。

    设某信源产生有五种符号u1、u2、u3、u4和u5,对应概率P1=0.4,P2=0.1,P3=P4=0.2,P5=0.1。首先,将符号按照概率由大到小排队,如图所示。编码时,从最小概率的两个符号开始,可选其中一个支路为0,另一支路为1。这里,我们选上支路为0,下支路为1。再将已编码的两支路的概率合并,并重新排队。多次重复使用上述方法直至合并概率归一时为止。从图(a)和(b)可以看出,两者虽平均码长相等,但同一符号可以有不同的码长,即编码方法并不唯一,其原因是两支路概率合并后重新排队时,可能出现几个支路概率相等,造成排队方法不唯一。一般,若将新合并后的支路排到等概率的最上支路,将有利于缩短码长方差,且编出的码更接近于等长码。这里图(a)的编码比(b)好。

    image-20210723155435192

    2 代码

    运行代码说明

    1.要改变代码中的图片地址(地址不能有中文)

    更改put(path)函数中的路径put(r'../image/image1.jpg')

    2.注意最后的plt.savefig('1.new.jpg')是保存plt图像,如果不使用可以注释掉

    注意本次代码实验是对图片进行压缩后再解压,显示解压前后的图片是否有变化。

    import os
    
    import cv2
    from queue import PriorityQueue
    import numpy as np
    import math
    import struct
    import matplotlib.pyplot as plt
    '''
    对图像哈夫曼编码/解码
    根据哈夫曼编码灰度图像,保存到文件中;读取哈夫曼编码的文件,解码成图像,与原图像对比。
    '''
    
    
    class HuffmanNode(object):
        '''
        哈夫曼树的节点类
        '''
    
        def __init__(self, value, key=None, symbol='', left_child=None, right_child=None):
            '''
            初始化哈夫曼树的节点
            :param value: 节点的值,i.e. 元素出现的频率
            :param key: 节点代表的元素,非叶子节点为None
            :param symbol: 节点的哈夫曼编码,初始化必须为空字符串
            :param left_child: 左子节点
            :param right_child: 右子节点
            '''
            self.left_child = left_child
            self.right_child = right_child
            self.value = value
            self.key = key
            assert symbol == ''
            self.symbol = symbol
    
        def __eq__(self, other):
            '''
            用于比较两个HuffmanNode的大小,等于号,根据value的值比较
            :param other:
            :return:
            '''
            return self.value == other.value
    
        def __gt__(self, other):
            '''
            用于比较两个HuffmanNode的大小,大于号,根据value的值比较
            :param other:
            :return:
            '''
            return self.value > other.value
    
        def __lt__(self, other):
            '''
            用于比较两个HuffmanNode的大小,小于号,根据value的值比较
            :param other:
            :return:
            '''
            return self.value < other.value
    
    
    def createTree(hist_dict: dict) -> HuffmanNode:
        '''
        构造哈夫曼树
        可以写一个HuffmanTree的类
        :param hist_dict: 图像的直方图,dict = {pixel_value: count}
        :return: HuffmanNode, 哈夫曼树的根节点
        '''
        # 借助优先级队列实现直方图频率的排序,取出和插入元素很方便
        q = PriorityQueue()
    
        # 根据传入的像素值和频率字典构造哈夫曼节点并放入队列中
        for k, v in hist_dict.items():
            # 这里放入的都是之后哈夫曼树的叶子节点,key都是各自的元素
            q.put(HuffmanNode(value=v, key=k))
    
        # 判断条件,直到队列中只剩下一个根节点
        while q.qsize() > 1:
            # 取出两个最小的哈夫曼节点,队列中这两个节点就不在了
            l_freq, r_freq = q.get(), q.get()
            # 增加他们的父节点,父节点值为这两个哈夫曼节点的和,但是没有key值;左子节点是较小的,右子节点是较大的
            node = HuffmanNode(value=l_freq.value + r_freq.value, left_child=l_freq, right_child=r_freq)
            # 把构造的父节点放在队列中,继续排序和取放、构造其他的节点
            q.put(node)
    
        # 队列中只剩下根节点了,返回根节点
        return q.get()
    
    
    def walkTree_VLR(root_node: HuffmanNode, symbol=''):
        '''
        前序遍历一个哈夫曼树,同时得到每个元素(叶子节点)的编码,保存到全局的Huffman_encode_dict
        :param root_node: 哈夫曼树的根节点
        :param symbol: 用于对哈夫曼树上的节点进行编码,递归的时候用到,为'0'或'1'
        :return: None
        '''
        # 为了不增加变量复制的成本,直接使用一个dict类型的全局变量保存每个元素对应的哈夫曼编码
        global Huffman_encode_dict
    
        # 判断节点是不是HuffmanNode,因为叶子节点的子节点是None
        if isinstance(root_node, HuffmanNode):
            # 编码操作,改变每个子树的根节点的哈夫曼编码,根据遍历过程是逐渐增加编码长度到完整的
            root_node.symbol += symbol
            # 判断是否走到了叶子节点,叶子节点的key!=None
            if root_node.key != None:
                # 记录叶子节点的编码到全局的dict中
                Huffman_encode_dict[root_node.key] = root_node.symbol
    
            # 访问左子树,左子树在此根节点基础上赋值'0'
            walkTree_VLR(root_node.left_child, symbol=root_node.symbol + '0')
            # 访问右子树,右子树在此根节点基础上赋值'1'
            walkTree_VLR(root_node.right_child, symbol=root_node.symbol + '1')
    
        return
    
    
    def encodeImage(src_img: np.ndarray, encode_dict: dict):
        '''
        用已知的编码字典对图像进行编码
        :param src_img: 原始图像数据,必须是一个向量
        :param encode_dict: 编码字典,dict={element:code}
        :return: 图像编码后的字符串,字符串中只包含'0'和'1'
        '''
        img_encode = ""
        assert len(src_img.shape) == 1, '`src_img` must be a vector'
        for pixel in src_img:
            img_encode += encode_dict[pixel]
        return img_encode
    
    
    def writeBinImage(img_encode: str, huffman_file: str):
        '''
        把编码后的二进制图像数据写入到文件中
        :param img_encode: 图像编码字符串,只包含'0'和'1'
        :param huffman_file: 要写入的图像编码数据文件的路径
        :return:
        '''
        # 文件要以二进制打开
        with open(huffman_file, 'wb') as f:
            # 每8个bit组成一个byte
            for i in range(0, len(img_encode), 8):
                # 把这一个字节的数据根据二进制翻译为十进制的数字
                img_encode_dec = int(img_encode[i:i + 8], 2)
                # 把这一个字节的十进制数据打包为一个unsigned char,大端(可省略)
                img_encode_bin = struct.pack('>B', img_encode_dec)
                # 写入这一个字节数据
                f.write(img_encode_bin)
    
    
    def readBinImage(huffman_file: str, img_encode_len: int):
        '''
        从二进制的编码文件读取数据,得到原来的编码信息,为只包含'0'和'1'的字符串
        :param huffman_file: 保存的编码文件
        :param img_encode_len: 原始编码的长度,必须要给出,否则最后一个字节对不上
        :return: str,只包含'0'和'1'的编码字符串
        '''
        code_bin_str = ""
        with open(huffman_file, 'rb') as f:
            # 从文件读取二进制数据
            content = f.read()
            # 从二进制数据解包到十进制数据,所有数据组成的是tuple
            code_dec_tuple = struct.unpack('>' + 'B' * len(content), content)
            for code_dec in code_dec_tuple:
                # 通过bin把解压的十进制数据翻译为二进制的字符串,并填充为8位,否则会丢失高位的0
                # 0 -> bin() -> '0b0' -> [2:] -> '0' -> zfill(8) -> '00000000'
                code_bin_str += bin(code_dec)[2:].zfill(8)
            # 由于原始的编码最后可能不足8位,保存到一个字节的时候会在高位自动填充0,读取的时候需要去掉填充的0,否则读取出的编码会比原来的编码长
            # 计算读取的编码字符串与原始编码字符串长度的差,差出现在读取的编码字符串的最后一个字节,去掉高位的相应数量的0就可以
            len_diff = len(code_bin_str) - img_encode_len
            # 在读取的编码字符串最后8位去掉高位的多余的0
            code_bin_str = code_bin_str[:-8] + code_bin_str[-(8 - len_diff):]
        return code_bin_str
    
    
    def decodeHuffman(img_encode: str, huffman_tree_root: HuffmanNode):
        '''
        根据哈夫曼树对编码数据进行解码
        :param img_encode: 哈夫曼编码数据,只包含'0'和'1'的字符串
        :param huffman_tree_root: 对应的哈夫曼树,根节点
        :return: 原始图像数据展开的向量
        '''
        img_src_val_list = []
    
        # 从根节点开始访问
        root_node = huffman_tree_root
        # 每次访问都要使用一位编码
        for code in img_encode:
            # 如果编码是'0',说明应该走到左子树
            if code == '0':
                root_node = root_node.left_child
            # 如果编码是'1',说明应该走到右子树
            elif code == '1':
                root_node = root_node.right_child
            # 只有叶子节点的key才不是None,判断当前走到的节点是不是叶子节点
            if root_node.key != None:
                # 如果是叶子节点,则记录这个节点的key,也就是哪个原始数据的元素
                img_src_val_list.append(root_node.key)
                # 访问到叶子节点之后,下一次应该从整个数的根节点开始访问了
                root_node = huffman_tree_root
        return np.asarray(img_src_val_list)
    
    
    def decodeHuffmanByDict(img_encode: str, encode_dict: dict):
        '''
        另外一种解码策略是先遍历一遍哈夫曼树得到所有叶子节点编码对应的元素,可以保存在字典中,再对字符串的子串逐个与字典的键进行比对,就得到相应的元素是什么。
        用C语言也可以这么做。
        这里不再对哈夫曼树重新遍历了,因为之前已经遍历过,所以直接使用之前记录的编码字典就可以。
        :param img_encode: 哈夫曼编码数据,只包含'0'和'1'的字符串
        :param encode_dict: 编码字典dict={element:code}
        :return: 原始图像数据展开的向量
        '''
        img_src_val_list = []
        decode_dict = {}
        # 构造一个key-value互换的字典,i.e. dict={code:element},后边方便使用
        for k, v in encode_dict.items():
            decode_dict[v] = k
        # s用来记录当前字符串的访问位置,相当于一个指针
        s = 0
        # 只要没有访问到最后
        while len(img_encode) > s + 1:
            # 遍历字典中每一个键code
            for k in decode_dict.keys():
                # 如果当前的code字符串与编码字符串前k个字符相同,k表示code字符串的长度,那么就可以确定这k个编码对应的元素是什么
                if k == img_encode[s:s + len(k)]:
                    img_src_val_list.append(decode_dict[k])
                    # 指针移动k个单位
                    s += len(k)
                    # 如果已经找到了相应的编码了,就可以找下一个了
                    break
        return np.asarray(img_src_val_list)
    
    
    def put(path):
        
        # 即使原图像是灰度图,也需要加入GRAYSCALE标志
        src_img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
        # 记录原始图像的尺寸,后续还原图像要用到
        src_img_w, src_img_h = src_img.shape[:2]
        # 把图像展开成一个行向量
        src_img_ravel = src_img.ravel()
    
        # {pixel_value:count},保存原始图像每个像素对应出现的次数,也就是直方图
        hist_dict = {}
    
        # 得到原始图像的直方图,出现次数为0的元素(像素值)没有加入
        for p in src_img_ravel:
            if p not in hist_dict:
                hist_dict[p] = 1
            else:
                hist_dict[p] += 1
    
        # 构造哈夫曼树
        huffman_root_node = createTree(hist_dict)
        # 遍历哈夫曼树,并得到每个元素的编码,保存到Huffman_encode_dict,这是全局变量
        walkTree_VLR(huffman_root_node)
        global Huffman_encode_dict
        print('哈夫曼编码字典:', Huffman_encode_dict)
        # 根据编码字典编码原始图像得到二进制编码数据字符串
        img_encode = encodeImage(src_img_ravel, Huffman_encode_dict)
        # 把二进制编码数据字符串写入到文件中,后缀为bin
        writeBinImage(img_encode, 'huffman_bin_img_file.bin')
    
        # 读取编码的文件,得到二进制编码数据字符串
        img_read_code = readBinImage('huffman_bin_img_file.bin', len(img_encode))
        # 解码二进制编码数据字符串,得到原始图像展开的向量
        # 这是根据哈夫曼树进行解码的方式
        img_src_val_array = decodeHuffman(img_read_code, huffman_root_node)
        # 这是根据编码字典进行解码的方式,更慢一些
        # img_src_val_array = decodeHuffmanByDict(img_read_code, Huffman_encode_dict)
    
        # 确保解码的数据与原始数据大小一致
        assert len(img_src_val_array) == src_img_w * src_img_h
        # 恢复原始二维图像
        img_decode = np.reshape(img_src_val_array, [src_img_w, src_img_h])
    
    
        # 计算平均编码长度和编码效率
        total_code_len = 0
        total_code_num = sum(hist_dict.values())
        avg_code_len = 0
        I_entropy = 0
        for key in hist_dict.keys():
            count = hist_dict[key]
            code_len = len(Huffman_encode_dict[key])
            prob = count / total_code_num
            avg_code_len += prob * code_len
            I_entropy += -(prob * math.log2(prob))
        S_eff = I_entropy / avg_code_len
        print("平均编码长度为:{:.3f}".format(avg_code_len))
        print("编码效率为:{:.6f}".format(S_eff))
    
        # 压缩率
        ori_size = src_img_w*src_img_h*8/ (1024*8)
        comp_size = len(img_encode)/(1024*8)
        comp_rate = 1 - comp_size/ori_size
        print('原图灰度图大小', ori_size, 'KB  压缩后大小', comp_size, 'KB  压缩率',comp_rate, '%')
    
        plt.rcParams['font.sans-serif'] = ['SimHei']
        plt.subplot(121), plt.imshow(src_img, plt.cm.gray), plt.title('原图灰度图像'), plt.axis('off')
        plt.subplot(122), plt.imshow(img_decode, plt.cm.gray), plt.title('解压后'), plt.axis('off')
        # plt.savefig('1.1new.jpg')
        plt.show()
    
    
    if __name__ == '__main__':
        # 哈夫曼编码字典{pixel_value:code},在函数中作为全局变量用到了
        Huffman_encode_dict = {}
    
        # 图像处理函数,要传入路径
        put(r'../image/image3.jpg')
    

    3 效果

    image-20210723161321001

    image-20210723161351287

    本文使用的压缩率是 1- 压缩后大小/压缩前大小

    而且不是使用文件格式对比,而是比较图片像素占用的bit

    展开全文
  • 写入压缩文件,后缀.huf,先写入文件头(包括文件类型,权值列表,文件长度,以便于从压缩文件中再次生成哈夫曼编码来解压,也可以用其他的方式,比如直接将哈夫曼编码以先序遍历的方式写入压缩文件的开始,代码中有...
  • 用MATLAB做的基于霍夫曼编码图像压缩,里面有个文件时专门的霍夫曼编码函数,自己写的。
  • 摘要:图像压缩技术是目前计算机应用领域的一项热门技术.随着计算机技术,现代通信技术,网络技术和信息处理技术的迅速发展,图像作为一种重要的信息载体已经成为应用最广泛的信息表现形式之一.但是由于未经处理的图像...
  • 利用哈夫曼编码思想,设计对一个文本文件(.txt)中的字符进行哈夫曼编码,生成编码压缩文件(.txt),并且还可将压缩后的文件进行解码还原为原始文本文件(.txt)。 实现的功能: (1)压缩:实现对文件的压缩,生成...
  • 基于哈夫曼编码压缩算法的Python实现

    千次阅读 多人点赞 2018-11-18 01:11:59
    离散数学老师布置了一份大作业,作业题目就是用自己喜欢的编程语言来实现课上所学的哈夫曼编码算法(Huffman Coding)。哈夫曼编码是一种采用变长编码表来表示数据的编码方式。其详细介绍详见下方引自维基百科的引文...
  • 四轮:1 ‘ljffajklf’有什么方法这样的字符串加密(我就想起了凯撒)2有什么方法可以避免数据传输出错的时候发生的错误(我说的奇偶校验,汉明码)3说说哈夫曼编码是怎么来的,或者说出一种你熟悉的编码方式。...
  • AAAAABCD THE_CAT_IN_THE_HAT END 输出样例: 64 13 4.9 144 51 2.8 解题思路: 原题目贼长,不看也罢,单看输入描述和输出描述以及样例,再结合题目中的一点数字描述就知道是求一串字符串的哈夫曼编码压缩比。...
  • 本发明属于图片处理技术领域,尤其涉及一种基于Huffman编码图像压缩处理方法。背景技术:目前,业内常用的现有技术是这样的:由于各种新型传感器的出现,图像质量得到了巨大的提升,随之而来的数据量对图像的...
  • 哈夫曼编码python实现

    2018-04-26 12:35:56
    使用python编写的一套代码,可以实现随机文本生成,字符串字符统计还有哈夫曼编码。可以转换哈夫曼编码到010101,然后解码生成字符串
  • 哈夫曼编码压缩解压缩程序(CPP写的) 多媒体课程设计中也许能用的到 希望能帮到能用的到的人
  • 图像压缩编码哈夫曼树)

    千次阅读 2019-01-16 12:13:28
    1.首先图片压缩编码对不同文件的压缩效率是不一样的  这也是我在最后发现...哈夫曼编码压缩解压缩实现&amp;不同类型文件压缩比的测试 https://blog.csdn.net/to_be_better/article/details/50431352   ...
  • IMAGE_DCT.m //基于dct变换和哈夫曼编码图像压缩函数,并计算压缩率,返回解码图像。 img_block.m //图像分块操作函数 main_.m //交互式图形界面代码,也是测试运行的主要入口 pingYi.m //图像平移函数 sf.m /...
  • 基于MATLAB的图像压缩程序(包含各种压缩编码与解码方法),算法包含详细代码,是图像编码技术的总结
  • 代码实现huffman图像压缩的过程:从内存中读出图像数据,计算各数据概率;...对图像数据就行huffman编码压缩;将压缩后的数据存入内存;再将该数据进行解码解压。可将解压后的数据与原数据进行对比,是完全一致的。
  • 哈夫曼树和哈夫曼编码应用之图片压缩编码c++实现

    千次阅读 多人点赞 2018-12-07 22:38:04
    因此今天我就分享给大家c语言数据结构有关哈夫曼压缩图片的项目实现。   一:下面先介绍有关的知识: 1.背景 压缩软件是用特定算法压缩数据的工具,压缩后的文件称为压缩包,可以对其进行解压。那么为什么要...
  • 在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称“熵编码法”),用于数据的无损压缩。本文主要介绍了基于哈 夫曼编码图像压缩技术的原理、算法、过程,并利用VB6.0作为编程开发工具,开发了一个对256...
  • def gradient_function(theta, X, Y): diff = dot(X, theta) - Y return (1/m) * dot(X.transpose(), diff) 根据数据画出对应的图像 代码如下 def plot(X, Y, theta): ax = plt.subplot(111) # 将画布分为1行1列,取...
  • 数据结构大作业——哈夫曼编码压缩BMP格式文件

    千次阅读 多人点赞 2020-04-17 10:21:06
    数据结构大作业——哈夫曼编码压缩BMP格式文件 首先需要了解BMP图像格式 BMP图像格式详解 其次需要了解哈夫曼编码如何对BMP文件进行压缩 哈夫曼压缩与解压缩 编程部分 从BMP文件中读取需要的内容 首先是自定义图像...
  • 基于哈夫曼编码实现文件压缩是在学习数据结构(严蔚敏版)书中哈夫曼树及其应用后对书中伪代码的实现和完善,采用哈夫曼静态编码的方式,通过对数据进行两遍扫描,第一次统计出现的字符频次,进而构造哈夫曼树,第二遍...
  • 基于哈夫曼编码对文件进行压缩和解压缩(详细讲解) 本文对应c++代码实现链接 一、背景 利用特定的算法来压缩数据的工具,压缩后生成的文件称为压缩包。如果想使用其中的数据,就得用压缩软件对数据进行解压。利用...
  • 用MATLAB实现哈夫曼编码的例程-Huffman.rar 用MATLAB实现哈夫曼编码的例程(以子函数形式给出), NORM2HUFF 哈夫曼编码器 对于输入向量, NORM2HUFF 返回向量的哈夫曼编码后的码串。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,245
精华内容 898
关键字:

哈夫曼编码压缩图像