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

文章目录

  • 5.5 Python图像处理之图像编码-位平面编码
    • 1 算法原理
    • 2 代码
    • 3 效果

1 算法原理

比特平面编码又称为位平面编码,位平面编码是一种通过单独地处理图像的位平面来减少像素间冗余的有效技术。它将一幅多级图像分解为一系列二值图像并采用几种熟知的二值图像压缩方法对每一幅二值图像进行压缩。位平面编码分为两个步骤:位平面分解和位平面编码

位平面分解

对于 8 位 256 灰度级图像来说,如果它的每个灰度值用二进制表示,选择将这 8 个数字用 8 个字节来表示,如 32 的二进制表示是 00100000,将其储存为[0 ,0, 1, 0, 0, 0, 0, 0],则其二维图像可以理解为一个 8 层的三维图像,每一层代表一个比特平面。对比每个比特平面可以发现,高阶平面(如 1 所在第六比特平面)储存的信息比低阶平面的多。重构是使用第 n 个平面的像素值乘以常数 2^(n-1),用 128 乘以比特平面 8,用 64 乘以比特平面 7,然后将这两个平面相加,原图的主要特征便被复原了。

位平面编码

下面讨论对分解后位面图的编码,这里仅介绍一种方法,即是1-D的游程编码方法。另外还有另一种是2-D的游程编码方法,它们分别是传真机中使用的两种二值图像压缩标准(G3和G4)中所用技术的基础,在文章就不细说了。

1-D的游程编码

对相关性较强的图像,相邻像素的灰度值比较接近,其各个位面中会有较多的全是0或1的连通区域。对这类常数区编码的有效方法之一就是用一系列描述0或1像素游程(连续的0或1像素段)的长度值来表示位平面中的每1行。1D游程编码的基本思路就是对1组从左向右扫描得到的连续的0或1游程用游程的长度来编码,而不是对每个像素分别编码。当游程较长时,其压缩效率会很高。为表示不同值(0或1)的游程,需要建立指定游程值的协定,常用的方法有:

①指出每行第1个游程的值;

②设每行都由(其长度可以是零)0游程(也可是1游程)开始。

进一步,通过用变长码对游程的长度编码还有可能获得更高的压缩率。实际应用中可将0和1的游程长度分开,并根据它们的统计特性分别编码。例如,令符号b代表1个长度为j的0游程,用图像中长度为j的0游程个数去除以图像中所有0游程的总个数,就可近似得到符号b是由某个想象中的0游程信源产生出来的概率。将这些概率代入式(733)就可得到上述0游程源的熵估计。

本适用就是使用1-D游程编码。

例如:原始文本:dfffffeeeeettttrrrrttttt

游程编码后文本:d1f5e5t4r4t5

当然,我们在存储的时候不会就是使用游程编码后字符串,而会考虑存储用的位数。尽量减少存储数据量。

在代码中,我是使用一个字节来存储游程编码,第一位是存储编码的符号(0或1),后7位存储的是符号的个数,即连续0和1的个数。(7位最大值是127)

2 代码

运行代码说明

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

83行,img = cv2.imread(r’…/image/32-1.jpg’, 0)

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

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author:mgboy time:2021/6/28
# encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as pltdef compress(str_num):"""1维游程压缩编码。对一连续的0,1,用8为进行存储游程信息。第一位存储的是字符0,1,后7位存储的是字符的数目:param str_num: 要求格式是二进制字符串,要在输入之前就转为二进制字符串:return:"""compress_str = ''last = Nonecount = 0for t in list(str_num):if last is None:last = tcount = 1else:# 一个字节能够存储的最大长度是255if t == last and count < 127:count += 1else:if last == '0':str_2 = str(bin(count))[2:]if len(str_2) < 8:str_2 = (8 - len(str_2)) * '0' + str_2compress_str = compress_str+ str_2else:count = count+128str_2 = str(bin(count))[2:]if len(str_2) < 8:str_2 = (8 - len(str_2)) * '0' + str_2compress_str = compress_str+str_2last = tcount = 1# 最后一次存储if last == '0':str_2 = str(bin(count))[2:]if len(str_2) < 8:str_2 = (8 - len(str_2)) * '0' + str_2compress_str = compress_str+ str_2else:count = count + 128str_2 = str(bin(count))[2:]if len(str_2) < 8:str_2 = (8 - len(str_2)) * '0' + str_2compress_str = compress_str + str_2return compress_strdef decompress(compress_str):"""游程编码解压缩,对输入的二进制字符串按 8 位一组进行解压:param compress_str::return:"""decompress_str = ''i = 0while True:string_num = compress_str[i:i+8]str_10 = int(string_num, 2)if  str_10 > 127:decompress_str += int(string_num[1:], 2) * '1'else:decompress_str += str_10*'0'i = i + 8if i+8 > len(compress_str):breakreturn decompress_str
###########################################################读取图片部分
# 读取图像
img = cv2.imread(r'../image/32-1.jpg', 0)
h, w = img.shape[0], img.shape[1]
rows, cols = img.shape[0], img.shape[1]
# 位平面解码处理过程,将8个位平面数据存储带new_img数组中
new_img = np.zeros((h, w, 8),np.uint8)
for i in range(h):for j in range(w):n = str(np.binary_repr(img[i, j], 8))for k in range(8):new_img[i, j, k] = n[k]#######################################################################
# 游程编码部分,是对8个位平面分别使用游程编码
compress_len_list = []
for k in range(8):img_k = new_img[:, :, k]image1 = img_k.flatten()  # 把灰度化后的二维图像降维为一维列表imgdata_str_list = [str(i) for i in image1]imgdata_str = ''.join(imgdata_str_list)compress_str = compress(imgdata_str)  # 压缩decompress_str = decompress(compress_str)  # 解压缩decompress_int = [int(i) for i in list(decompress_str)]  # 转换回int格式# 转换会图像数组形式new_img[:, :, k] = np.reshape(decompress_int, (rows, cols))# 打印信息# if decompress_str == imgdata_str:#     print('正确解压')# else:#     print('解压出错')# print(decompress_str)# print('游程编码压缩解压成功!')compress_size = len(compress_str)/8/1024.0compress_len_list.append(compress_size)decompress_size = len(decompress_str)/8/1024.0ratio = 100 - compress_size / decompress_size*100# 压缩率print('第 {} 平面,原图大小:{:.2f}KB  压缩后大小:{:.2f}KB  压缩率{:.2f}%(即比原图减少了多少空间)'.format(k,decompress_size, compress_size,ratio))
#################################################################
# 计算只压缩前两个平面的压缩率
compress_len_sum = (compress_len_list[0]+compress_len_list[1]) + w*h*6/1024.0/8.0
all_size = (w*h*8)/1024.0/8
ratio = 100 - compress_len_sum / all_size*100
# 只对第一和第二层进行编码压缩
print('只对第一和第二层进行编码压缩')
print('原图大小:{:.2f}KB  压缩后大小:{:.2f}KB  压缩率{:.2f}%(即比原图减少了多少空间)'.format(all_size, compress_len_sum,ratio))
#######################################################################
# 位面解码
res_img = np.zeros((h, w),np.uint8)
for i in range(h):for j in range(w):s = ''for k in range(8):s += str(new_img[i, j, k])res_img[i][j] = int(s,2)
#####################################################################
# 显示结果,用以中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
# 显示1-8层位平面
for i in range(8):j = i + 1plt.subplot(2, 4, i + 1)plt.axis('off')plt.title('位平面第%i层图像' % j)plt.imshow(new_img[:, :, i], cmap='gray')
plt.savefig('2.1.1new-' + '32-1.jpg')plt.figure()
plt.subplot(121), plt.imshow(img, plt.cm.gray), plt.title('原图灰度图像'), plt.axis('off')
plt.subplot(122), plt.imshow(res_img, plt.cm.gray), plt.title('解压后'), plt.axis('off')
# plt.savefig('5.5new.jpg')
plt.show()

注:我没有保存编码后的数据,而是直接用来解压,如果有需要的话自行修改代码。

3 效果

位平面分解结果

统计结果:

5.5 Python图像处理之图像编码-位平面编码相关推荐

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

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

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

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

  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. python 图像处理_Python中的十大图像处理工具

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

  9. Python图像处理

    一.简介 实现计算机视觉任务的过程中,不可避免地需要对图像进行读写操作以及图像预处理操作,下面介绍两个常用的Python图像处理库:OpenCV和Pillow. OpenCV全称是由英特尔公司资助的开 ...

最新文章

  1. 深入了解Oracle前滚恢复rolling forward(一)
  2. PTAM增强现实相关
  3. (SpringMVC)RestFul和Controller
  4. 11.JDK8内存模型、本地方法栈、虚拟机栈、栈帧结构(局部变量表、操作数栈、方法出口、虚拟机栈与本地方法栈的关系、寄存器、方法区、堆(Heap)、jvm中的常量池、Metaspace(元空间))
  5. 孤儿进程和僵死进程处理方法
  6. tomcat和servlet的关系
  7. 全局照明算法基础——从辐射亮度到渲染方程
  8. linux下设定动态库路径的命令-error while loading shared libraries: xxx.so.x错误的原因和解决办法
  9. 三十五岁后,如何自学WEB前端编程
  10. python黑屏改成白底_Python 进行黑屏 PNR 的提取
  11. easyrecovery软件如何恢复丢失数据-注册码-序列号-密钥最新绿色下载版
  12. epoll原理详解及epoll反应堆模型
  13. win8.1搭建php环境,WIN8.1下搭建PHP5.6环境
  14. oppor11点击Android,OPPO R11怎么网络共享?OPPO R11三种共享网络设置教程
  15. http和https协议下,http可以正常下载,但是https却不能
  16. 用Python写了一个带界面的聊天室
  17. 关于国际象棋皇后的递归问题——经典为8皇后
  18. Android编程 不显示菜单,网易MuMu模拟器不显示Menu(菜单)键的解决办法
  19. ★关于人类体质弱化的分析
  20. shipyard安装不迷茫

热门文章

  1. 微信公众号开发之获取oppenid和用户基本信息
  2. sangerbox制作heapmap_使用highmaps制作中国地图
  3. Sizes of tensors must match except in dimension 1. Expected size 24 but got size 25 for tensor numbe
  4. 内容付费的分类与分析
  5. Redis 部署方式(单点、master/slaver、sentinel、cluster) 概念与区别 -- 敲黑板!!!=_=
  6. 56个民族按照字母排序,首字母拼音组合
  7. 新浪微博爬虫遇到的cookie rejected 问题解决办法
  8. 计算机应用基础2021自考本科,2021自考本科都考什么
  9. 判断iPhoneX的基带是英特尔还是高通的
  10. windows安装perl及komodo IDE的详细步骤