利用哈达玛变换对真彩色图像进行压缩

  彩色图像的信息量很大,尤其是真彩色的活动图像,由于每秒的帧数有25帧,储存和传输都很不方便。减少彩色图像信息量需要通过压缩完成,依图像在压缩过程中是否受到损伤,压缩可分为无损压缩和有损压缩。有损压缩主要采用变换编码,例如离散余弦变换、斜变换、沃尔什变换、小波变换等。将离散余弦变换的余弦函数集替换为哈达玛矩阵,通过模仿JPEG的原理,可对图像进行压缩。由于哈达玛矩阵是一个二值化矩阵,仅由1和-1构成,计算较为简单。

  程序运行环境:scilab-4.0 , sivp 0.5。

function mqt=dht(mqc0, Q, Qdc)  // 离散哈达玛变换
    mqt =round(M_HAD * int32(mqc0) * M_HAD) * SCALE;
    mqt1 =mqt(1) / Qdc; // 直流系数单独量化
    mqt = mqt/ Q;
    mqt(1) =mqt1;
endfunction

function mqc=idht(mqt, Q, Qdc)  // 离散哈达玛反变换
    mqt1 =mqt(1) * Qdc; // 直流系数单独反量化
    mqt = mqt* Q;
    mqt(1) =mqt1;
    mqc =round(M_HAD * int32(mqt) * M_HAD) / (BLOCKSIZE^2) / SCALE;
      // 数据类型非常重要,若数据类型精度低,会引起误差
endfunction

function snr=psnr(mqc0, mqc)
    snrt =max(abs(mqc0-mqc));
    snr =mean2(abs(mqc0-mqc));
    ifsnrt>snr
      snr =snrt;
    end
endfunction

function snr=rsnr(mqc0, mqc)
    snr =mean2(abs(mqc0-mqc));
endfunction

// Image Compression

clc;
clear all;
clear im0;
M_HAD1 = [ +1 ];
M_HAD2 = [ M_HAD1 M_HAD1; M_HAD1  -M_HAD1];
M_HAD4 = [ M_HAD2 M_HAD2; M_HAD2  -M_HAD2];
M_HAD8 = [ M_HAD4 M_HAD4; M_HAD4  -M_HAD4];
M_HAD16 = [ M_HAD8 M_HAD8; M_HAD8  -M_HAD8];
M_HAD32 = [ M_HAD16 M_HAD16; M_HAD16  -M_HAD16];
M_HAD64 = [ M_HAD32 M_HAD32; M_HAD32  -M_HAD32];

stacksize(40000000)

BLOCKSIZE = 16;
M_HAD = M_HAD16;

fname = "C:\in.png"
im0 = imread(fname);
z = size(im0)
xsize = z(2)/BLOCKSIZE
ysize = z(1)/BLOCKSIZE
mqc = zeros(BLOCKSIZE,BLOCKSIZE);
mqc0 = zeros(BLOCKSIZE,BLOCKSIZE);
mqd = zeros(z);
mqtd = zeros(z);

SCALE = 1;   // 直流系数
Q1 = 256;   // 压缩系数
Q2 = 128;  // 压缩系数
Q3 = 256;  // 压缩系数

Q1dc = 8;
Q2dc = 8;
Q3dc = 8;

//imt=rgb2ycbcr(im0);
//im0=int32(imt *255);
//imt=[];

snr1 = 0;
snr2 = 0;
snr3 = 0;

for i=0:xsize-1
 i0=i*BLOCKSIZE+1;
 i1=i0+BLOCKSIZE-1;
  forj=0:ysize-1
   j0=j*BLOCKSIZE+1;
   j1=j0+BLOCKSIZE-1;
    mqc0 =int32(im0(j0:j1,i0:i1,1));     // Cb   // 采用int16计算时,即便在DC=11比特时都会产生很大误差
    mqt =dht(mqc0, Q1, Q1dc);
    mqc =idht(mqt, Q1, Q1dc);
    mqd(j0:j1,i0:i1,1) = uint8(mqc);  
    mqtd(j0:j1,i0:i1,1) = int32(mqt);
    snr1 =psnr(mqc0,mqc);
    snrr1 =rsnr(mqc0,mqc);

    mqc0 =int32(im0(j0:j1,i0:i1,2));    // Y   // 采用int16计算时,即便在DC=11比特时都会产生很大误差
    mqt =dht(mqc0, Q2, Q2dc);
    mqc =idht(mqt, Q2, Q2dc);
    mqd(j0:j1,i0:i1,2) = uint8(mqc);
    mqtd(j0:j1,i0:i1,2) = int32(mqt);
    snr2 =psnr(mqc0,mqc);
    snrr2 =rsnr(mqc0,mqc);

    mqc0 =int32(im0(j0:j1,i0:i1,3));    // Cr   // 采用int16计算时,即便在DC=11比特时都会产生很大误差
    mqt =dht(mqc0, Q3, Q3dc);
    mqc =idht(mqt, Q3, Q3dc);
    mqd(j0:j1,i0:i1,3) = uint8(mqc);
    mqtd(j0:j1,i0:i1,3) = int32(mqt);
    snr3 =psnr(mqc0,mqc);
    snrr3 =rsnr(mqc0,mqc);
  end
end

//mqt=ycbcr2rgb(mqd/255)*255;
//mqd=mqt;
//mqt=[];

printf("\nDone.\n");
printf("Peak ERR.: R:%d, G:%d,B:%d\n",snr3,snr2,snr1);
printf("Peak SNR.: R:%4.1f dB, G:%4.1f dB,B:%4.1fdB\n",20*log10(double(snr3)/255),20*log10(double(snr2)/255),20*log10(double(snr1)/255));
printf("Mean ERR.: R:%d, G:%d, B:%d\n",snrr3,snrr2,snrr1);
printf("Mean SNR.: R:%4.1f dB, G:%4.1f dB,B:%4.1fdB\n",20*log10(double(snrr3)/255),20*log10(double(snrr2)/255),20*log10(double(snrr1)/255));

你可能感兴趣的:(利用哈达玛变换对真彩色图像进行压缩)