5.2 Python图像处理之图像编码-哥伦布编码

文章目录

  • 5.2 Python图像处理之图像编码-哥伦布编码
    • 1 算法原理
      • 变体Rice–Golomb
      • 在图像的应用
    • 2 代码
    • 3 效果

1 算法原理

哥伦布(Golomb)编码是一种无损的数据压缩方法,由数学家Solomon W.Golomb在1960年代发明。Golomb编码只能对非负整数(unsigned int)进行编码。当待编码符号表中的符号出现的概率符合几何分布(Geometric Distribution)时,使用Golomb编码可以取得最优效果,也就是说Golomb编码比较适合小数字比大数字出现概率高的场景编码。它使用较短的码长编码较小的数字,较长的码长编码较大的数字。

Golomb编码是一种分组编码,需要一个正整数参数m。用m对待编码的数字(n)进行求商(q=int(n/m))和余(r=n%m),然后对商做一元编码,对余做固定长度的二进制编码(用固定bit数来表示余数)。

算法原理哥伦布编码算法步骤为:给定一个非负整数 n 和一个正整数除数 m,记 n 相对于 m 的哥伦布码记为Gm(n),

1构建**⌊n/m⌋**的一元码;比如商为 2,一元码就是 2 个 1 加一个 0,即 110;商为 3,一元码就是 3 个 1 加一个 0 为 1110;

2令:

计算截断的 r’,(截断的意思就是转化成 2 进制,保留相应的位)。

3拼接 1 和 2 的结果。

我们将 m = 0, 1, 2, 3 时的 Golomb 编码表列出:

变体Rice–Golomb

Golomb-Rice是Golomb编码的一个变种,它给Golomb编码的参数m添加了个限制条件:m必须是2的次幂。这样有两个好处:

1不需要做模运算即可得到余数r,r = N & (m - 1)

2对余数r编码更为简单,只需要取r二进制的低log2(m)位即可。

则Golomb-Rice的编码过程更为简洁:

1 初始化参数m,m必须为2的次幂

2 计算q和r,r = N & (m - 1)

3使用一元编码编码q

4取r的二进制位的低log2(m)位作为r的码字。

在图像的应用

本代码实现是把图像文件按字节的方式读取,按字节编码。通过给定的m值,计算0到255的哥伦布编码,因为一个字节的范围也是0-255,这样就可以使用哥伦布编码替换像素值,从而实现编码。而且本代码实验室把编码好的哥伦布编码保存为ASCII码的文本文件,这样就相当于base64编码,有保密传输的作用。

2 代码

运行代码说明

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

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

还有139行当open(’./image/img5.jpg’,‘rb’) 也要改为自己的图片地址

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

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = Falsefrom math import ceil, log
class Golomb(object):"""Golomb Rice Coding:"""def __init__(self, m):self.m = mself.maxbits = int(ceil(log(self.m, 2)))def encode(self, n):# TODO: log this assertionassert isinstance(n, int)  # 检测n是否是intl类型# Python divmod() 函数接收两个数字类型(非复数)参数,返回一个包含商和余数的元组(a // b, a % b)。q, r = divmod(n, self.m)return '{0:1>{1}}{2:0>{3}}'.format(0, q + 1, bin(r)[2:], self.maxbits)def decode(self, s):# TODO: log this assertionassert isinstance(s, str)zero_pos = s.find('0')try:return (zero_pos * self.m + int(s[zero_pos + 1: zero_pos + 1 + self.maxbits], 2),s[zero_pos + 1 + self.maxbits:])except ValueError:  # occurs when remainder is nonereturn (zero_pos * self.m, s[zero_pos + 1 + self.maxbits:])class GolombStream(Golomb):"""哥伦布编码流,对字符串流进行编码"""def __init__(self, m, inputstream, outputstream):super(GolombStream, self).__init__(m)self.inp = inputstreamself.out = outputstreamself.maxbits_2 = int(ceil(log(self.m, 2)))def compress(self,read_type='r'):"""读取文件可以指定以r字符或rb字节读取,但写一定要是w字符格式:param read_type::return:"""s = ''t_num = 0while True:t = self.inp.read(1)t_num += 1if not t:breakif read_type == 'r':s += self.encode(ord(t))else:t_0_1 = int.from_bytes(t, 'big')s += self.encode(t_0_1)# print('编码后的二进制字符串:',ss)print(len(s)/8)# 将最后一个字节有4中可能,一种 0, 0000, 00010, 10001 对于中间两种要记录0的个数,要不然不能正确解码# 所以我用第一个字节记录最后一个字节前面有多少个0end = int(len(s) / 8) * 8end_str = s[end:]zeros_num = 0for i in end_str:if i == '0':zeros_num += 1else:breakself.out.write(chr(zeros_num))org_size = t_num / 1024comp_size = ceil(len(s)/8)/1024rate = 100- comp_size/org_size*100print('原图大小:{:.2f}KB  压缩后大小:{:.2f}KB  压缩率{:.2f}%(即比原图减少了多少空间)'.format(org_size,comp_size,rate))# 存储while s:self.out.write(chr(int(s[:8], 2)))s = s[8:]print('------------压缩完成-------------')def decompress(self, write_type='w'):"""完善解压,当读取的字节不够解码时,要进行判断末尾字节的要进行特殊处理,现在是全部读取再进行解码:return:"""s = ''# 读取第一个字节,了解最后一个字节的情况first_b = self.inp.read(1)first_int = ord(first_b)last = self.inp.read(1)while True:t = lastlast = self.inp.read(1)  # 读取字符if not t:breakstr_2 = bin(ord(t))[2:]  # 将读取的字符串转为二进制if last:  #if len(str_2) < 8:str_2 = (8 - len(str_2)) * '0' + str_2else:# 处理末尾字节的情况zeros_num = 0for i in str_2:if i == '0':zeros_num += 1else:breakif zeros_num == first_int:passelse:str_2 = (first_int-zeros_num)*'0' +str_2s += str_2print(len(s)/8)while s:n, s = self.decode(s)if write_type == 'w':self.out.write(chr(n))else:self.out.write(int.to_bytes(n, 1, byteorder='big'))print('------------解压缩完成-------------')if __name__ == '__main__':# 异常情况。m=4时解码正常,但在8,使会失真,16时就干脆不能解压# 压缩部分with open('gol.gol','w',encoding='utf-8') as comp:with open('./image/img5.jpg','rb') as f:G_str = GolombStream(4,f,comp)G_str.compress(read_type='rb')  # 哥伦布编码的结果是字符,类似base64编码# 解压部分with open('gol.jpg','wb') as comp:with open('gol.gol','r',encoding='utf-8') as f:G_str = GolombStream(4,f,comp)G_str.decompress(write_type='wb')#显示压缩前的和解压后的图片import cv2org_img = cv2.imread('./image/img5.jpg',1)dep_img = cv2.imread('gol.jpg', 1)plt.figure()plt.suptitle('哥伦布编码')plt.subplot(1, 2, 1)plt.title('原图')plt.imshow(cv2.cvtColor(org_img, cv2.COLOR_BGR2RGB))plt.subplot(1, 2, 2)plt.title('解压后')plt.imshow(cv2.cvtColor(dep_img, cv2.COLOR_BGR2RGB))# plt.savefig('1.new.jpg')plt.show()

此代码还是有点瑕疵的,有能力可以完善,解决m=8时失真的问题,甚至有时m>=8就不能使用了

3 效果

可以看到空间反而大了很多,所以使用本算法压缩时不适合应用到色彩繁多的图片上。但如果是类似于base64都编码都可以使用

5.2 Python图像处理之图像编码-哥伦布编码相关推荐

  1. 5.5 Python图像处理之图像编码-位平面编码

    5.5 Python图像处理之图像编码-位平面编码 文章目录 5.5 Python图像处理之图像编码-位平面编码 1 算法原理 2 代码 3 效果 1 算法原理 比特平面编码又称为位平面编码,位平面编 ...

  2. 5.3 Python图像处理之图像编码-算术编码

    5.3 Python图像处理之图像编码-算术编码 文章目录 5.3 Python图像处理之图像编码-算术编码 1 算法原理 2 代码 3 效果 1 算法原理 算术编码在图像数据压缩标准(如JPEG,J ...

  3. 6.1 Python图像处理之图像编码技术和标准-DPCM编码

    6.1 Python图像处理之图像编码技术和标准-DPCM编码 文章目录 6.1 Python图像处理之图像编码技术和标准-DPCM编码 1 算法原理 2 代码 3 效果 1 算法原理 预测编码利用的 ...

  4. 6.3 Python图像处理之图像编码技术和标准-小波变换编码

    6.3 Python图像处理之图像编码技术和标准-小波变换编码 文章目录 6.3 Python图像处理之图像编码技术和标准-小波变换编码 1 算法原理 2 代码 3 效果 1 算法原理 所谓的小波的小 ...

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

    5.1 Python图像处理之图像编码-哈夫曼编码 文章目录 5.1 Python图像处理之图像编码-哈夫曼编码 1 算法原理 2 代码 3 效果 1 算法原理 哈夫曼编码是一种根据词频变化的变长二进 ...

  6. 6.2 Python图像处理之图像编码技术和标准-余弦变换编码

    6.2 Python图像处理之图像编码技术和标准-余弦变换编码 文章目录 6.2 Python图像处理之图像编码技术和标准-余弦变换编码 1 算法原理 2 代码 3 效果 (6)图像编码技术和标准,包 ...

  7. python图像切面numpy_十个Python图像处理工具,不可不知!

    原标题:十个Python图像处理工具,不可不知! 这些Python库提供了一种简单直观的方法来转换图像并理解底层数据. 今天的世界充满了数据,图像是这些数据的重要组成部分.但是,在使用它们之前,必须对 ...

  8. 【H264/AVC 句法和语义详解】(五):Exp-Golomb指数哥伦布编码(理论篇)

    版权声明:本文为博主原创文章,未经博主允许不得转载.    https://blog.csdn.net/u011399342/article/details/80472399 本篇隶属于文集:< ...

  9. python 图像处理_Python中的十大图像处理工具

    文章发布于公号[数智物语] (ID:decision_engine),关注公号不错过每一篇干货. 来源 | 大数据文摘(BigDataDigest) 编译 | 张秋玥.小七.蒋宝尚 本文主要介绍了一些 ...

最新文章

  1. Java提高班(一)Thread详解
  2. java操作storm,Storm集群常用批量操作命令
  3. php ajax工作原理,AJAX实现页面无刷新操作原理解析
  4. leetcode - 1201. 丑数 III
  5. leetcode 95 python
  6. 票价最低10元 北京大兴国际机场线票价方案正式启用
  7. 项目管理工具project软件学习(六) - 设置里程碑、任务备注
  8. C++设计模式-Command命令模式
  9. C3P0的几种使用方法(非JNDI)
  10. VISIO——word中插入visio图片 图片边缘空白裁剪
  11. 通达OA - 数据备份与恢复指南
  12. python实现英文新闻摘要自动提取_自然语言处理之自动摘要
  13. python入门教程陈孟林_如何入门Python?
  14. esp32 物联网应用 01
  15. 华硕路由器远程连接配置指南
  16. 达尔文的进化论VS柏拉图的理念论
  17. css-doodle插件初体验
  18. 中职计算机教师招聘试题库,职业技术学校教师考试题目
  19. 【机器学习】模型评估-手写数字集模型训练与评估
  20. 梦回----32位CPU和64位CPU的通用寄存器

热门文章

  1. “银联商务全民付移动支付”接入及问题处理
  2. 【​观察】探访中国首家高端装备智能工厂 浪潮重新定义计算新未来
  3. 实现一个可host asp.net程序的小型IIS(Cassinidev介绍)
  4. 【沐风老师】3DMAX橱柜生成器工具使用教程
  5. Echart城市空气分析地图实例解析
  6. 【笔记】组网方案 - mesh组网、AC+AP组网
  7. 阿里java开发一二面面经
  8. 一款功能强大的课程报名系统 v6.2.0
  9. 使用OpenCV的车辆检测和计数系统
  10. Android群英传神兵利器读书笔记——第一章:程序员小窝——搭建高效的开发环境