zoukankan      html  css  js  c++  java
  • 图像压缩编解码实验(DCT编码+量化+熵编码(哈夫曼编码))【MATLAB】

    课程要求

    Assignment IV Transform + Quantization + Entropy Coding

    Input: an intra-frame or a residue picture after motion compensation.

    Task: Code the input picture into a bitstream  and decode the picture from the generated bitstream.

    Specifications: Implement a transform-based codec, consisting transform, quantization, and entropy coding.  The block size can be 8x8, 16x16, or other reasonable sizes. As in most existing image/video codecs, you can use 2D DCT. A simple uniform quantizer could be used for verification purpose.  For the entropy coding, you can use either Huffman coding or arithmetic coding 

    README

    运行main函数,注意main函数用到了下面的Normalize函数
    指定待处理的图片,依次对图片进行一下变换:
    一、灰度化
    二、8 * 8 DCT变换(这一步r)如果加上一个掩模可以去除图片中人眼不敏感的高频分量,从而进一步压缩图片
    三、量化处理(采用JPEG亮度量化表,将DCT举证除以量化码表),由于量化后有取整操作,因此是有损压缩图片
    四、Huffman编码,编码得到的比特流序列比原序列更加短小,进一步提高传输效率
    五、发送方比特流序列传输(将上一步得到的比特流进行传输)
    %中间对比了直接传输图片的比特流长度和经过压缩变换得到的比特流长度
    六、接收方接收比特流序列
    七、解码,是Huffman编码的逆过程,得到量化后的序列
    八、反量化处理,是第三步的逆过程,将量化后的矩阵乘以量化码表
    九、反DCT变换得到图片

    main函数:

     1 clc;clear;
     2   
     3   %采用JPEG亮度量化表
     4 Q =[16 11 10 16  24  40  51  61
     5     12 12 14 19  26  58  60  55
     6     14 13 16 24  40  57  69  56
     7     14 17 22 29  51  87  80  62
     8     18 22 37 56  68 109 103  77
     9     24 35 55 64  81 104 113  92
    10     49 64 78 87 103 121 120 101
    11     72 92 95 98 112 100 103 99];
    12 
    13 X = 8;%分块大小
    14 
    15 I=imread('cameraman.jpg');%读取图像
    16 gray_img = rgb2gray(I);%灰度化
    17 
    18 
    19 I_DCT = blkproc(gray_img,[X X],'dct2');%对图像进行DCT变换,
    20 
    21 Iq = round(blkproc(I_DCT,[X X],'x./P1',Q));%量化处理
    22 
    23 Iq = Iq + 120;%量化处理之后,序列的symbol取-120到+120之间,为了方便编码,将其平移到0-255的区间
    24 
    25 %哈夫曼编码
    26 [M,N] = size(Iq);
    27 I1 = Iq(:);
    28 P = zeros(1,256);
    29 for i = 0:255
    30     P(i+1) = length(find(I1 == i))/(M*N);
    31 end
    32 k = 0:255;
    33 dict = huffmandict(k,P); %生成字典
    34 enco = huffmanenco(I1,dict); %编码
    35 %bitstream传输
    36 
    37         %计算编码长度,计算压缩率
    38         binaryComp = de2bi(enco);
    39         encodedLen = numel(binaryComp);
    40         imgLen = numel(de2bi(I1));
    41         disp(strcat(['编码后传输的比特流长度为' num2str(encodedLen)]))
    42         disp(strcat(['原图片二进制编码比特长度为' num2str(imgLen)]))
    43         disp(strcat(['压缩率为' num2str(100*(imgLen-encodedLen)/imgLen) '%']))
    44 
    45 %bitstream接收
    46 %哈夫曼解码
    47 deco = huffmandeco(enco,dict);
    48 Idq = col2im(deco,[M,N],[M,N],'distinct')-120; %把向量重新转换成图像块,记得要把图像平移回去原来的区间;
    49 
    50 
    51 I_rq =  round(blkproc(Idq,[X X],'x.*P1',Q));%反量化
    52 
    53 I_rDCT = round(blkproc(I_rq,[X X],'idct2'));%对图像进行DCT反变换
    54 
    55 I_rDCT = Normalize(I_rDCT);%归一化到0-255区间
    56 
    57 
    58 
    59 figure
    60 subplot(1,2,1)
    61 imshow(gray_img);
    62 title('原图')
    63 
    64 
    65 subplot(1,2,2)
    66 %在matlab处理完数据好,我们希望显示或者imwrite写入图片时候,需要注意。如果直接对double之间的数据矩阵I运行imshow(I),
    67 %我们会发现有时候显示的是一个白色的图像。 这是因为imshow()显示图像时对double型是认为在0~1范围内,即大于1时都是显示为白色,
    68 %而imshow显示uint8型时是0~255范围。所以对double类型的图像显示的时候,要么归一化到0~1之间,
    69 %要么将double类型的0~255数据转为uint8类型
    70 imshow(I_rDCT/255);
    71 title('经压缩传输后解压的图像')
    72 
    73 
    74   

    Normalize函数:

    1 function OutImg = Normalize(InImg)
    2 ymax=255;ymin=0;
    3 xmax = max(max(InImg)); %求得InImg中的最大值
    4 xmin = min(min(InImg)); %求得InImg中的最小值
    5 OutImg = round((ymax-ymin)*(InImg-xmin)/(xmax-xmin) + ymin); %归一化并取整
    6 end
    TALK IS CHEAP, SHOW ME THE CODE
  • 相关阅读:
    Opengl绘制我们的小屋(二)第一人称漫游
    C# this.Invoke和this.BeginInvoke 最简单的写法
    C# 递归模型定义。赋值
    .net Core 2.1 后 Session保存,新页面获取不到值
    .net core mvc 错误信息显示 ModelState.AddModelError
    .net Core 依赖注入 Add********说明
    C# 中2个问号的作用。C#的??代表是什么意思
    asp.net mvc 加三层架构 完美搭配
    C# DataTable.Compute()用法
    C# DateTime判断时间
  • 原文地址:https://www.cnblogs.com/greatLong/p/10693276.html
Copyright © 2011-2022 走看看