基于python的二元霍夫曼编码译码详细设计
一、设计题目
对一幅BMP格式的灰度图像(个人证件照片)进行二元霍夫曼编码和译码
二、算法设计
(1)二元霍夫曼编码:
①:图像灰度处理:
利用python的PIL自带的灰度图像转换函数,首先将彩色图片转为灰度的bmp图像,此时每个像素点可以用单个像素点来表示。
②:二元霍夫曼编码:
程序流程图:
详细设计:
- 统计像素点频率,首先通过python自带的PIL库的图像像素点读取函数read()获取灰度图像的所有像素点,通过循环遍历每个像素点,将每个出现的像素点值以及其次数以键值对的形式放入到python的字典中。
①:首先构造用以表示节点的类,其中每个节点包括一下成员属性:
self.left = left
self.right = right
self.parent = parent
self.weight = weight
self.code = code
②:遍历已经保存好的像素点频率字典,将图片中出现的像素点全部定义为叶子节点,通过类的code以及weight来表示对应的像素点值和该像素点出现的次数。
③:此时叶子结点中的权值为乱序,此时依据每个叶子结点的权重所有的叶子结点进行从小到大的排序;
④:每次取权值最小的两个节点最为要被替换的节点,将这两个节点的权值进行相加,然后生成新的节点,同时将这两个节点从叶子结点列表中去除,同时将新生成的节点放入叶子节点列表,同时对列表进行排序;
⑤:重复步骤④,直到列表中还剩下一个节点,此时这个节点便为头节点。
3.
①:根据已经构造好的二元霍夫曼编码树,由叶子节点开始遍历整棵树,左边赋予码字1,右边赋予码字0,每次向下遍历一次,若节点为非根节点,则依次将码符号放在码字左边,若遍历到根节点,则将该叶子结点所表示的像素值以及对应编成的码字放到码字字典中;
②:重复步骤①,直到所有的叶子节点都有其对应的二元霍夫曼码字。
③:经过步骤②,此时像素的码字字典已经生成,此时回归到原图片,根据遍历原图片的像素点,依次在码字列表中查找其对应的码字,将所有像素点对应的码字拼接在一起。
4.此时由于为二元霍夫曼编码,则编码结果为01字符串,此时为了对信息量进行压缩,采用将8个string类似的值转为一个byte,首先填充编码结果使其长度为8的倍数,并增加冗余位数保存原使编码结果最后多余位数的值以及其长度。填充完毕后,只需每次取编码结果的八位转为一个byte存入到txt中即可。
(2)二元霍夫曼译码:
详细设计:
1.每次读取txt中的一个字节,将其还原为字符串,直到txt中的所有字节被读取结束 ,则所得到的字符串则为霍夫曼编码的结果。
2.
①遍历霍夫曼编码的结果,根据霍夫曼编码已经生成的码字列表,对原始像素点进行还原,并根据还原后的像素点生成原始bmp图片。
②:对于每一个被遍历到的字符均在码字列表中进行查找,若未找到则加上后续一个字符,继续查找;
③:重复步骤③,直到在码字列表中找到该码字对应的像素点,将其码字对应的像素值放入到像素点列表中,重复以上查找还原像素值的步骤直到所有字符串均被遍历完。
三、模块划分
(1)二元霍夫曼编码部分:
①:类:
class node:
def __init__(self, right=None, left=None, parent=None, weight=0, code=None):
self.left = left
self.right = right
self.parent = parent
self.weight = weight
self.code = code
功能:表示叶子节点的类
②:函数:
def picture_convert():
功能:此函数完成彩色图转为灰度图的功能
③:函数:
def pin_lv_tong_ji(list):
功能:统计每个像素出现的次数
④:函数
def gou_zao_ye_zi(xiang_su_zhi):
功能:此函数主要为生成叶子结点,将每个节点赋予权值与像素值
⑤:函数
def sort_by_weight(list_node):
功能:根据每个叶子结点的权重对叶子结点列表进行排序
⑥:函数
def huo_fu_man_shu(listnode):
功能:根据叶子结点列表,生成对应的霍夫曼编码树
⑦:函数
def er_yuan_huo_fu_man_bian_ma(picture):
功能:此函数为进行二元霍夫曼编码的主函数,通过对其他函数的调用完成对像素点的编码
⑧:函数
def zi_jie_xie_ru():
功能:由于霍夫曼编码结果为string类型,此时应将其转为byte保存,此函数完成将编码结果的字节存入
(2)二元霍夫曼译码部分:
①:函数:
def zi_jie_du_qu(qqqq):
功能:根据霍夫曼编码生成的txt文件读取其中的字节恢复为字符串形式的编码结果
②函数:
def er_yuan_huo_fu_man_yi_ma(kuan,gao)
功能:此为二元霍夫曼译码的主函数,通过调用其他函数来还原原始的bmp图像
四、测试数据
测试采取图片像素点个数大小两种bmp图进行:
图片1信息:
名称:new.bmp
大小: 255 KB (261,366 字节)
像素点个数为: 260288
灰度图宽为448像素
灰度图高为581像素
图片2信息:
名称:test1.bmp
大小:12.7 KB (13,078 字节)
像素点个数: 12000
灰度图宽:96像素
灰度图高:125像素
六、测试情况及结果分析:
(一)二元霍夫曼编码过程:
图片1测试结果:
程序运行后将会生成霍夫曼编码表,并且将最终的编码结果存入到当前程序运行目录下的huo_fu_man_compress.txt中
由于存入为字节形式,以txt形式查看会显示乱码,属于正常情况。
原始图像大小为255kb,经过霍夫曼编码最终大小为218kb,大小缩减了接近15%。
图片2测试结果:
由程序运行结果可得出二元霍夫曼游程编码结果保存到
er_yuan_huo_fu_man_youcheng_compress.txt中
由于存入为字节形式,以txt形式查看会显示乱码,属于正常情况。
原始图片大小为12.7kb,编码结果文件为9.5kb,大小缩减了接近26%。
(二)二元霍夫曼译码过程:
图一测试结果:
根据编码生成的huo_fu_man_compress.txt还原原始bmp图片并保存为
er_yuan_huo_fu_man_huan_yuan.bmp
还原后的图片与原始图片相符合,译码成功
图片2测试结果:
根据编码生成的huo_fu_man_compress.txt还原原始bmp图片并保存为
er_yuan_huo_fu_man_huan_yuan.bmp
还原后的图片与原始图片相符合,译码成功
结果分析:
Bmp灰度图片经过二元霍夫曼编码后,文件大小总能够缩小,即所占空间减小,即达到了压缩的效果,压缩效率会由像素点出现频率的影响。
等长码编码位数的影响。
基于python的二元霍夫曼编码译码详细设计的更多相关文章
- 赫夫曼\哈夫曼\霍夫曼编码 (Huffman Tree)
哈夫曼树 给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的结点离 ...
- 霍夫曼编码(Huffman Coding)
霍夫曼编码(Huffman Coding)是一种编码方法,霍夫曼编码是可变字长编码(VLC)的一种. 霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符 ...
- 采用霍夫曼编码(Huffman)画出字符串各字符编码的过程并求出各字符编码 --多媒体技术与应用
题目:有一个字符串:cabcedeacacdeddaaaba,问题: (1)采用霍夫曼编码画出编码的过程,并写出各字符的编码 (2)根据求得的编码,求得各编码需要的总位数 (3)求出整个字符串总编码长 ...
- 霍夫曼编码(Huffman)
题目:有一个字符串:cabcedeacacdeddaaaba,问题: (1)采用霍夫曼编码画出编码的过程,并写出各字符的编码 (2)根据求得的编码,求得各编码需要的总位数 (3)求出整个字符串总编码长 ...
- Java数据结构(十二)—— 霍夫曼树及霍夫曼编码
霍夫曼树 基本介绍和创建 基本介绍 又称哈夫曼树,赫夫曼树 给定n个权值作为n个叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称为最优二叉树 霍夫曼树是带权路径长度最短的树,权值较 ...
- 哈夫曼编码译码系统(c/c++)
哈夫曼编码译码系统的实现,主要包含三部分: 1.创建哈夫曼树 2.编码函数 3.译码函数 编写代码时为了方便,在这里混用了c++的输入输出流.主体用c语言实现. 下面时代码部分: 1.头文件,以及储存 ...
- Huffman树、霍夫曼编码
Huffman树指的是带权路径长度WPL最小的二叉树 WPL=路径*权值 Huffman常用于压缩编码,正常传输ABCDEF这些字母需要3位二进制树来描述,但由于一篇文章中ABCDEF这些字母出现的概 ...
- Alink漫谈(十六) :Word2Vec源码分析 之 建立霍夫曼树
Alink漫谈(十六) :Word2Vec源码分析 之 建立霍夫曼树 目录 Alink漫谈(十六) :Word2Vec源码分析 之 建立霍夫曼树 0x00 摘要 0x01 背景概念 1.1 词向量基础 ...
- word2vec 中的数学原理二 预备知识 霍夫曼树
主要参考: word2vec 中的数学原理详解 自己动手写 word2vec 编码的话,根是不记录在编码中的 这一篇主要讲的就是霍夫曼树(最优二叉树)和编码. ...
随机推荐
- Catalog Service - 解析微软微服务架构eShopOnContainers(三)
上一篇我们说了Identity Service,因为其基于IdentityServer4开发的,所以知识点不是很多,今天我们来看下Catalog Service,今后的讲解都会把不同的.重点的拿出来讲 ...
- Web前端性能优化全攻略
网页制作poluoluo文章简介:Web 前端性能优化是个大话题,是个值得运维人员持续跟踪的话题,是被很多网站无情忽视的技术. Web 前端性能优化是个大话题,是个值得运维人员持续跟踪的话题,是被很多 ...
- javaCV开发详解之3:收流器实现,录制流媒体服务器的rtsp/rtmp视频文件(基于javaCV-FFMPEG)
javaCV系列文章: javacv开发详解之1:调用本机摄像头视频 javaCV开发详解之2:推流器实现,推本地摄像头视频到流媒体服务器以及摄像头录制视频功能实现(基于javaCV-FFMPEG.j ...
- C# 并行任务——Parallel类
一.Parallel类 Parallel类提供了数据和任务的并行性: 二.Paraller.For() Paraller.For()方法类似于C#的for循环语句,也是多次执行一个任务.使用Paral ...
- 惊心动魄的SAP S4客户额度调整运动
今天一大早,收到商务部发来的消息,说某一个客户的额度超额了,但实际上并未超额.从SAP系统中反馈的额度来看,显示超了2万多.后来经过在BP画面检查信用段发现,这个客户额度占用里面,某一个未清订单已经部 ...
- ecshop支付方式含线下自提
用户展示页面模板所在:如ecshop/theme/default/flow.dwt 后台管理展示页面模板所在:如admin/templates/payment_list.htm ecshop 支付接口 ...
- python网络爬虫之LXML与HTMLParser
Python lxml包用于解析html和XML文件,个人觉得比beautifulsoup要更灵活些 Lxml中的路径表达式如下: 在下面的表格中,我们已列出了一些路径表达式以及表达式的结果: 路径表 ...
- fdisk 非交互式创建 分区
一. key 非交互式创建分区, 与 交互式创建分区区别不大. 使用 fdisk 的默认选项, 使用空行即可, 不用回车. 创建 主分区 和 扩展分区时, 需要注意 分区号 二. 创建主分区 fdis ...
- 数列[专杀Splay版]
时间限制: 3 Sec 内存限制: 128 MB提交: 49 解决: 7 题目描述 输入一个数列,你需要进行如下操作: 1. 把编号为I的数值改为K 2. 输出从小到大排序后第k个数 输入 输 ...
- Sql函数简单使用
),)) ) as begin ) --如果@nameA 不为空则直接返回@nameA IF @nameA <>'' BEGIN set @lastNameVal = @nameA END ...