news 2026/3/16 13:57:33

信号处理仿真:图像信号处理_(4).图像压缩与编码

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
信号处理仿真:图像信号处理_(4).图像压缩与编码

图像压缩与编码

引言

图像压缩与编码是图像信号处理中的重要技术之一,其目的是减少图像数据的存储空间或传输带宽,同时保持图像的视觉质量。在数字通信系统中,图像压缩编码技术不仅可以提高数据传输的效率,还可以降低存储成本。本节将详细介绍图像压缩的基本原理、常用算法以及编码技术,并通过具体的代码示例来演示这些技术的应用。

图像压缩的基本原理

图像压缩的基本原理是通过去除图像中的冗余信息来减少数据量。图像中的冗余信息可以分为以下几种类型:

  1. 空间冗余:相邻像素之间存在相似性,可以通过预测编码或变换编码来去除。
  2. 时间冗余:在视频序列中,相邻帧之间存在相似性,可以通过帧间预测编码来去除。
  3. 编码冗余:图像数据的表示方式中存在冗余,可以通过熵编码来优化。
  4. 心理视觉冗余:人类视觉系统对某些信息不敏感,可以通过量化来去除。

压缩类型

图像压缩可以分为无损压缩和有损压缩两大类:

  • 无损压缩:压缩后的图像在解压缩后与原始图像完全相同,常用算法有Huffman 编码算术编码
  • 有损压缩:压缩后的图像在解压缩后与原始图像存在一定的差异,但视觉上难以察觉,常用算法有JPEGJPEG 2000

常用的图像压缩算法

1. Huffman 编码

Huffman 编码是一种基于符号出现频率的变长编码方法,常用于无损压缩。其基本步骤如下:

  1. 统计符号频率:计算每个符号在图像中出现的频率。
  2. 构建 Huffman 树:根据符号频率构建 Huffman 树。
  3. 生成编码表:从 Huffman 树生成每个符号的编码。
  4. 编码图像数据:使用生成的编码表对图像数据进行编码。
  5. 解码图像数据:使用 Huffman 树对编码后的数据进行解码。
代码示例

以下是一个简单的 Python 代码示例,演示如何使用 Huffman 编码对图像数据进行压缩和解压缩。

importheapqimportosfromcollectionsimportdefaultdict,Counter# 定义 Huffman 节点类classHuffmanNode:def__init__(self,char,freq):self.char=char self.freq=freq self.left=Noneself.right=Nonedef__lt__(self,other):returnself.freq<other.freq# 构建 Huffman 树defbuild_huffman_tree(frequencies):heap=[HuffmanNode(char,freq)forchar,freqinfrequencies.items()]heapq.heapify(heap)whilelen(heap)>1:node1=heapq.heappop(heap)node2=heapq.heappop(heap)merged_node=HuffmanNode(None,node1.freq+node2.freq)merged_node.left=node1 merged_node.right=node2 heapq.heappush(heap,merged_node)returnheap[0]# 生成 Huffman 编码表defgenerate_huffman_codes(node,prefix="",code_dict=None):ifcode_dictisNone:code_dict={}ifnodeisnotNone:ifnode.charisnotNone:code_dict[node.char]=prefix generate_huffman_codes(node.left,prefix+"0",code_dict)generate_huffman_codes(node.right,prefix+"1",code_dict)returncode_dict# 编码图像数据defhuffman_encode(data,code_dict):encoded_data=''.join(code_dict[byte]forbyteindata)returnencoded_data# 解码图像数据defhuffman_decode(encoded_data,huffman_tree):decoded_data=[]current_node=huffman_treeforbitinencoded_data:ifbit=='0':current_node=current_node.leftelse:current_node=current_node.rightifcurrent_node.charisnotNone:decoded_data.append(current_node.char)current_node=huffman_treereturnbytes(decoded_data)# 主函数defmain():# 读取图像文件withopen('image.raw','rb')asfile:image_data=file.read()# 统计符号频率frequencies=Counter(image_data)# 构建 Huffman 树huffman_tree=build_huffman_tree(frequencies)# 生成 Huffman 编码表code_dict=generate_huffman_codes(huffman_tree)# 编码图像数据encoded_data=huffman_encode(image_data,code_dict)# 写入压缩文件withopen('image.huffman','w')asfile:file.write(encoded_data)# 读取压缩文件withopen('image.huffman','r')asfile:encoded_data=file.read()# 解码图像数据decoded_data=huffman_decode(encoded_data,huffman_tree)# 写入解压缩文件withopen('decoded_image.raw','wb')asfile:file.write(decoded_data)# 比较原始文件和解压文件的大小original_size=os.path.getsize('image.raw')compressed_size=os.path.getsize('image.huffman')print(f"Original Size:{original_size}bytes")print(f"Compressed Size:{compressed_size}bytes")if__name__=="__main__":main()

2. JPEG 压缩

JPEG(Joint Photographic Experts Group)是一种常用的有损压缩算法,广泛用于连续色调静止图像的压缩。JPEG 压缩的基本步骤如下:

  1. 颜色空间转换:将 RGB 图像转换为 YCbCr 颜色空间。
  2. 子采样:对 Cb 和 Cr 分量进行子采样,减少数据量。
  3. 分块:将图像分为 8x8 的块。
  4. DCT 变换:对每个块进行离散余弦变换(DCT)。
  5. 量化:对 DCT 系数进行量化,去除高频细节。
  6. 熵编码:对量化后的系数进行 Huffman 编码或算术编码。
代码示例

以下是一个使用 Python 和 OpenCV 库进行 JPEG 压缩的示例代码。

importcv2importnumpyasnp# 量化表QUANTIZATION_TABLE=np.array([[16,11,10,16,24,40,51,61],[12,12,14,19,26,58,60,55],[14,13,16,24,40,57,69,56],[14,17,22,29,51,87,80,62],[18,22,37,56,68,109,103,77],[24,35,55,64,81,104,113,92],[49,64,78,87,103,121,120,101],[72,92,95,98,112,100,103,99]],dtype=np.float32)# DCT 变换defdct2(block):returncv2.dct(block)# 逆 DCT 变换defidct2(block):returncv2.idct(block)# 量化defquantize(block,quantization_table):returnnp.round(block/quantization_table)# 逆量化defdequantize(block,quantization_table):returnblock*quantization_table# JPEG 压缩defjpeg_compress(image,quantization_table):# 颜色空间转换image_yuv=cv2.cvtColor(image,cv2.COLOR_BGR2YCrCb)# 分块y,cr,cb=cv2.split(image_yuv)y_blocks=[dct2(y[i:i+8,j:j+8])foriinrange(0,y.shape[0],8)forjinrange(0,y.shape[1],8)]cr_blocks=[dct2(cr[i:i+8,j:j+8])foriinrange(0,cr.shape[0],8)forjinrange(0,cr.shape[1],8)]cb_blocks=[dct2(cb[i:i+8,j:j+8])foriinrange(0,cb.shape[0],8)forjinrange(0,cb.shape[1],8)]# 量化y_blocks_quantized=[quantize(block,quantization_table)forblockiny_blocks]cr_blocks_quantized=[quantize(block,quantization_table)forblockincr_blocks]cb_blocks_quantized=[quantize(block,quantization_table)forblockincb_blocks]# 重新组合图像y_quantized=cv2.merge(y_blocks_quantized,8,y.shape)cr_quantized=cv2.merge(cr_blocks_quantized,8,cr.shape)cb_quantized=cv2.merge(cb_blocks_quantized,8,cb.shape)image_quantized=cv2.merge([y_quantized,cr_quantized,cb_quantized])# 逆颜色空间转换image_compressed=cv2.cvtColor(image_quantized,cv2.COLOR_YCrCb2BGR)returnimage_compressed# JPEG 解压缩defjpeg_decompress(image,quantization_table):# 颜色空间转换image_yuv=cv2.cvtColor(image,cv2.COLOR_BGR2YCrCb)# 分块y,cr,cb=cv2.split(image_yuv)y_blocks=[dct2(y[i:i+8,j:j+8])foriinrange(0,y.shape[0],8)forjinrange(0,y.shape[1],8)]cr_blocks=[dct2(cr[i:i+8,j:j+8])foriinrange(0,cr.shape[0],8)forjinrange(0,cr.shape[1],8)]cb_blocks=[dct2(cb[i:i+8,j:j+8])foriinrange(0,cb.shape[0],8)forjinrange(0,cb.shape[1],8)]# 逆量化y_blocks_dequantized=[dequantize(block,quantization_table)forblockiny_blocks]cr_blocks_dequantized=[dequantize(block,quantization_table)forblockincr_blocks]cb_blocks_dequantized=[dequantize(block,quantization_table)forblockincb_blocks]# 逆 DCT 变换y_blocks_idct=[idct2(block)forblockiny_blocks_dequantized]cr_blocks_idct=[idct2(block)forblockincr_blocks_dequantized]cb_blocks_idct=[idct2(block)forblockincb_blocks_dequantized]# 重新组合图像y_idct=cv2.merge(y_blocks_idct,8,y.shape)cr_idct=cv2.merge(cr_blocks_idct,8,cr.shape)cb_idct=cv2.merge(cb_blocks_idct,8,cb.shape)image_idct=cv2.merge([y_idct,cr_idct,cb_idct])# 逆颜色空间转换image_decompressed=cv2.cvtColor(image_idct,cv2.COLOR_YCrCb2BGR)returnimage_decompressed# 主函数defmain():# 读取图像image=cv2.imread('image.jpg')# JPEG 压缩compressed_image=jpeg_compress(image,QUANTIZATION_TABLE)cv2.imwrite('compressed_image.jpg',compressed_image)# 读取压缩图像compressed_image=cv2.imread('compressed_image.jpg')# JPEG 解压缩decompressed_image=jpeg_decompress(compressed_image,QUANTIZATION_TABLE)cv2.imwrite('decompressed_image.jpg',decompressed_image)if__name__=="__main__":main()

3. JPEG 2000 压缩

JPEG 2000 是 JPEG 的改进版本,使用小波变换(Wavelet Transform)和嵌套块编码(EBCOT)技术,提供了更高的压缩比和更好的图像质量。JPEG 2000 的基本步骤如下:

  1. 颜色空间转换:将 RGB 图像转换为 YCbCr 颜色空间。
  2. 小波变换:对每个颜色分量进行小波变换。
  3. 量化:对小波系数进行量化。
  4. 嵌套块编码:对量化后的系数进行嵌套块编码。
  5. 熵编码:对嵌套块编码后的数据进行 Huffman 编码或算术编码。
代码示例

以下是一个使用 OpenCV 和 PyWavelets 库进行 JPEG 2000 压缩的示例代码。

importcv2importpywtimportnumpyasnp# 小波变换defwavelet_transform(image,wavelet='db1'):# 颜色空间转换image_yuv=cv2.cvtColor(image,cv2.COLOR_BGR2YCrCb)y,cr,cb=cv2.split(image_yuv)# 小波变换y_coeffs=pywt.wavedec2(y,wavelet)cr_coeffs=pywt.wavedec2(cr,wavelet)cb_coeffs=pywt.wavedec2(cb,wavelet)returny_coeffs,cr_coeffs,cb_coeffs# 逆小波变换definverse_wavelet_transform(y_coeffs,cr_coeffs,cb_coeffs,wavelet='db1'):y=pywt.waverec2(y_coeffs,wavelet)cr=pywt.waverec2(cr_coeffs,wavelet)cb=pywt.waverec2(cb_coeffs,wavelet)# 重新组合图像image_yuv=cv2.merge([y,cr,cb])# 逆颜色空间转换image=cv2.cvtColor(image_yuv,cv2.COLOR_YCrCb2BGR)returnimage# 量化defquantize_coeffs(coeffs,factor=1):return[np.round(c/factor)forcincoeffs]# 逆量化defdequantize_coeffs(coeffs,factor=1):return[c*factorforcincoeffs]# JPEG 2000 压缩defjpeg2000_compress(image,wavelet='db1',factor=1):y_coeffs,cr_coeffs,cb_coeffs=wavelet_transform(image,wavelet)y_coeffs_quantized=quantize_coeffs(y_coeffs,factor)cr_coeffs_quantized=quantize_coeffs(cr_coeffs,factor)cb_coeffs_quantized=quantize_coeffs(cb_coeffs,factor)returny_coeffs_quantized,cr_coeffs_quantized,cb_coeffs_quantized# JPEG 2000 解压缩defjpeg2000_decompress(y_coeffs,cr_coeffs,cb_coeffs,wavelet='db1',factor=1):y_coeffs_dequantized=dequantize_coeffs(y_coeffs,factor)cr_coeffs_dequantized=dequantize_coeffs(cr_coeffs,factor)cb_coeffs_dequantized=dequantize_coeffs(cb_coeffs,factor)decompressed_image=inverse_wavelet_transform(y_coeffs_dequantized,cr_coeffs_dequantized,cb_coeffs_dequantized,wavelet)returndecompressed_image# 主函数defmain():# 读取图像image=cv2.imread('image.jpg')# JPEG 2000 压缩y_coeffs,cr_coeffs,cb_coeffs=jpeg2000_compress(image,wavelet='db1',factor=1)# 保存压缩后的系数np.save('y_coeffs.npy',y_coeffs)np.save('cr_coeffs.npy',cr_coeffs)np.save('cb_coeffs.npy',cb_coeffs)# 读取压缩后的系数y_coeffs=np.load('y_coeffs.npy')cr_coeffs=np.load('cr_coeffs.npy')cb_coeffs=np.load('cb_coeffs.npy')# JPEG 2000 解压缩decompressed_image=jpeg2000_decompress(y_coeffs,cr_coeffs,cb_coeffs,wavelet='db1',factor=1)# 保存解压缩后的图像cv2.imwrite('decompressed_image.jpg',decompressed_image)if__name__=="__main__":main()

编码技术

1. 熵编码

熵编码是一种基于信息熵的无损编码技术,常用的熵编码方法有Huffman 编码算术编码

Huffman 编码

Huffman 编码通过构建 Huffman 树来生成每个符号的变长编码,使得出现频率高的符号使用较短的编码,出现频率低的符号使用较长的编码。Huffman 编码的具体实现已经在上面的代码示例中给出。

算术编码

算术编码是一种更高级的无损编码技术,通过将符号序列映射到一个区间内的小数来实现编码。算术编码的压缩比通常比 Huffman 编码高,但实现复杂度也更高。

2. 嵌套块编码(EBCOT)

嵌套块编码(EBCOT)是 JPEG 2000 中用于编码量化后的小波系数的技术。EBCOT 通过将小波系数分为多个嵌套块,对每个块进行独立编码,从而提高压缩效率。

应用案例

1. 医学图像压缩

在医学领域,图像压缩技术可以显著减少图像存储和传输的成本。例如,使用 JPEG 2000 压缩可以保留更多的高频细节,对于诊断和治疗具有重要意义。

2. 卫星图像传输

在卫星通信领域,图像压缩技术同样发挥着重要作用。卫星图像通常具有较高的分辨率和较大的数据量,这使得传输和存储变得非常昂贵。通过使用高效的图像压缩算法,可以显著减少传输带宽和存储成本,同时保持图像的视觉质量。

压缩需求

卫星图像传输面临的主要挑战包括:

  • 带宽限制:卫星通信带宽有限,需要通过压缩来减少数据量。
  • 存储成本:卫星存储容量有限,需要高效压缩来存储更多的图像数据。
  • 实时性:卫星图像传输通常要求实时或近实时,压缩算法需要在保证压缩效率的同时具有较低的计算复杂度。
技术选择

在卫星图像传输中,常用的图像压缩技术包括:

  • JPEG:适用于一般的静止图像,可以在较低的计算复杂度下提供较好的压缩比。
  • JPEG 2000:适用于高分辨率图像,可以在较高的压缩比下保持较好的图像质量。
  • 小波变换:通过多分辨率分析,可以更好地保留图像的高频细节。

3. 视频压缩

视频压缩是图像压缩的一个扩展,用于减少视频数据的存储空间或传输带宽。视频压缩技术不仅需要考虑空间冗余,还需要处理时间冗余。常用的视频压缩标准包括MPEG-1MPEG-2H.264H.265

基本步骤

视频压缩的基本步骤如下:

  1. 颜色空间转换:将 RGB 视频帧转换为 YCbCr 颜色空间。
  2. 帧内压缩:对每个帧进行类似 JPEG 的压缩。
  3. 帧间压缩:利用相邻帧之间的相似性进行预测编码。
  4. 熵编码:对压缩后的数据进行 Huffman 编码或算术编码。

4. 互联网图像传输

在互联网应用中,图像压缩技术可以显著提高网页加载速度和用户体验。常见的互联网图像压缩格式包括JPEGPNGWebP

压缩需求

互联网图像传输面临的主要挑战包括:

  • 加载速度:用户期望网页内容能够快速加载,压缩可以减少数据传输时间。
  • 带宽优化:通过压缩减少带宽使用,降低网络成本。
  • 视觉质量:保持图像的视觉质量,避免压缩带来的明显失真。
技术选择

在互联网图像传输中,常用的图像压缩技术包括:

  • JPEG:适用于一般的静止图像,可以在较低的计算复杂度下提供较好的压缩比。
  • PNG:适用于需要无损压缩的图像,支持透明度。
  • WebP:由 Google 开发,结合了有损和无损压缩技术,提供了较高的压缩比和较好的视觉质量。

结论

图像压缩与编码技术在数字通信系统中扮演着重要角色,不仅提高了数据传输的效率,还降低了存储成本。通过去除图像中的冗余信息,这些技术能够在减少数据量的同时保持图像的视觉质量。本文介绍了几种常用的图像压缩算法,包括 Huffman 编码、JPEG 压缩和 JPEG 2000 压缩,并通过具体的代码示例展示了这些技术的应用。未来,随着计算能力的提升和新算法的不断涌现,图像压缩技术将更加高效和智能,为各个领域的应用提供更强的支持。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/13 13:31:23

【开题答辩全过程】以 南工计算机等级网站为例,包含答辩的问题和答案

个人简介 一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等 开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。 感谢大家…

作者头像 李华
网站建设 2026/3/13 21:24:27

震撼来袭!AI应用架构师的智能金融系统设计创新趋势

震撼来袭&#xff01;AI应用架构师的智能金融系统设计创新趋势 引言&#xff1a;当AI遇见金融——一场效率与信任的革命 凌晨3点&#xff0c;某股份制银行的信贷审批员李阳揉了揉眼睛&#xff0c;看着电脑里堆积的127份贷款申请材料&#xff0c;叹了口气。这些材料需要逐一核…

作者头像 李华
网站建设 2026/3/14 9:30:12

强烈建议去听前端技术博客,真的能提level

&#x1f31f; 真心建议前端方向的同学&#xff0c;把碎片时间留给优质的前端干货博客&#xff0c;就像开启一个“随身知识胶囊”&#xff0c;把碎片时段&#xff0c;变成你在用户界面与系统底层交界处深化理解的黄金窗口。 &#x1f539; 核心基石&#xff1a;《JavaScript语…

作者头像 李华
网站建设 2026/3/14 11:05:23

计算机Java毕设实战-基于springboot的城市公园综合服务系统设计与实现小程序【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/3/12 12:31:27

风雪守通信 初心护畅通—临沂郯城联通抢修团队风雪中的坚守

寒潮突至&#xff0c;沂蒙大地迎来降雪天气&#xff0c;低温与积雪给通信网络带来严峻考验。关键时刻&#xff0c;郯城联通员工以雪为令、向险而行&#xff0c;用专业与坚守筑起通信保障的“风雪防线”&#xff0c;上演了两场紧急抢修的暖心故事。 单人攻坚&#xff0c;企业园…

作者头像 李华
网站建设 2026/3/14 9:25:06

vllm设置参数 llm调用显存使用1gb

- 模型加载仅占用 0.32 GiB 内存 - 可用 KV 缓存内存&#xff1a; 0.57 GiB - 总显存使用&#xff1a;约 0.89 GiB &#xff08;符合 1GB 以内的要求&#xff09; (TraeAI-6) ~/my_python_server/wsl [1] $ cd /root/my_python_server/wsl ; /root/my_python_server/vllm-env…

作者头像 李华