【MATLAB图像处理】图像的压缩比、霍夫曼编码、JPEG编码

2023-10-09 20:59

本文主要是介绍【MATLAB图像处理】图像的压缩比、霍夫曼编码、JPEG编码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        图像压缩是一种通过减少图像数据的表示形式来减小图像文件大小的过程。压缩图像可以节省存储空间并加快图像传输速度,而且在网络传输和存储方面非常有用。

图像压缩有两种主要类型:有损压缩和无损压缩。

  1. 有损压缩:有损压缩通过丢弃一些图像数据的细节来减小文件大小。这种压缩方法会牺牲一些图像质量,但通常可以实现更高的压缩比。在图像中,人眼对于某些颜色和细节的变化并不敏感,因此有损压缩算法利用这一点来去除冗余信息。常见的有损压缩格式包括JPEG(Joint Photographic Experts Group)。

  2. 无损压缩:无损压缩通过重新编码图像数据,以减小文件大小,同时保持图像的完整性,没有损失任何信息。无损压缩方法通常适用于对图像质量要求较高的情况,如图像编辑和医学成像。常见的无损压缩格式包括PNG(Portable Network Graphics)和GIF(Graphics Interchange Format)。

压缩图像可以使用各种压缩算法和工具来实现。常见的图像处理软件和编程语言通常提供了压缩图像的功能。在实际应用中,根据图像的特性和要求选择适当的压缩方法和参数非常重要。

 1.图像的压缩比计算

图1.1 压缩前与压缩质量quality=5时对比图

图1.2 程序运算得到的压缩比

图1.3 利用imfinfo函数查看原始图像信息

图1.4 利用imfinfo函数查看压缩图像信息

当压缩因子quality=5时,原始图像与压缩图像对比如图1.1所示。利用imratio函数计算压缩比,得到的结果如图1.2所示。调用函数“imfinfo ‘filename.jpg ’”可以对图像的信息进行查看(或使用“whos”对数组数据进行查看),如图1.3和1.4所示。

通过观察图像信息我们可以发现,利用两幅图的文件大小(Filesize)可以手动计算得到CR = \frac{22235}{2780} = 7.99820144≈7.9982,与imratio函数计算值相同。因此可以验证压缩比CR就是原始图像与压缩图像数据大小之比。同时,两幅图的长宽比是相同的,但比特深度是不相同的,而使用两幅图的长宽比×比特深度得到的值之比为3并不是压缩比CR,而我们可以发现,两幅图的编码方式都是霍夫曼编码,因此文件大小是经过霍夫曼编码后得到的值,应该使用文件大小来计算压缩比。当压缩质量越高时,压缩比越小。

%图像压缩比 CR的计算
I=imread('elephant.jpg');
f=rgb2gray(I);
imwrite(f,'compressed_elephant.jpg','quality',5);
imwrite(f,'gray_elephant.jpg');
f25=imread('compressed_elephant.jpg');
Cr=imratio('elephant.jpg','compressed_elephant.jpg')
title('Compressed');
imfinfo compressed_elephant.jpg
imfinfo elephant.jpg
subplot(1,2,1),imshow(f),title('Original Image');
subplot(1,2,2),imshow('compressed_elephant.jpg'),title('Compressed Image');


2.霍夫曼编码

        霍夫曼编码是一种无损压缩算法,可以通过减少图像数据的冗余性来压缩图像。它利用每个像素在图像中出现的概率来为每个像素分配唯一的编码。出现频率高的像素将被赋予短编码,而出现频率低的像素将被赋予长编码。这样,整个图像可以使用较少的比特数来表示。

下面是使用霍夫曼编码对图像进行压缩的基本步骤:
  1.首先,将图像分成不同的块或区域,以便对它们进行单独的压缩。每个像素在图像中出现的频率可以通过统计其在每个块中出现的次数来估计。
  2.使用霍夫曼编码算法为每个像素分配唯一的编码。这可以通过构建霍夫曼树来实现。在霍夫曼树中,出现频率高的像素将被放置在树的较低层,而出现频率低的像素将被放置在树的较高层。每个像素的编码是从根到其所在叶子节点的路径上的0和1序列。因为每个像素的编码都是唯一的,所以可以使用它们来表示图像数据。
  3. 将每个块中的像素编码为它们的霍夫曼编码,并将编码后的像素数据存储在文件中。由于每个像素编码的长度不同,所以需要使用位填充技术来确保它们占用相同的比特数。
  4.在解压缩图像时,首先需要读取文件中的霍夫曼编码,并将它们重新映射为像素值。这可以通过使用相同的霍夫曼树来实现。
  5.对于每个块中的编码像素,将它们解码为原始像素值,并将它们组合成原始图像。
        需要注意的是,霍夫曼编码可以减少图像数据的冗余性,但它不适用于所有类型的图像。对于具有大量随机噪声或高频细节的图像,霍夫曼编码的效果可能不好。此外,在进行图像压缩时,还应该考虑到压缩率和解压速度之间的权衡,以选择最合适的压缩算法。

        霍夫曼树(Huffman Tree),也称作最优二叉树(Optimal Binary Tree),是一种用于构建霍夫曼编码的特殊二叉树。霍夫曼树的构建过程是基于霍夫曼编码算法的,它利用每个字符出现的频率作为权值构建一棵树,以便字符出现频率高的节点位于树的底部,而出现频率低的节点位于树的顶部。这使得字符集中出现频率高的字符可以被编码为较短的比特串,而出现频率低的字符可以被编码为较长的比特串,从而实现对数据的压缩。
        霍夫曼树的构建过程是通过不断地选择两个权值最小的节点来合并生成新的节点,并将新节点的权值设置为两个子节点的权值之和。这个过程一直进行到只剩下一个节点为止,这个节点就是整个霍夫曼树的根节点。在构建的过程中,每个节点都可以表示一个字符或一个比特串,而每个叶子节点都表示一个字符。
霍夫曼树的结构具有如下特点:
1. 它是一棵二叉树,即每个节点最多有两个子节点。
2. 叶子节点表示的字符或比特串的权值为正整数,可以表示为节点的频率。
3. 内部节点不表示字符或比特串,它们只是用来合并子节点的权值。
4. 根节点到每个叶子节点的路径表示对应字符的霍夫曼编码,该编码是唯一的。
通过构建霍夫曼树,我们可以将一个字符集中的所有字符编码为唯一的比特串,从而实现对数据的无损压缩。 

`huffman()`函数和`mat2huff()`函数都是实现霍夫曼编码压缩的函数,但是它们的输入数据类型有所不同。
        `huffman()`函数是用于对一维向量进行压缩的,输入参数为符号数组和概率数组,输出为编码表。符号数组是一维向量,包含需要进行编码压缩的数据,例如音频、文本等。概率数组则是对每个符号出现概率的估计。`huffman()`函数的输出是一个结构体,包含每个符号的霍夫曼编码和对应的码字长度。
        `mat2huff()`函数则是用于对二维矩阵或多维数组进行压缩的,输入参数为需要压缩的数据和编码表,输出为压缩后的数据。在图像压缩中,可以将图像转换为灰度图像后,每个像素值作为符号,对每个像素值出现的概率进行统计,生成编码表。然后,将原始的灰度图像使用生成的编码表进行编码压缩,压缩后的数据是一维的比特流。
因此,两个函数虽然都是用于实现霍夫曼编码压缩,但是输入的数据类型和输出的结果有所不同,适用于不同类型的数据。 

(1)对向量进行霍夫曼编码(huffman)

图2.1 向量数据内容

图2.1 利用霍夫曼方法对向量编码结果

        对向量进行霍夫曼编码具体实施步骤为:重排数组得到p_new[0.125,0.1875,0.1875,0.5],选最小的两个概率合并为新的节点,插入数组排序后的数组,得到p_new[0.1875,0.3125,0.5];重复上述步骤,得到p_new[0.5,0.5;绘制霍夫曼树,通过左支与右支分别编码0与1得到霍夫曼编码。

 图2.2 对向量编码的霍夫曼树

%对p = [0.1875 0.5 0.125 0.1875]进行霍夫曼编码
p = [0.1875 0.5 0.125 0.1875];
c=huffman(p)

(2)对图像进行霍夫曼编码(mat2huff)

图2.3 利用霍夫曼方法对图像编码计算得到的压缩比

%霍夫曼编码mat2huff图像压缩
I=imread('elephant.jpg');
f=rgb2gray(I);
c = mat2huff(f);    % 对图像进行霍夫曼编码
Cr=imratio(f,c)


3.JPEG编码

        JPEG编码是一种有损压缩方法。有损压缩是指在压缩数据的过程中,丢失了一定的图像信息以减小文件大小。JPEG编码通过量化和舍入等技术来丢弃一些视觉上不太敏感的图像细节,以达到更高的压缩比。对于每一个8×8的子块,左上角为低频部分,右下角为高频部分,而有损压缩就是指损失高频成分。

        JPEG编码(im2jpeg)分为四个步骤:1.将原始图像图像分为若干个8×8的子块 2. 进行余弦变换(DCT)变换 3..使用量化表进行量化 4.使用编码表进行编码,得到压缩数据。

        JPEG解码(jpeg2im)分为四个步骤:1.获取压缩数据 2.从压缩数据中得到编码表进行反编码 3.从压缩数据中得到量化表进行反量化 4.进行反余弦变换(IDCT),得到恢复图像。

图3.1 默认压缩因子(=1)的压缩比

图3.2 压缩因子为4的压缩比

%JPEG标准的压缩/解压缩技术
f=imread('elephant.jpg');
F=rgb2gray(f);
c1=im2jpeg(F);
% f1=jpeg2im(c1);
Cr1=imratio(f,c1)
c4=im2jpeg(F,4);%若需要提高压缩率,应增大因子
% f4=jpeg2im(c4);
Cr4=imratio(f,c4)
% subplot(2,2,1),imshow(F),title('Original Image');
% subplot(2,2,3),imshow(f1),title('Compressed Image (default) quality 1');
% subplot(2,2,4),imshow(f4),title('Compressed Image with quality 4');

由于函数jpeg2im函数会出现运行错误的情况,因此不进行解码操作,也就不能对解压缩图像进行显示。

冈萨雷斯源代码见笔者资源。

这篇关于【MATLAB图像处理】图像的压缩比、霍夫曼编码、JPEG编码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/175530

相关文章

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

matlab读取NC文件(含group)

matlab读取NC文件(含group): NC文件数据结构: 代码: % 打开 NetCDF 文件filename = 'your_file.nc'; % 替换为你的文件名% 使用 netcdf.open 函数打开文件ncid = netcdf.open(filename, 'NC_NOWRITE');% 查看文件中的组% 假设我们想读取名为 "group1" 的组groupName

form表单提交编码的问题

浏览器在form提交后,会生成一个HTTP的头部信息"content-type",标准规定其形式为Content-type: application/x-www-form-urlencoded; charset=UTF-8        那么我们如果需要修改编码,不使用默认的,那么可以如下这样操作修改编码,来满足需求: hmtl代码:   <meta http-equiv="Conte

利用matlab bar函数绘制较为复杂的柱状图,并在图中进行适当标注

示例代码和结果如下:小疑问:如何自动选择合适的坐标位置对柱状图的数值大小进行标注?😂 clear; close all;x = 1:3;aa=[28.6321521955954 26.2453660695847 21.69102348512086.93747104431360 6.25442246899816 3.342835958564245.51365061796319 4.87

C# double[] 和Matlab数组MWArray[]转换

C# double[] 转换成MWArray[], 直接赋值就行             MWNumericArray[] ma = new MWNumericArray[4];             double[] dT = new double[] { 0 };             double[] dT1 = new double[] { 0,2 };

研究人员在RSA大会上演示利用恶意JPEG图片入侵企业内网

安全研究人员Marcus Murray在正在旧金山举行的RSA大会上公布了一种利用恶意JPEG图片入侵企业网络内部Windows服务器的新方法。  攻击流程及漏洞分析 最近,安全专家兼渗透测试员Marcus Murray发现了一种利用恶意JPEG图片来攻击Windows服务器的新方法,利用该方法还可以在目标网络中进行特权提升。几天前,在旧金山举行的RSA大会上,该Marcus现场展示了攻击流程,

Verybot之OpenCV应用一:安装与图像采集测试

在Verybot上安装OpenCV是很简单的,只需要执行:         sudo apt-get update         sudo apt-get install libopencv-dev         sudo apt-get install python-opencv         下面就对安装好的OpenCV进行一下测试,编写一个通过USB摄像头采

libsvm在matlab中的使用方法

原文地址:libsvm在matlab中的使用方法 作者: lwenqu_8lbsk 前段时间,gyp326曾在论坛里问libsvm如何在matlab中使用,我还奇怪,认为libsvm是C的程序,应该不能。没想到今天又有人问道,难道matlab真的能运行libsvm。我到官方网站看了下,原来,真的提供了matlab的使用接口。 接口下载在: http://www.csie.ntu.edu.