核心内容摘要
“18摸app”
图像压缩与编码引言图像压缩与编码是图像信号处理中的重要技术之一其目的是减少图像数据的存储空间或传输带宽同时保持图像的视觉质量。
在数字通信系统中图像压缩编码技术不仅可以提高数据传输的效率还可以降低存储成本。
本节将详细介绍图像压缩的基本原理、常用算法以及编码技术并通过具体的代码示例来演示这些技术的应用。
图像压缩的基本原理图像压缩的基本原理是通过去除图像中的冗余信息来减少数据量。
图像中的冗余信息可以分为以下几种类型空间冗余相邻像素之间存在相似性可以通过预测编码或变换编码来去除。
时间冗余在视频序列中相邻帧之间存在相似性可以通过帧间预测编码来去除。
编码冗余图像数据的表示方式中存在冗余可以通过熵编码来优化。
心理视觉冗余人类视觉系统对某些信息不敏感可以通过量化来去除。
压缩类型图像压缩可以分为无损压缩和有损压缩两大类无损压缩压缩后的图像在解压缩后与原始图像完全相同常用算法有Huffman 编码和算术编码。
有损压缩压缩后的图像在解压缩后与原始图像存在一定的差异但视觉上难以察觉常用算法有JPEG和JPEG 2000。
常用的图像压缩算法
Huffman 编码Huffman 编码是一种基于符号出现频率的变长编码方法常用于无损压缩。
其基本步骤如下统计符号频率计算每个符号在图像中出现的频率。
构建 Huffman 树根据符号频率构建 Huffman 树。
生成编码表从 Huffman 树生成每个符号的编码。
编码图像数据使用生成的编码表对图像数据进行编码。
解码图像数据使用 Huffman 树对编码后的数据进行解码。
代码示例以下是一个简单的 Python 代码示例演示如何使用 Huffman 编码对图像数据进行压缩和解压缩。
importheapqimportosfromcollectionsimportdefaultdict,Counter# 定义 Huffman 节点类classHuffmanNode:def__init__(self,char,freq):self.charchar self.freqfreq self.leftNoneself.rightNonedef__lt__(self,other):returnself.freqother.freq# 构建 Huffman 树defbuild_huffman_tree(frequencies):heap[HuffmanNode(char,freq)forchar,freqinfrequencies.items()]heapq.heapify(heap)whilelen(heap)1:node1heapq.heappop(heap)node2heapq.heappop(heap)merged_nodeHuffmanNode(None,node
freqnode
freq)merged_node.leftnode1 merged_node.rightnode2 heapq.heappush(heap,merged_node)returnheap[0]# 生成 Huffman 编码表defgenerate_huffman_codes(node,prefix,code_dictNone):ifcode_dictisNone:code_dict{}ifnodeisnotNone:ifnode.charisnotNone:code_dict[node.char]prefix generate_huffman_codes(node.left,prefix0,code_dict)generate_huffman_codes(node.right,prefix1,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_nodehuffman_treeforbitinencoded_data:ifbit0:current_nodecurrent_node.leftelse:current_nodecurrent_node.rightifcurrent_node.charisnotNone:decoded_data.append(current_node.char)current_nodehuffman_treereturnbytes(decoded_data)# 主函数defmain():# 读取图像文件withopen(image.raw,rb)asfile:image_datafile.read()# 统计符号频率frequenciesCounter(image_data)# 构建 Huffman 树huffman_treebuild_huffman_tree(frequencies)# 生成 Huffman 编码表code_dictgenerate_huffman_codes(huffman_tree)# 编码图像数据encoded_datahuffman_encode(image_data,code_dict)# 写入压缩文件withopen(image.huffman,w)asfile:file.write(encoded_data)# 读取压缩文件withopen(image.huffman,r)asfile:encoded_datafile.read()# 解码图像数据decoded_datahuffman_decode(encoded_data,huffman_tree)# 写入解压缩文件withopen(decoded_image.raw,wb)asfile:file.write(decoded_data)# 比较原始文件和解压文件的大小original_sizeos.path.getsize(image.raw)compressed_sizeos.path.getsize(image.huffman)print(fOriginal Size:{original_size}bytes)print(fCompressed Size:{compressed_size}bytes)if__name____main__:main()
JPEG 压缩JPEGJoint Photographic Experts Group是一种常用的有损压缩算法广泛用于连续色调静止图像的压缩。
JPEG 压缩的基本步骤如下颜色空间转换将 RGB 图像转换为 YCbCr 颜色空间。
子采样对 Cb 和 Cr 分量进行子采样减少数据量。
分块将图像分为 8x8 的块。
DCT 变换对每个块进行离散余弦变换DCT。
量化对 DCT 系数进行量化去除高频细节。
熵编码对量化后的系数进行 Huffman 编码或算术编码。
代码示例以下是一个使用 Python 和 OpenCV 库进行 JPEG 压缩的示例代码。
importcv2importnumpyasnp# 量化表QUANTIZATION_TABLEnp.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]],dtypenp.float
# DCT 变换defdct2(block):returncv
dct(block)# 逆 DCT 变换defidct2(block):returncv
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_yuvcv
cvtColor(image,cv
COLOR_BGR2YCrCb)# 分块y,cr,cbcv
split(image_yuv)y_blocks[dct2(y[i:i8,j:j8])foriinrange(0,y.shape[0],
forjinrange(0,y.shape[1],
]cr_blocks[dct2(cr[i:i8,j:j8])foriinrange(0,cr.shape[0],
forjinrange(0,cr.shape[1],
]cb_blocks[dct2(cb[i:i8,j:j8])foriinrange(0,cb.shape[0],
forjinrange(0,cb.shape[1],
]# 量化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_quantizedcv
merge(y_blocks_quantized,8,y.shape)cr_quantizedcv
merge(cr_blocks_quantized,8,cr.shape)cb_quantizedcv
merge(cb_blocks_quantized,8,cb.shape)image_quantizedcv
merge([y_quantized,cr_quantized,cb_quantized])# 逆颜色空间转换image_compressedcv
cvtColor(image_quantized,cv
COLOR_YCrCb2BGR)returnimage_compressed# JPEG 解压缩defjpeg_decompress(image,quantization_table):# 颜色空间转换image_yuvcv
cvtColor(image,cv
COLOR_BGR2YCrCb)# 分块y,cr,cbcv
split(image_yuv)y_blocks[dct2(y[i:i8,j:j8])foriinrange(0,y.shape[0],
forjinrange(0,y.shape[1],
]cr_blocks[dct2(cr[i:i8,j:j8])foriinrange(0,cr.shape[0],
forjinrange(0,cr.shape[1],
]cb_blocks[dct2(cb[i:i8,j:j8])foriinrange(0,cb.shape[0],
forjinrange(0,cb.shape[1],
]# 逆量化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_idctcv
merge(y_blocks_idct,8,y.shape)cr_idctcv
merge(cr_blocks_idct,8,cr.shape)cb_idctcv
merge(cb_blocks_idct,8,cb.shape)image_idctcv
merge([y_idct,cr_idct,cb_idct])# 逆颜色空间转换image_decompressedcv
cvtColor(image_idct,cv
COLOR_YCrCb2BGR)returnimage_decompressed# 主函数defmain():# 读取图像imagecv
imread(image.jpg)# JPEG 压缩compressed_imagejpeg_compress(image,QUANTIZATION_TABLE)cv
imwrite(compressed_image.jpg,compressed_image)# 读取压缩图像compressed_imagecv
imread(compressed_image.jpg)# JPEG 解压缩decompressed_imagejpeg_decompress(compressed_image,QUANTIZATION_TABLE)cv
imwrite(decompressed_image.jpg,decompressed_image)if__name____main__:main()
JPEG 2000 压缩JPEG 2000 是 JPEG 的改进版本使用小波变换Wavelet Transform和嵌套块编码EBCOT技术提供了更高的压缩比和更好的图像质量。
JPEG 2000 的基本步骤如下颜色空间转换将 RGB 图像转换为 YCbCr 颜色空间。
小波变换对每个颜色分量进行小波变换。
量化对小波系数进行量化。
嵌套块编码对量化后的系数进行嵌套块编码。
熵编码对嵌套块编码后的数据进行 Huffman 编码或算术编码。
代码示例以下是一个使用 OpenCV 和 PyWavelets 库进行 JPEG 2000 压缩的示例代码。
importcv2importpywtimportnumpyasnp# 小波变换defwavelet_transform(image,waveletdb
:# 颜色空间转换image_yuvcv
cvtColor(image,cv
COLOR_BGR2YCrCb)y,cr,cbcv
split(image_yuv)# 小波变换y_coeffspywt.wavedec2(y,wavelet)cr_coeffspywt.wavedec2(cr,wavelet)cb_coeffspywt.wavedec2(cb,wavelet)returny_coeffs,cr_coeffs,cb_coeffs# 逆小波变换definverse_wavelet_transform(y_coeffs,cr_coeffs,cb_coeffs,waveletdb
:ypywt.waverec2(y_coeffs,wavelet)crpywt.waverec2(cr_coeffs,wavelet)cbpywt.waverec2(cb_coeffs,wavelet)# 重新组合图像image_yuvcv
merge([y,cr,cb])# 逆颜色空间转换imagecv
cvtColor(image_yuv,cv
COLOR_YCrCb2BGR)returnimage# 量化defquantize_coeffs(coeffs,factor
:return[np.round(c/factor)forcincoeffs]# 逆量化defdequantize_coeffs(coeffs,factor
:return[c*factorforcincoeffs]# JPEG 2000 压缩defjp
_compress(image,waveletdb1,factor
:y_coeffs,cr_coeffs,cb_coeffswavelet_transform(image,wavelet)y_coeffs_quantizedquantize_coeffs(y_coeffs,factor)cr_coeffs_quantizedquantize_coeffs(cr_coeffs,factor)cb_coeffs_quantizedquantize_coeffs(cb_coeffs,factor)returny_coeffs_quantized,cr_coeffs_quantized,cb_coeffs_quantized# JPEG 2000 解压缩defjp
_decompress(y_coeffs,cr_coeffs,cb_coeffs,waveletdb1,factor
:y_coeffs_dequantizeddequantize_coeffs(y_coeffs,factor)cr_coeffs_dequantizeddequantize_coeffs(cr_coeffs,factor)cb_coeffs_dequantizeddequantize_coeffs(cb_coeffs,factor)decompressed_imageinverse_wavelet_transform(y_coeffs_dequantized,cr_coeffs_dequantized,cb_coeffs_dequantized,wavelet)returndecompressed_image# 主函数defmain():# 读取图像imagecv
imread(image.jpg)# JPEG 2000 压缩y_coeffs,cr_coeffs,cb_coeffsjp
_compress(image,waveletdb1,factor
# 保存压缩后的系数np.save(y_coeffs.npy,y_coeffs)np.save(cr_coeffs.npy,cr_coeffs)np.save(cb_coeffs.npy,cb_coeffs)# 读取压缩后的系数y_coeffsnp.load(y_coeffs.npy)cr_coeffsnp.load(cr_coeffs.npy)cb_coeffsnp.load(cb_coeffs.npy)# JPEG 2000 解压缩decompressed_imagejp
_decompress(y_coeffs,cr_coeffs,cb_coeffs,waveletdb1,factor
# 保存解压缩后的图像cv
imwrite(decompressed_image.jpg,decompressed_image)if__name____main__:main()编码技术
熵编码熵编码是一种基于信息熵的无损编码技术常用的熵编码方法有Huffman 编码和算术编码。
Huffman 编码Huffman 编码通过构建 Huffman 树来生成每个符号的变长编码使得出现频率高的符号使用较短的编码出现频率低的符号使用较长的编码。
Huffman 编码的具体实现已经在上面的代码示例中给出。
算术编码算术编码是一种更高级的无损编码技术通过将符号序列映射到一个区间内的小数来实现编码。
算术编码的压缩比通常比 Huffman 编码高但实现复杂度也更高。
嵌套块编码EBCOT嵌套块编码EBCOT是 JPEG 2000 中用于编码量化后的小波系数的技术。
EBCOT 通过将小波系数分为多个嵌套块对每个块进行独立编码从而提高压缩效率。
应用案例
医学图像压缩在医学领域图像压缩技术可以显著减少图像存储和传输的成本。
例如使用 JPEG 2000 压缩可以保留更多的高频细节对于诊断和治疗具有重要意义。
卫星图像传输在卫星通信领域图像压缩技术同样发挥着重要作用。
卫星图像通常具有较高的分辨率和较大的数据量这使得传输和存储变得非常昂贵。
通过使用高效的图像压缩算法可以显著减少传输带宽和存储成本同时保持图像的视觉质量。
压缩需求卫星图像传输面临的主要挑战包括带宽限制卫星通信带宽有限需要通过压缩来减少数据量。
存储成本卫星存储容量有限需要高效压缩来存储更多的图像数据。
实时性卫星图像传输通常要求实时或近实时压缩算法需要在保证压缩效率的同时具有较低的计算复杂度。
技术选择在卫星图像传输中常用的图像压缩技术包括JPEG适用于一般的静止图像可以在较低的计算复杂度下提供较好的压缩比。
JPEG 2000适用于高分辨率图像可以在较高的压缩比下保持较好的图像质量。
小波变换通过多分辨率分析可以更好地保留图像的高频细节。
视频压缩视频压缩是图像压缩的一个扩展用于减少视频数据的存储空间或传输带宽。
视频压缩技术不仅需要考虑空间冗余还需要处理时间冗余。
常用的视频压缩标准包括MPEG-
MPEG-
H.264和H.265。
基本步骤视频压缩的基本步骤如下颜色空间转换将 RGB 视频帧转换为 YCbCr 颜色空间。
帧内压缩对每个帧进行类似 JPEG 的压缩。
帧间压缩利用相邻帧之间的相似性进行预测编码。
熵编码对压缩后的数据进行 Huffman 编码或算术编码。
互联网图像传输在互联网应用中图像压缩技术可以显著提高网页加载速度和用户体验。
常见的互联网图像压缩格式包括JPEG、PNG和WebP。
压缩需求互联网图像传输面临的主要挑战包括加载速度用户期望网页内容能够快速加载压缩可以减少数据传输时间。
带宽优化通过压缩减少带宽使用降低网络成本。
视觉质量保持图像的视觉质量避免压缩带来的明显失真。
技术选择在互联网图像传输中常用的图像压缩技术包括JPEG适用于一般的静止图像可以在较低的计算复杂度下提供较好的压缩比。
PNG适用于需要无损压缩的图像支持透明度。
WebP由 Google 开发结合了有损和无损压缩技术提供了较高的压缩比和较好的视觉质量。
结论图像压缩与编码技术在数字通信系统中扮演着重要角色不仅提高了数据传输的效率还降低了存储成本。
通过去除图像中的冗余信息这些技术能够在减少数据量的同时保持图像的视觉质量。
本文介绍了几种常用的图像压缩算法包括 Huffman 编码、JPEG 压缩和 JPEG 2000 压缩并通过具体的代码示例展示了这些技术的应用。
未来随着计算能力的提升和新算法的不断涌现图像压缩技术将更加高效和智能为各个领域的应用提供更强的支持。