来手把手教你通过Matlab用两种方法实现图像压缩与解压(附超详细代码),赶紧点赞收藏吧

图像压缩方法

DCT图像压缩

DCT原理介绍

数字图像处理DCT是数字图像处理中的一种重要处理手段,被广泛地用与图像的压缩编码算法中,已有的各种成熟的压缩标准如JPEG,MPEG,H.26X以及HDTV等都无一例外地采用基于DCT/IDCT的压缩编码。

离散余弦变换(Discrete Cosine Transform) 是一种最主要的正交变换。它将图像信号从空间域变换到DCT域,保持原始信号的熵和能量不变,却使得DCT域系数之间的相关性减弱,然后再对DCT域系数进行量化和编码,以达到压缩的目的。

DCT将运动补偿误差或原画面信息块转换成代表不同频率分量的系数集,这有两个优点
其一,信号常将其能量的大部分集中于频率域的1个小范围内,这样一来,描述不重要的分量只需要很少的比特数;
其二,频率域分解映射了人类视觉系统的处理过程,并允许后继的 量化过程满足其灵敏度的要求。

离散余弦变换(Discrete Cosine Transform,简称DCT变换)是一种与傅立叶变换紧密相关的数学运算。在傅立叶级数展开式中,如果被展开的函数是实偶函数,那么其傅立叶级数中只包含余弦项,再将其离散化可导出余弦变换,因此称之为离散余弦变换。

离散余弦变换(DCT)是N.Ahmed等人在1974年提出的正交变换方法。它常被认为是对语音和图像信号进行变换的最佳方法。为了工程上实现的需要,国内外许多学者花费了很大精力去寻找或改进离散余弦变换的快速算法。由于近年来数字信号处理芯片(DSP)的发展,加上专用集成电路设计上的优势,这就牢固地确立离散余弦变换(DCT)在目前图像编码中的重要地位,成为H.261、JPEG、MPEG 等国际上公用的编码标准的重要环节。

在视频压缩中,最常用的变换方法是DCT,DCT被认为是性能接近K-L变换的准最佳变换,变换编码的主要特点有:
(1)在变换域里视频图像要比空间域里简单。
(2)视频图像的相关性明显下降,信号的能量主要集中在少数几个变换系数上,采用量化和熵编码可有效地压缩其数据。
(3)具有较强的抗干扰能力,传输过程中的误码对图像质量的影响远小于预测编码。通常,对高质量的图像,DMCP要求信道误码率 ,而变换编码仅要求信道误码率 。

DCT等变换有快速算法,能实现实时视频压缩。
针对目前采用的帧内编码加运动补偿的视频压缩方法的不足, 我们在Westwater 等人提出三维视频编码的基础上, 将三维变换的结构应用于视频图像压缩, 进一步实现了新的视频图像序列的编码方法。

码率压缩基于变换编码和熵值编码两种算法。前者用于降低熵值,后者将数据变为可降低比特数的有效编码方式。

在MPEG标准中,变换编码采用的是DCT,变换过程本身虽然并不产生码率压缩作用,但是变换后的频率系数却非常有利于码率压缩。

实际上压缩数字视频信号的整个过程分为块取样、DCT、量化、编码4个主要过程进行—–首先在时间域将原始图像分成N(水平)×N(垂直)取样块,根据需要可选择4×4、4×8、8×8、8×16、16×16等块,这些取样的像素块代表了原图像帧各像素的灰度值,其范围在139-163之间,并依序送入DCT编码器,以便将取样块由时间域转换为频率域的DCT系数块。DCT系统的转换分别在每个取样块中进行,这些块中每个取样是数字化后的值,表示一场中对应像素的视频信号幅度值。

DCT和它解压时的反运算的具体算法

  • 当u,v = 0 时,离散余弦正变换(DCT)后的系数若为F(0,0)=1,则离散余弦反变换(IDCT)后的重现函数f(x,y)=1/8,是个常数值,所以将F(0,0)称为直流(DC)系数;
  • 当u,v≠0时,正变换后的系数为F(u,v)=0,则反变换后的重现函数f(x,y)不是常数,此时正变换后的系数F(u,v)为交流(AC)系数。

详细实现代码

function Jpeg
I=imread('lena.jpg');
%该图片在安装matlab的目录中找,原图为灰度图象
I=im2double(I);%图像存储类型转换
T=dctmtx(8);%离散余弦变换矩阵
B=blkproc(I,[8 8],'P1*x*P2',T,T'); %对原图像进行DCT变换 mask=[1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]; B2=blkproc(B,[8 8],'P1.*x',mask); %数据压缩,丢弃右下角高频数据 I2=blkproc(B2,[8 8],'P1*x*P2',T',T);
%进行DCT反变换,得到压缩后的图像
imshow(I)
title('原始图像')
figure;
imshow(I2)
title('压缩后的图像')

结果展示

《来手把手教你通过Matlab用两种方法实现图像压缩与解压(附超详细代码),赶紧点赞收藏吧》
《来手把手教你通过Matlab用两种方法实现图像压缩与解压(附超详细代码),赶紧点赞收藏吧》

行程编码压缩与解压

读入图像

matlab中利用imread函数读入图像,并将其进行灰度化,之后设置为二值图像,指明相应的阈值。

I=imread('lena1.jpg'); % 读入图像
I1=rgb2gray(I);	% 灰度化
I3=im2bw(I1,0.5); %将原图转换为二值图像,阈值为 0.5

图像转为矩阵

I2=I1(:); %将原始图像写成一维的数据并设为 I2
I2length=length(I2); %计算 I2 的长度

X=I3(:); %令 X 为新建的二值图像的一维数据组
L=length(X);

行程编码压缩

行程编码(Run-Length Encoding):仅存储一个像素值以及具有相同颜色的像素数目的图象数据编码方式称为行程编码,或称游程编码,常用RLE(Run-Length Encoding)表示。该压缩编码技术相当直观和经济,运算也相当简单,因此解压缩速度很快。RLE压缩编码尤其适用于计算机生成的图形图像,对减少存储容量很有效果。

在此方式下每两个字节组成一个信息单元。第一个字节给出其后面相连的象素的个数。第二个字节给出这些象素使用的颜色索引表中的索引。例如:信息单元03 04,03表示其后的象素个数是3个,04表示这些象素使用的是颜色索引表中的第五项的值。压缩数据展开后就是04 04 04 .同理04 05 可以展开为05 05 05 05. 信息单元的第一个字节也可以是00,这种情况下信息单元并不表示数据单元,而是表示一些特殊的含义。这些含义通常由信息单元的第二个字节的值来描述。

给出的数据序列为:A-A-A-A-A-B-B-C-D

未压缩前:A-A-A-A-A-B-B-C-D

(0x41-0x41-0x41-0x41-0x41-0x42-0x42-0x43-0x44)

压缩后:5-A-2-B-1-C-1-D

(0x05-0x41-0x02-0x42-0x01-0x43-0x01-0x44)

j=1;
I4(1)=1;
for z=1:1:(length(X)-1) %行程编码程序段
    if X(z)==X(z+1)
        
        I4(j)=I4(j)+1;
    else
        data(j)=X(z); % data(j)代表相应的像素数据
        j=j+1;
        I4(j)=1;
    end
end
data(j)=X(length(X)); %最后一个像素数据赋给 data
I4length=length(I4);  %计算行程编码后的所占字节数,记为 I4length
CR=I2length/I4length; %比较压缩前于压缩后的大小

行程编码解压

l=1;
for m=1:I4length
    for n=1:1:I4(m);
        decode_image1(l)=data(m);
        l=l+1;
    end
end
decode_image=reshape(decode_image1,256,256); %重建二维图像数组

显示图像

h=figure,set(h,'color','white')
x=1:1:length(X);
subplot(131),plot(x,X(x)); title('编码前图像数据');%显示行程编码之前的图像数据
y=1:1:I4length ;
subplot(132),plot(y,I4(y)); title('编码后图像数据');%显示编码后数据信息
u=1:1:length(decode_image1);
subplot(133),plot(u,decode_image1(u));title('解压后图像数据'); %查看解压后的图像数据
h=figure;
subplot(131);imshow(I);title('原始图像'); %显示原图的二值图像
subplot(132);imshow(I3);title('原图的二值图像'); %显示原图的二值图像
subplot(133),imshow(decode_image);title('解压恢复后的图像'); %显示解压恢复后的图像
set(h,'color','white')
disp('压缩比: ')
disp(CR);
disp('原图像数据的长度:')
disp(L);
disp('压缩后图像数据的长度:')
disp(I4length);
disp('解压后图像数据的长度:')
disp(length(decode_image1));

《来手把手教你通过Matlab用两种方法实现图像压缩与解压(附超详细代码),赶紧点赞收藏吧》
《来手把手教你通过Matlab用两种方法实现图像压缩与解压(附超详细代码),赶紧点赞收藏吧》
《来手把手教你通过Matlab用两种方法实现图像压缩与解压(附超详细代码),赶紧点赞收藏吧》

完整代码附录

close all; clear all; clc;
I=imread('lena1.jpg'); %读入图像
I1=rgb2gray(I);
I2=I1(:); %将原始图像写成一维的数据并设为 I2
I2length=length(I2); %计算 I2 的长度
I3=im2bw(I1,0.5); %将原图转换为二值图像,阈值为 0.5
%以下程序为对原图像进行行程编码,压缩
X=I3(:); %令 X 为新建的二值图像的一维数据组
L=length(X);
j=1;
I4(1)=1;
for z=1:1:(length(X)-1) %行程编码程序段
    if X(z)==X(z+1)
        
        I4(j)=I4(j)+1;
    else
        data(j)=X(z); % data(j)代表相应的像素数据
        j=j+1;
        I4(j)=1;
    end
end
data(j)=X(length(X)); %最后一个像素数据赋给 data
I4length=length(I4);  %计算行程编码后的所占字节数,记为 I4length
CR=I2length/I4length; %比较压缩前于压缩后的大小
%下面程序是行程编码解压
l=1;
for m=1:I4length
    for n=1:1:I4(m);
        decode_image1(l)=data(m);
        l=l+1;
    end
end
decode_image=reshape(decode_image1,256,256); %重建二维图像数组
h=figure,set(h,'color','white')
x=1:1:length(X);
subplot(131),plot(x,X(x)); title('编码前图像数据');%显示行程编码之前的图像数据
y=1:1:I4length ;
subplot(132),plot(y,I4(y)); title('编码后图像数据');%显示编码后数据信息
u=1:1:length(decode_image1);
subplot(133),plot(u,decode_image1(u));title('解压后图像数据'); %查看解压后的图像数据
h=figure;
subplot(131);imshow(I);title('原始图像'); %显示原图的二值图像
subplot(132);imshow(I3);title('原图的二值图像'); %显示原图的二值图像
subplot(133),imshow(decode_image);title('解压恢复后的图像'); %显示解压恢复后的图像
set(h,'color','white')
disp('压缩比: ')
disp(CR);
disp('原图像数据的长度:')
disp(L);
disp('压缩后图像数据的长度:')
disp(I4length);
disp('解压后图像数据的长度:')
disp(length(decode_image1));

有用的话各位老铁来个三连击!!!

《来手把手教你通过Matlab用两种方法实现图像压缩与解压(附超详细代码),赶紧点赞收藏吧》

    原文作者:左手の明天
    原文地址: https://blog.csdn.net/ywsydwsbn/article/details/106341759
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞