数字图像处理|Matlab-数字图像编码实验-有损压缩/压缩算法实验-JPEG编码压缩

Matlab-数字图像编码实验-有损压缩/压缩算法实验

代码链接:https://download.csdn.net/download/qq_43571150/12033274

查阅JPEG编码的有关资料,对图像进行JPEG压缩
算法步骤必须包括如下几个部分:

  1. 图像分块
  2. 离散余弦变换
  3. 量化
  4. ac和dc系数的Z字形编排

问题1:质量因子分别选为20,60,80,对比显示原图与不同质量因子下解码后的图像;
问题2:记录图像大小、压缩比、均方根误差;对结果进行分析。

JPEG标准亮度量化表
数字图像处理|Matlab-数字图像编码实验-有损压缩/压缩算法实验-JPEG编码压缩_第1张图片
结果
数字图像处理|Matlab-数字图像编码实验-有损压缩/压缩算法实验-JPEG编码压缩_第2张图片
数字图像处理|Matlab-数字图像编码实验-有损压缩/压缩算法实验-JPEG编码压缩_第3张图片

Matlab代码

function JPEG;

close all;clear all;clc;
J=imread('05.jpg'); 
imwrite(J,'05 质量因子80.jpg','quality',80);
x=imread('05 质量因子80.jpg');
R=rgb2gray(x);
I=double(R);
imwrite(R,'05 灰度图.jpg');

图像分割
以8x8为最小单元分割,可分割成4096个方块,从上往下,得到32768x8的矩阵

%% 图像分割 以8x8为最小单元分割,可分割成4096个方块,从上往下,得到32768x8的矩阵
% lena512: 512*512
% Block: 32768*8
Block=[];
for numi=1:64 %逐行取方阵
    m=(numi-1)*8+1; %每块行的开头
    for numj=1:64 %逐列取方阵
        n=(numj-1)*8+1; %每块列的开头
        Block=[Block; I(m:m+7,n:n+7)];
    end
end

离散余弦变换(DCT变换)
对4096个方阵分别进行DCT变换,得到4096个变换方阵,从上往下存,32768x8的矩阵

%% 离散余弦变换 DCT变换 对4096个方阵分别进行DCT变换,得到4096个变换方阵,从上往下存,32768x8的矩阵
% Block: 32768*8
% FBlock: 32768*8
for num=1:4096
    start=(num-1)*8+1;
    FBlock(start:start+7,:)=dct2(Block(start:start+7,:));
end

量化
对4096个方阵分别根据JPEG亮度标准量化表进行量化,从上往下

%% 量化 对4096个方阵分别根据JPEG亮度标准量化表进行量化,从上往下存,32768x8的矩阵,部分高频分量被舍弃,减小了视觉冗余
% FBlock: 32768*8
% QBlock: 32768*8
load('JPEG512.mat','lighttable');%JPEG标准亮度量化表
for num=1:4096
    start=(num-1)*8+1;
    QBlock(start:start+7,:)=round(FBlock(start:start+7,:)./lighttable);
end

反向量化

%% 反向量化
% QBlock: 32768*8
% reFBlock: 32768*8
for num=1:4096
    start=(num-1)*8+1;
    reFBlock(start:start+7,:)=QBlock(start:start+7,:).*lighttable;
end

反离散余弦变换(IDCT)

for num=1:4096
    start=(num-1)*8+1;
    Block(start:start+7,:)=idct2(reFBlock(start:start+7,:));
end

图像重构

%% 图像重构
reI=[];
for numi=1:64
    m=(numi-1)*512+1;
    % 分成64512*8阵列,每个阵列有648*8方阵
    A=[];
    for numj=1:64
        n=(numj-1)*8;
        A=[A Block(m+n:m+n+7,:)];
    end
    reI=[reI; A];
end

JPEG Figure

subplot(1,2,1);imshow(I./256);title('input');
subplot(1,2,2);imshow(reI./256);title('JPEG压缩');
imwrite(reI./256,'05 质量因子80.jpg');

CODE

%% 锯齿形 ZIG-ZAG 对每一个方阵采用ZIG-ZAG排序,以增加图像中的连0个数,得到4096x64的矩阵
% QBlock: 32768*8
% QLine: 4096*64
QLine=[];
load('JPEG512.mat','zigzag');%快速Z型排序行向量
zigzag = zigzag + 1;  % 下标加1,从0开始

for num=1:4096
    start=(num-1)*8+1;
    A=reshape(QBlock(start:start+7,:),1,64);% 变成行向量
    QLine=[QLine;A(zigzag)];
end

%% 对第一列的DC分量进行DPCM编码 第一个记为0,后面的都只记录与前者的差值
% QLine: 4096*64
% VLIDC: 4096*1
% 对第一列进行DPCM编码,第一个值记为DC,并赋0
DC=QLine(1,1);%保留备用
sumcode=0;%计算编码长度

QLine(1,1)=0;
for num=4096:-1:2
    QLine(num,1)=QLine(num,1)-QLine(num-1,1);
end

VLIDC=ones(4096,1);% VLI分组
for num=1:4096
    temp=abs(QLine(num,1));%用绝对值判断组别
    if temp==0
        VLIDC(num)=0;
    else
        for k=1:7%经测试,第一列最大值为80,前7组够用
            if (temp>=2^(k-1)) && (temp<2^k)
                VLIDC(num)=k;
                break;
            end
        end
    end
end

for num=1:4096
    %先根据DC亮度huffman表计算sumcode
    if (VLIDC(num)<=5) && (VLIDC(num)>=0)
        sumcode=sumcode+3;
    elseif VLIDC(num)==6
        sumcode=sumcode+4;
    else
        sumcode=sumcode+5;
    end
    
    %再根据VLI表计算sumcode
    sumcode=sumcode+VLIDC(num);
end

%% 对其余63列AC分量进行RLC编码
% QLine: 4096*64
% 经测试,后63列最大值为58,VLI前6组够用。
eob=max(QLine(:))+1; %设一个超大值作为每一行结束符

for numn=1:4096 %放eob
    for numm=64:-1:2
        if QLine(numn,numm)~=0
            QLine(numn,numm+1)=eob;
            break;
        end
        if (numm==2)%没找到
            QLine(numn,2)=eob;
        end
    end
end
test=QLine';
[col,~]=find(test==eob);%我们只要eob列位置
validAC=col-1; %每一行保留的AC数据量,含EOB
maxcz=0;

for numn=1:4096 %逐行计算并加至sumcode
    cz=[];%记录前0数
    VLIAC=[];%记录组号
    count=0;%记录连0for numm=2:1+validAC(numn)
        if QLine(numn,numm)==eob
            cz=[cz 0];
            VLIAC=[VLIAC 0];
        elseif QLine(numn,numm)==0
            count=count+1;
        else %遇到非0if count>15 %遇到连0大于15的
                cz=[cz 15];
                count=0;
                VLIAC=[VLIAC 0];
                continue;
            end
            cz=[cz count];
            count=0;
            
            temp=abs(QLine(numn,numm));%用绝对值判断组别
            for k=1:6%经测试,后63列最大值为58,前6组够用
                if (temp>=2^(k-1)) && (temp<2^k)
                    VLIAC=[VLIAC k];
                    break;
                end
            end
        end
    end%该行cz和VLIAC已定,开始计算
    
    sumcode=sumcode+4;%EOB对应1010,就是4bit
    czlen=length(cz)-1; %czlen不包括EOB
    load('JPEG512.mat','codelength');%霍夫曼编码码长矩阵(AC、DC亮度编码表)
    for k=1:czlen
        if VLIAC(k)==0
            sumcode=sumcode+11;
        else
            sumcode=sumcode+codelength(cz(k)+1,VLIAC(k));
        end
    end 
end

压缩率

%% 压缩率
OB=512*512*8;
CR=OB/sumcode;
D=I-reI;
MSE = sum(D(:).*D(:))/prod(size(I));

disp(['原图 Bit:                  ',num2str(OB),' bit']);
disp(['压缩图像 Bit:               ',num2str(sumcode),' bit']);
disp(['压缩比:                     ',num2str(CR)]);
disp(['均方根误差:                  ',num2str(MSE)]);

end

你可能感兴趣的:(数字图像处理)