JPEG2000图像压缩算法学习

article/2025/9/25 0:26:49

压缩算法——JPEG2000 编解码原理
JPEG2000-Matlab源码实现

JPEG和JPEG2000

JPEG2000和JEPG都是静止图像压缩标准,最大区别是在空间域至频域转换。JPEG是基于离散余弦变换(DCT), 而JEPG2000是基于离散小波变换(DWT)。JPEG2000是JPEG的升级版,其压缩率比JPEG高约30%左右,同时支持有损和无损压缩。JPEG2000格式一个极其重要的特征在于它能实现渐进传输,即先传输图像的轮廓,然后逐步传输数据,不断提高图像质量,让图像由朦胧到清晰显示。在有损压缩下,JPEG2000一个比较明显的优点就是没有JPEG压缩中的马赛克失真效果

JPEG2000 编码算法源于 David Taubman 提出的 EBCOT 算法,使用小波变换,采用了两层编码策略,对压缩位流进行分层组织,不仅提高了压缩效率,而且压缩码流具有较大的灵活性.

JPEG2000编解码原理

在这里插入图片描述
JPEG2000 的编码系统由七个主要模块组成,在JPEG2000 编码过程中,首先是对原始图像进行离散小波变换,根据用户要求对变换后小波系数进行量化;量化后的小波系数划分为小的数据单元——码块,然后对每个码块进行独立的嵌入式编码;并将得到的所有码块的嵌入式位流,按照率失真最优原则分层组织,形成不同质量的层.对每一层,按照一定的码流格式打包,输出压缩码流.下面介绍各部分的作用及基本原理.

数据预处理及图像分量变换

在这里插入图片描述

图像分块与拼接

与JPEG 不同,JPEG 2000 算法并不需要将图像强制分成8 × 8 的小块.但为了降低对内存的需求和方便压缩域中可能的分块处理,可以将图像分割成若干互不重叠的矩形块(tile)分块的大小任意,可以整个图像是一个块,也可以一个像素是一个块.

数据偏移和归一化处理

分量变换

指对具有多个分量的图像先经过某种变换来降低各分量之间的相关性.将传统的RGB(红绿蓝)色域转换至其他色彩空间

小波变换

图像的二维离散小波分解和重构过程如图所示,分解过程可描述为:首先对图像的每一行进行1D-DWT,获得原始图像在水平方向上的低频分量L 和高频分量H,然后对变换所得数据的每一列进行1D-DWT,获得原始图像在水平和垂直方向上的低频分量LL、水平方向上的低频和垂直方向上的高频LH、水平方向上的高频和垂直方向上的低频HL 以及水平和垂直方向上的的高频分量HH.重构过程可描述为:首先对变换结果的每一列进行以为离散小波逆变换,再对变换所得数据的每一行进行一维离散小波逆变换,即可获得重构图像.由上述过程可以看出,图像的小波分解是一个将信号按照低频和有向高频进行分离的过程,分解过程中还可以根据需要对得到的LL 分量进行进一步的小波分解,直至达到要求.
在这里插入图片描述
在JPEG 2000 的核心编码系统中,对有损压缩采用的是基于Daubechies 9/7 滤波器之提升实现的不可逆DWT.对无损压缩采用的则是基于Le Gall 5/3 滤波器之提升实现的可逆DWT.JPEG 2000 标准支持基于卷积(convolution-based) 和基于提升(lifting-based) 两种滤波模式.

MQ 二值算术编码

二进制算术编码是算术编码中的一种特殊情况.JPEG2000 所用的MQ 算术编码器属于自适应二进制算术编码器,它是指编码系统用来划分区间的当前符号概率估计是可以根据已经传输和编码的信息串调整的.

JPEG2000-MatLab实现

db97_re.m

function [c]=db97_re(image,T)
c=image;
for i=1:3x=image(:,:,i);[sa,sb]=size(x); 
% t1=liftwave('9.7'); % 获取提升系数(MATLAB7.0以后) 
d1=[-1.586100000000000e+000,-1.586134342069360e+000];
p1=[1.079600000000000e+000,-5.298011857188560e-002];
d2=[-8.829110755411875e-001,-8.829110755411875e-001];
p2=[4.435068520511142e-001,1.576123746148364e+000];
d3=-8.698644516247808e-001;
p3=-1.149604398860242e+000;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%分解层数确定
% 采用用户输入和自动给出最大层数两种方法 N=length(x); % 矩阵大小
N=length(x);
S=N; % 变量
s=log2(N); % 最大循环次数
n1=N/2; % 初始一半矩阵大小
n2=N; % 初始矩阵大小
u=0; % 初始值 % 对非2的整数幂大小图像确定最大分解层数
% 6.提升法反变换 else
n2=N/(2.^(T-1)); % 分解最小子块维数
n1=n2/2;
for time=1:T; % 行反变换% 去归一
x([1:n1],:)=x([1:n1],:)/p3;
x([n1+1:n2],:)=x([n1+1:n2],:)/d3; % 反p;
x(n1,:)=x(n1,:)-p2(2)*x(n1+1,:)-p2(1)*x(n1+2,:);
x(n1-1,:)=x(n1-1,:)-p2(2)*x(n2,:)-p2(1)*x(n1+1,:);
x([1:n1-2],:)=x([1:n1-2],:)-p2(2)*x([n1+2:n2-1],:)-p2(1)*x([n1+3:n2],:);% 反d;
x(n1+1,:)=x(n1+1,:)-d2(2)*x(n1,:)-d2(1)*x(1,:);
x([n1+2:n2],:)=x([n1+2:n2],:)-d2(2)*x([1:n1-1],:)-d2(1)*x([2:n1],:);% 反p;
x1(1,:)=x(1,:)-p1(2)*x(n2,:)-p1(1)*x(n1+1,:);
x1([2:n1],:)=x([2:n1],:)-p1(2)*x([n1+1:n2-1],:)-p1(1)*x([n1+2:n2],:);% 反d;
x(n2,:)=x(n2,:)-d1(2)*x1(n1,:)-d1(1)*x1(1,:);
x([2:2:n2-2],:)=x([n1+1:n2-1],:)-d1(2)*x1([1:n1-1],:)-d1(1)*x1([2:n1],:);% 偶数
x([1:2:n2-1],:)=x1([1:n1],:);clear x1;% 列反变换% 归一
x(:,[1:n1])=x(:,[1:n1])/d3;
x(:,[n1+1:n2])=x(:,[n1+1:n2])/p3; % 反d;
x(:,n1+1)=x(:,n1+1)+p2(1)*x(:,n1-1)+p2(2)*x(:,n1);
x(:,n1+2)=x(:,n1+2)+p2(1)*x(:,n1)+p2(2)*x(:,1);
x(:,[n1+3:n2])=x(:,[n1+3:n2])+p2(1)*x(:,[1:n1-2])+p2(2)*x(:,[2:n1-1]);% 反p;
x(:,n1,:)=x(:,n1)+d2(1)*x(:,n2)+d2(2)*x(:,n1+1);
x(:,[1:n1-1])=x(:,[1:n1-1])+d2(1)*x(:,[n1+1:n2-1])+d2(2)*x(:,[n1+2:n2]);% 反d;
x(:,n2)=x(:,n2)+p1(1)*x(:,n1)+p1(2)*x(:,1);
x(:,[n1+1:n2-1])=x(:,[n1+1:n2-1])+p1(1)*x(:,[1:n1-1])+p1(2)*x(:,[2:n1]);% 反p;
x1(:,1)=x(:,1)+d1(1)*x(:,n2)+d1(2)*x(:,n1+1);
x1(:,[2:n1])=x(:,[2:n1])+d1(1)*x(:,[n1+1:n2-1])+d1(2)*x(:,[n1+2:n2]); % 奇偶
x(:,[2:2:n2])=x(:,[n1+1:n2]);
x(:,[1:2:n2-1])=x1(:,[1:n1]); clear x1;n2=n2*2; % 原大小
n1=n2/2; % 一半大小 end;
end;
c(:,:,i)=x;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

EBCOT.m

function [FLength,FCtxt,x_new]=EBCOT(filename,numOfBlocks,x)
%% function EBCOT.m
% Description:
% 该函数用于对数据块进行嵌入式编码
% filename:输入的数据块,大小要求为64*64的整型
% numOfBlocks:数据块的个数
% x:待存储码流的文件
% FLength:记录编码长度信息的文件
% FCtxt:记录上下文信息的文件
% x_new:存储码流后的文件
%%
% 初始化
sign=cell(numOfBlocks,1);       % 符号集
significant=cell(numOfBlocks,1);% 重要性集
refinement=cell(numOfBlocks,1); % 细化编码集
Block=cell(numOfBlocks,1);      % 码块
FCtxt=cell(numOfBlocks,1);
FLength=cell(numOfBlocks,1);% 开始编码,对每个码块依次处理
for nb=1:numOfBlockswidthBlock=filename.width;heightBlock=filename.height;level=filename.level;subband=filename.subband;Block{nb}=filename.data; % data should be 64*64 and integer[~,x_new]=InitializeWrite(x);   % 对存储码流的文件进行初始化FCtxt{nb}=[];FLength{nb}=[];sign{nb}=zeros(heightBlock,widthBlock);significant{nb}=zeros(heightBlock,widthBlock);refinement{nb}=zeros(heightBlock,widthBlock);% 对符号集进行赋值,并将数据集全部取为正数[h,v]=find(Block{nb}<0);for i=1:length(h)sign{nb}(h(i),v(i))=1;endBlock{nb}=abs(Block{nb});maximum=max(max(Block{nb}));% 通过位与操作获取位平面数numOfPlanes=1;for i=32:-1:1if bitand(maximum,bitshift(1,i-1))>0numOfPlanes=i;break;endendencoded=cell(numOfPlanes,1);    % 记录每个位置是否已编码% 创建位平面planeOfBits=cell(numOfPlanes,1);for i=1:numOfPlanesplaneOfBits{i}=bitand(Block{nb},bitshift(1,i-1))>0;end% 开始编码FLength{nb}(end+1)=widthBlock;FLength{nb}(end+1)=heightBlock;FLength{nb}(end+1)=level;FLength{nb}(end+1)=subband;FLength{nb}(end+1)=numOfPlanes;for n=numOfPlanes:-1:1% 记录每个通道已扫描的个数bitsPropagation=0;bitsRefinement=0;bitsCleaning=0;bitsGenProp=0;bitsGenRef=0;bitsGenClea=0;encoded{n}=zeros(heightBlock,widthBlock);%% start propagationfor k=1:4:heightBlockfor j=1:widthBlockfor i=k:k+3[y,h,v,d]=GetSignificantNeighbors(...significant{nb},widthBlock,heightBlock,i,j);    % 获取邻居的重要性信息if ~significant{nb}(i,j) && y                       % 判断自身是否重要if planeOfBits{n}(i,j)x_new=WriteBit(1,x_new);                    % 向文件中写入1FCtxt{nb}(end+1)=Context(h,v,d,subband);    % 记录上下文信息x_new=WriteBit(sign{nb}(i,j),x_new);        % 写入该位置的符号[FCtxt{nb}(end+1),~,~]=ContextSign(h,v,significant{nb},sign{nb});   % 记录符号上下文信息bitsGenProp=bitsGenProp+4;elsex_new=WriteBit(0,x_new);                    % 向文件写入0FCtxt{nb}(end+1)=Context(h,v,d,subband);    % 记录上下文信息bitsGenProp=bitsGenProp+2;endencoded{n}(i,j)=1;                              % 标记为已编码bitsPropagation=bitsPropagation+1;endendendend%% start refinementfor k=1:4:heightBlockfor j=1:widthBlockfor i=k:k+3if ~encoded{n}(i,j) && significant{nb}(i,j)         % 判断是否已编码以及当前位置的重要性x_new=WriteBit(planeOfBits{n}(i,j),x_new);      % 向文件写入当前所在位平面的数值if refinement{nb}(i,j)context=16;                                 % 上下文信息记为16[y,~,~,~]=GetSignificantNeighbors(...significant{nb},widthBlock,heightBlock,i,j);    % 获取邻居的重要性信息else if ycontext=15;                             % 上下文信息记为15elsecontext=14;                             % 上下文信息记为14endrefinement{nb}(i,j)=1;                      % 当前位置记为已通过细化编码扫描endFCtxt{nb}(end+1)=context;                       % 记录上下文信息encoded{n}(i,j)=1;                              % 记为已编码bitsGenRef=bitsGenRef+2;bitsRefinement=bitsRefinement+1;endendendend%% start cleanfor k=1:4:heightBlockfor j=1:widthBlockfor i=k:k+3if ~encoded{n}(i,j)if planeOfBits{n}(i,j)x_new=WriteBit(1,x_new);[y,h,v,d]=GetSignificantNeighbors(...significant{nb},widthBlock,heightBlock,i,j);FCtxt{nb}(end+1)=Context(h,v,d,subband);x_new=WriteBit(sign{nb}(i,j),x_new);[FCtxt{nb}(end+1),~,~]=ContextSign(h,v,...significant{nb},sign{nb});              % 记录符号上下文信息significant{nb}(i,j)=1;                     % 该位置的重要性记为1bitsGenClea=bitsGenClea+4;elsex_new=WriteBit(0,x_new);[y,h,v,~]=GetSignificantNeighbors(...significant{nb},widthBlock,heightBlock,i,j);[FCtxt{nb}(end+1),~,~]=ContextSign(h,v,...significant{nb},sign{nb});bitsGenClea=bitsGenClea+2;endbitsCleaning=bitsCleaning+1;endendendend% 记录各通道的编码个数FLength{nb}(end+1)=idivide(int32(bitsPropagation),int32(256));FLength{nb}(end+1)=mod(bitsPropagation,256);FLength{nb}(end+1)=idivide(int32(bitsRefinement),int32(256));FLength{nb}(end+1)=mod(bitsRefinement,256);FLength{nb}(end+1)=idivide(int32(bitsCleaning),int32(256));FLength{nb}(end+1)=mod(bitsCleaning,256);endx_new=EndWriting(x_new);    % 结束写入信息
end
end

在这里插入图片描述


http://chatgpt.dhexx.cn/article/2hwyLEV6.shtml

相关文章

图像处理(六)——图像压缩

图像压缩模型图像数据中的冗余 三种数据冗余&#xff1a;编码冗余、像素冗余、视觉心理冗余 如果一个图像的灰度级编码&#xff0c;使用了多于实际需要的编码符号&#xff0c;就称该图像包含了编码冗余。 图像压缩中的信息论观点 字典压缩 有…

图片压缩算法

有损算法&#xff1a; JPEG&#xff0c;我们最为常用的算法。他是通过离散余弦变换&#xff0c;对图片质量尽量小的时候进行有损压缩&#xff0c;改算法对高中波特率下效果很好&#xff0c;但是对低波特率下&#xff0c;就会出现方格之类的&#xff0c;比如100多MB的MPEG电影&…

算法设计与分析——图像的压缩

一、基本概念&#xff1a; 像素灰度值为0-255&#xff0c;需要8位二进制数来存储。若一灰度序列为{p1,p2,p3…pn}&#xff0c;pi为第i个像素点的灰度值。则所需的空间为8n。 二、问题提出&#xff1a; 若图像中有一大部分的颜色的相同的或是相近的&#xff0c;能不能有更好的…

JPEG图像压缩算法的python实现

摘要 文章在研究JPEG压缩编码对图像数据压缩的基本原理的基础上&#xff0c;设计了JPEG图像压缩算法程序实现流程&#xff0c;利用 Python语言对程序进行了编写&#xff0c;并实现了对压缩质量进行控制&#xff0c;验证了JPEG压缩编码对图像数据压缩的可行性。 用 JPEG压缩软件…

基于深度学习的图像压缩

近年来&#xff0c;深度学习在计算机视觉领域已经占据主导地位&#xff0c;不论是在图像识别还是超分辨重现上&#xff0c;深度学习已成为图片研究的重要技术&#xff0c;但它们的能力并不仅限于这些任务&#xff1b;现在深度学习技术已进入图片压缩领域。下面就说说神经网络在…

JPEG压缩算法步骤原理

目录 JPEG压缩算法解密 步骤一&#xff1a;图像分割 步骤二&#xff1a;颜色空间转换RGB->YCbCr 步骤三&#xff1a;离散余弦变换 步骤四&#xff1a;数据量化 步骤五&#xff1a;哈弗曼编码 JPEG压缩算法解密 by jinchao 图片压缩有多重要&#xff0c;可能很多人可能…

影像算法解析——JPEG 压缩算法

由于视频是由一帧帧图像构成的&#xff0c;研究视频编码首先先要研究图像编码。这篇文章就详细说一下 JPEG 是如何压缩一个图像的。 先简单介绍一下 JPEG&#xff08;Joint Photographic Experts Group&#xff0c;联合图像专家小组&#xff09;&#xff1a;此团队创立于1986年…

数字图像处理(七)图像压缩-无损编码/压缩算法+matlab

要求&#xff1a; 无损编码/压缩算法&#xff1a; 问题1: 实现行程编码压缩, 肉眼观察压缩效果&#xff0c;并计算原图和压缩以后的尺寸&#xff0c;计算压缩率并比较分析&#xff1b;问题2: 实现哈夫曼压缩, 肉眼观察压缩效果&#xff0c;并计算原图和压缩以后的尺寸&#x…

图像压缩原理-JPEG

搬来一个基础啊 给自己看~~ 非技术指正勿扰 图像的格式有很多种&#xff0c;比如PNG&#xff0c;JPEG等等&#xff0c;但当我们把一张图用工具变成各种其他格式时&#xff0c;其在计算机文件系统显示的文件大小各不一样&#xff0c;但是当你打开显示时&#xff0c;从视觉角度…

图像压缩算法简介

理论基础 香农的信息论&#xff0c;在不产生任何失真的前提下&#xff0c;通过合理的编码&#xff0c;对于每个信源符号分配不等长的码字&#xff0c;平均码长可以任意接近于信源的熵。在这个理论框架下产生了几种不同的无失真的信源编码方法&#xff1a;哈夫曼编码&#xff0c…

图像压缩原理

原文网址&#xff1a;http://blog.csdn.net/newchenxf/article/details/51693753 转载请注明出处。 1 图像可压缩的原因 一张原始图像(1920x1080)&#xff0c;如果每个像素32bit表示&#xff08;RGBA&#xff09;&#xff0c;那么&#xff0c;图像需要的内存大小 1920x1080x…

JPEG图像压缩算法详解

转载自 http://www.ibm.com/developerworks/cn/linux/l-cn-jpeg/ JPEG压缩算法之前已有很多前辈详细讲解过&#xff0c;我就不在这里画蛇添足了&#xff08;主要是我懒。。&#xff09;&#xff0c;转载两篇JPEG压缩算法介绍&#xff0c;拼为一篇。侵删。 JPEG图像压缩算法详解…

图片压缩知识

一、图片压缩算法 有损算法&#xff1a; JPEG&#xff0c;我们最为常用的算法。他是通过离散余弦变换&#xff0c;对图片质量尽量小的时候进行有损压缩&#xff0c;该算法对高中波特率下效果很好&#xff0c;但是对低波特率下&#xff0c;就会出现方格之类的&#xff0c;比如1…

imadjust函数分析一

声明&#xff1a;本文涉及到的行数皆指本文提供的附件imadjust.m的代码中行数 本文只讨论imadjust函数是一种用法&#xff0c;即 J IMADJUST(I,[LOW_IN; HIGH_IN],[LOW_OUT; HIGH_OUT],GAMMA) 处理效果如下图 图像矩阵I要求数据类型uint8、uint16、double、single和int16&…

matlab灰度变换函数imadjust、stretchlim

1、imadjust函数 gimadjust(f,[low_in,high_in],[low_out,high_out],gamma) f为输入灰度图像&#xff0c;将low_in和high_in之间的灰度值映射到low_out到high_out之间 gamma大于1&#xff0c;映射函数下凸&#xff1b;小于1&#xff0c;上凸&#xff1b;gamma默认为1&#x…

Matlab中库函数imadjust()的使用细节

不知道大家有没有使用这个函数时&#xff0c;出现结果异常、过曝的情况我在使用时&#xff0c;发现在官方文档中并未声明的细节。 结合开源的程序源码和实验结果发现该函数对矩阵进行处理时&#xff0c;会对参数指明的处理数据以外的内容进行调整&#xff0c;错误使用会导致图像…

stretchlim matlab,matlab灰阶变换函数imadjust和stretchlim的c++实现

灰阶变换 首先介绍一下灰阶变换&#xff0c;一幅图像数据本身在存储的数据结构上为一个二维的矩阵&#xff0c;即一幅图像为m*n个密密麻麻的像素点构成。 image.png 然后&#xff0c;这些像素点有着一个值&#xff0c;这个值成为灰度值或者亮度值&#xff0c;值的范围为[0,255]…

在OpenCV里实现函数imadjust

imadjust 函数是针对灰度图像进行灰度变换的基本图像。 J = imadjust(f,[low_in; high_in],[low_out; high_out],gamma) 此函数将 f 的灰度值映像到 g 中的新值, 也就是将 low_in 与high in 之间的值映射到 low out 与 high out 之间的值。 low in 以下与 high in 以上的值可…

imadjust使用opencv实现

实现函数功能 J low_out (high_out - low_out).* ((I - low_in)/(high_in - low_in)).^ gamma [cpp] view plain copy print ? IplImage* ImageAdjust(IplImage *src, IplImage *dst, double low_in, double high_in, double low_out, double h…

python实现matlab stretchlim函数和imadjust函数

matlab 代码&#xff1a; [img,map]imread(“/home/zhongjia/test.png”); LOW_HIGHstretchlim(img); Jimadjust(img,[LOW_HIGH(1) LOW_HIGH(2)],[0 1],1); imwrite(J,"/home/zhongjia/test_result.png"); 实现功能是&#xff1a;对16位深度1024*1024大小的test.…