当前位置: 首页 > ops >正文

数字图像处理——图像压缩

背景

图像压缩是一种减少图像文件大小的技术,旨在在保持视觉质量的同时降低存储和传输成本。随着数字图像的广泛应用,图像压缩在多个领域如互联网、移动通信、医学影像和卫星图像处理中变得至关重要。

技术总览

当下图像压缩JPEG几乎一统天下,本文主要依据其原理,进行解析。

工作流总览

  1. 颜色空间(YUV)下采样
  2. 分块DCT
  3. 依据量化表进行DCT量化
  4. zigzag扫描
  5. RLE编码
  6. Huffman编码
  7. 上述过程反向进行,解压缩

颜色空间下采样

关于YUV空间一些基础知识:

https://zhuanlan.zhihu.com/p/587189669https://zhuanlan.zhihu.com/p/587189669其中Y空间也称灰度空间,直方图均衡化、灰度拉伸等操作就是基于这个空间进行的,很多时候,为了图像处理的简洁,经常在该空间上进行操作。

将颜色空间RGB转化为YUV之后,由于人眼主要对Y(亮度)敏感,而对UV空间不敏感,所以可以对UV空间进行下采样,(这里对UV空间体积分别缩小到原来的1/4),以512 * 512尺寸的RGB图片为例。仅一步颜色空间下采样,存储空间就压缩为了原本的 

(512*512 + 256*256 + 256*256)/ 512*512*3 = 1/2

分块DCT

关于dct的一些相关知识⬇️

https://zhuanlan.zhihu.com/p/85299446https://zhuanlan.zhihu.com/p/85299446dct将空域转化成等价的频域, 在频域中,人眼对高频的信息不敏感,那么如果略去高频,保留低频,则实现了图像的有损压缩。

dct仅仅是一步变换而已,并不对图像构成压缩,真正起到压缩效果的是量化 + 编码(也即接下来两步)

为何分块?

全局dct当然可以完成任务,并且压缩效果依旧十分优异。但分块后的好处是明显的

从空间上来说:有固定分块更容易研究量化表,读者仔细思考就会发现,对于任意尺寸的dct二维数组,去用函数生成量化表是困难的,但是如果行业定下一个固定的dct二维数组尺寸,大家就可以尽情研究这个条件下什么样的量化表效果会比较好。

从时间上来说:进行分块后,计算的总体时间比整体计算快很多。在此之外,对于8*8分块的dct,也有很多研究其快速算法的,ANN算法就是其中典例。

DCT矩阵量化

这一步的根本目标就是把DCT的高频部分消去。

具体的计算步骤为,DCT矩阵的元素处以量化矩阵的对应位置元素

读者的困惑应该大多在于量化表的生成。 关于这一点,对于任意M*N尺寸的图片,其量化表可以设计一个指数函数去表达, 其中k的值应当偏小,对于512 * 512的lena图来说,笔者尝试值为0.4效果较佳。当然,如果真使用幂函数,记得在最外加上1,防止在0位置除0

        

Zigzag扫描

JPEG图像压缩探索_zigzag扫描(原创)-CSDN博客文章浏览阅读2k次。文章详细介绍了DCT变换后如何使用zigzag扫描算法将图像数据从高频到低频有序地转化为一维数据,以便于后续的霍夫曼编码等操作。该方法允许在不知原始二维数据边长的情况下,将二维数据转换为一维并能恢复原状。文中还提供了Java代码示例来实现这一过程。 https://blog.csdn.net/cjzjolly/article/details/129158254

借上方博客图一用,zigzag扫描顺序如上图所示,其中“扫描”的目的是为了把二维数组转一维数组,方便进一步编码压缩,采用“zigzag”顺序的理由是,这样扫描让尽可能多的‘0’ 靠在了一起,为随后的RLE编码提供基础。

RLE编码

关于该编码,下边这篇讲的挺不错。

https://zhuanlan.zhihu.com/p/1892905961586405848https://zhuanlan.zhihu.com/p/1892905961586405848经过RLE之后,就把重复很多的0给去除了 (其实这一点的效用和Huffman编码稍微有点打架,因为如果没有RLE,在量化后DCT矩阵的Huffman编码中,最主要能节省的空间就是重复的0)

Huffman编码

Huffman编码的知识⬇️

Huffman 编码原理详解(代码示例)_霍夫曼解码原理-CSDN博客文章浏览阅读2.9w次,点赞19次,收藏47次。本文介绍了Huffman编码的基本原理,包括路径长度、带权路径长度等概念,并详细阐述了Huffman树的构造过程及其编码实现。通过实例展示了如何选择最优二叉树以获得最短编码。 https://blog.csdn.net/qinglongzhan/article/details/80982067关于该编码压缩空间的机理:

我们知道一个int在存储空间占用4个字节 32位, 但是如果使用编码的方式以字节流存入,则根本用不了32位,在解码的时候只需保留Huffman的编码表即可。

在调试这一段代码的实践中笔者其实废了挺多力气,因为按字节流存入,再读取的时候由于不清楚大端读还是小端读导致调试的一头雾水。

解码过程

整体的解码过程,按上方流程反过来走一遍即可达成完整解码的效果。

http://www.xdnf.cn/news/7324.html

相关文章:

  • ai agent(智能体)开发 python高级应用8:crawl4ai 对用 LLMExtractionStrategy 和 python的 re 如何选择
  • 【C++】19. set和map的使用
  • Vue.js---立即执行的watch与回调执行时机
  • 【PhysUnits】4.4 零类型(Z0)及其算术运算(zero.rs)
  • 支持python的单片机有哪些
  • 高防CDN:让攻击流量“一键清零“的智能防御之道
  • 动态页面采集技术
  • Spring Boot入门案例(Spring Initializr方式,IDEA版)
  • 新时代的可观测性:拥抱 GuanceDB 3.0
  • 前端的面试笔记——HTMLJavaScript篇(二)前端页面性能检测
  • 2025B卷 - 华为OD机试七日集训第2期 - 按算法分类,由易到难,循序渐进,玩转OD(Python/JS/C/C++)
  • 192环境记录 zlm2
  • 大小端模式和消息的加密解密
  • IPV4详解和ensp基础命令
  • C#学习9——接口、抽象类
  • Web3:Ubuntu系统 使用Docker-compose方式部署blockscout浏览器配置版本-v5.2.3-beta+charts图表
  • 2025ICPC邀请赛南昌游记
  • 架构演变 -单体到云原生
  • C++学习:六个月从基础到就业——C++20:范围(Ranges)进阶
  • 高速光耦在通信行业的应用(六) | 5Mbps通信光耦的应用
  • 5月19日day30打卡
  • JavaWeb:SpringBoot处理全局异常(RestControllerAdvice)
  • 5.19本日总结
  • Windows逆向工程提升之PE文件的基本概念
  • leetcode hot100:解题思路大全
  • 对话即编程:如何用 Trae 的 @智能体 5 分钟修复一个复杂 Bug?
  • JESD204 ip核使用与例程分析(二)
  • ebpf-verifier
  • Visual Studio构建三剑客:生成/重新生成/清理解决方案的正确打开方式
  • 双条件拆分工作表,一键生成独立工作簿-Excel易用宝