实验4MPEG编码1实验目的本试验通过MATLAB编程实现MPEG标准的avi文件的编解码,了解MPEG标准的视频文件的前后帧图片差分编码及解码方法。2实验步骤(1)首先设置8x8的离散余弦变换矩阵T、亮度维矩阵lighttable、色度为矩阵colortable以及64维向量sequence和sequence2;(2)获取avi文件信息,并读入该avi文件,设置图片分块的数量、每秒帧数、压缩、解压文件大小,以及参考帧等信息;(3)对avi文件进行前后帧图片差分编码及解码,包括DCT变换-量化-z字形编码-DC差分编码等以及DC差分编码-z字形解码-反量化-DCT逆变换等;(4)保存编码、解码文件分别为mpegrar.mat和out.mat,并计算使用时间,将解码文件保存成out.avi文件,可以在MATLAB中观看保存的解码文件out.mat。3MATLAB程序代码程序保存为mpeg_coding.m文件。functionmpeg_coding(filename)%MPEG压缩编码T=dctmtx(8);%Discretecosinetransformmatrixlighttable=...[1611101624405161;1212141926586055;1413162440576956;1417222951878062;182237566810910377;243555648110411392;49647887103121120101;7292959811210010399];%亮度维colortable=...[1718244799999999;1821266699999999;2426569999999999;4766999999999999;9999999999999999;9999999999999999;9999999999999999;9999999999999999];%色度维sequence=[192310172518114512192633413427201367...1421283542495750433629221581623303744515859...5245383124323946536061544740485562635664];sequence2=[134101121223625912202335376813192434...3849714182533394850151726324047515816273141...4652575928304245535660632943445455616264];tic;%Startastopwatchtimerinfor=aviinfo(filename)%InformationaboutAVIfilefs=infor.FramesPerSecond;%每秒帧数fprintf('正在读取视频...\n');finput=aviread(filename);%读入文件fprintf('读取视频完成...\n');frame=length(finput);[row,col,dim]=size(finput(1).cdata);r=ceil(row/8);%8*8块的数量c=ceil(col/8);mpegrar=int8(zeros(r*c,64,dim,frame));%压缩文件大小定义output=uint8(zeros(row,col,dim,frame));%解压文件大小定义imref=zeros(row,col,dim);%参考帧%前后帧图片差分编码fprintf('开始处理视频...\n');for(f=1:frame)pic=uint8((double(finput(f).cdata)-imref+255)./2);%pic为前后帧图片差pic=rgb2ycbcr(pic);%填补图片-行列转化为8的倍数temp=mod(size(pic,1),8);if(temp~=0)pic=[pic;uint8(zeros(8-temp,size(pic,2),3))];endtemp=mod(size(pic,2),8);if(temp~=0)pic=[pic,uint8(zeros(size(pic,1),8-temp,3))];endcleartemp%每一维输入转化为(-128~127)t1=double(pic(:,:,1))-2^7;t2=double(pic(:,:,2))-2^7;t3=double(pic(:,:,3))-2^7;%DCT变换-量化-z字形编码-DC差分编码%%处理亮度维count=1;p1=int8(zeros(r*c,64));for(i=1:r)for(j=1:c)temp=round(T*t1(8*i-7:8*i,8*j-7:8*j)*T'./lighttable);%DCT变换,量化p1(count,:)=temp(sequence);%z字形编码count=count+1;endendp1(:,1)=[p1(1);diff(p1(:,1))];%DC系数差分编码cleart1;%处理色度维count=1;p2=int8(zeros(r*c,64));for(i=1:r)for(j=1:c)temp=round(T*t2(8*i-7:8*i,8*j-7:8*j)*T'./colortable);p2(count,:)=temp(sequence);count=count+1;endendp2(:,1)=[p2(1);diff(p2(:,1))];cleart2;%处理色度维count=1;p3=int8(zeros(r*c,64));for(i=1:r)for(j=1:c)temp=round(T*t3(8*i-7:8*i,8*j-7:8*j)*T'./colortable);p3(count,:)=temp(sequence);count=count+1;endendp3(:,1)=[p3(1);diff(p3(:,1))];cleart3;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%mpegrar(:,:,:,f)=cat(3,p1,p2,p3);%保存的内容%DC系数差分解码for(i=2:size(p1,1))p1(i,1)=p1(i-1,1)+p1(i,1);p2(i,1)=p2(i-1,1)+p2(i,1);p3(i,1)=p3(i-1,1)+p3(i,1);end%%z字形解码-反量化-DCT逆变换%%%处理亮度维count=1;t1=zeros(8*r,8*c);for(i=1:r)for(j=1:c)tmp=p1(count,:);tmp=reshape(tmp(sequence2),[8,8]);%z字形解码t1(8*i-7:8*i,8*j-7:8*j)=T'*(double(tmp).*lighttable)*T;%反量化,DCT逆变换count=count+1;endendclearp1;%处理色度维count=1;t2=zeros(8*r,8*c);for(i=1:r)for(j=1:c)tmp=p2(count,:);tmp=reshape(tmp(sequence2),[8,8]);t2(8*i-7:8*i,8*j-7:8*j)=T'*(double(tmp).*colortable)*T;count=count+1;endendclearp2;%处理色度维count=1;t3=zeros(8*r,8*c);for(i=1:r)for(j=1:c)tmp=p3(count,:);tmp=reshape(tmp(sequence2),[8,8]);t3(8*i-7:8*i,8*j-7:8*j)=T'*(double(tmp).*colortable)*T;count=count+1;endendclearp3;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%每一维输出转化为(0~255)t1=uint8(t1+2^7);t2=uint8(t2+2^7);t3=uint8(t3+2^7);pic=ycbcr2rgb(cat(3,t1,t2,t3));%ycbcr-rgbpic=pic(1:row,1:col,:);%转化为原始图像大小pic=double(pic)*2-255;imref=imref+pic;%重新设定参考帧output(:,:,:,f)=uint8(imref);%解压内容fprintf('完成进度%1.2f%%',f/frame*100);%输出进度fprintf('\n');endfprintf('处理视频完成...\n');fprintf('开始保存文件...\n');savempegrarfsrowcol;saveoutput;fprintf('保存文件完成...\n');fprintf('压缩文件保存为mpegrar.mat\n');fprintf('解压文件保存为output.mat\n');fprintf('压缩解压共花费时间为%f秒\n',toc);clearcolrowdimcrTcolortablelighttablesequencesequence2;cleart1t2t3mpegrarfinputpicimref;clearcounttemptmpijffilenameinfor;%%%%%%%%%%%%%%%保存成avi格式%%%%%%%%%%%%%%%fprintf('开始保存成avi文件...\n');avifilename='output.avi';mov=avifile(avifilename,'compression','Indeo5','fps',fs);for(i=1:frame)mov=addframe(mov,output(:,:,:,i));endmov=close(mov);fprintf('保存avi文件完成...\n');fprintf('文件保存为out.avi\n');%%%在Matlab中播放%%%fprintf('按任意键观看视频...');pause();fprintf('\n');choice='y';while(choice=='y'||choice=='Y')for(i=1:frame)imshow(output(:,:,:,i));pause(1/4/fs);endclose;choice=input('再看一次[Y/N]:','s');end4实验结果与分析在MATLAB的CommandWindow窗口下输入:mpeg_coding('D:\test.avi')CommandWindow窗口输出显示为:infor=Filename:'D:\test.avi'FileSize:1128448FileModDate:'29-六月-201122:25:29'NumFrames:30FramesPerSecond:1Width:836Height:628ImageType:'truecolor'VideoCompression:'tscc'Quality:0NumColormapEntries:0AudioFormat:'PCM'AudioRate:8000NumAudioChannels:1正在读取视频...读取视频完成...开始处理视频...完成进度3.33%完成进度6.67%完成进度10.00%完成进度13.33%完成进度16.67%完成进度20.00%完成进度23.33%完成进度26.67%完成进度30.00%完成进度33.33%完成进度36.67%完成进度40.00%完成进度43.33%完成进度46.67%完成进度50.00%完成进度53.33%完成进度56.67%完成进度60.00%完成进度63.33%完成进度66.67%完成进度70.00%完成进度73.33%