图像大作业
第一部分 基础知识
2.相关程序如下
close all,clear all, clc;
load('hall.mat');
T=hall_color;
for count=1:120
for count2=1:168
if((count-60)^2+(count2-84)^2<=3600)
T(count,count2,1)=255;
T(count,count2,2)=0;
T(count,count2,3)=0;
end
end
end
image(T);
imwrite(T,'TI1.bmp','bmp');
效果为
close all, clear all, clc;
load('hall.mat');
T=hall_color;
for count=1:8
for count2=1:8
if(mod(count+count2,2)==0)
T((count-1)*15+1:count*15,(count2-1)*21+1:count2*21,1)=0;
T((count-1)*15+1:count*15,(count2-1)*21+1:count2*21,2)=0;
T((count-1)*15+1:count*15,(count2-1)*21+1:count2*21,3)=0;
end
end
end
image(T);
imwrite(T,'T2.bmp','bmp');
效果为
第二部分 图像压缩编码
1. 图像的预处理是将每个像素灰度值减去 128 ,这个步骤是否可以在变换域进行?请在测
试图像中截取一块验证你的结论。
这个步骤是完全可行的。
相关程序如下
clear all ,close all,clc;
load('JpegCoeff.mat');
load('hall.mat');
example=double(hall_gray(1:10,1:10));
sub=ones(10,10)*128;
dir=example-sub;
indir=idct2(dct2(example)-dct2(sub));
ans=dir-indir;
我们得到ans中最大的绝对值为1.136868377216160e-13,基本可以忽略不计,所以我们可以
知道,这个步骤是完全可行的。
2. 请编程实现二维DCT,并和MATLAB自带的库函数dct2 比较是否一致
相关程序如下
clear all, close all, clc;
load('hall.mat');
example=double(hall_gray(1:10,1:10));
%下为计算差别
difference=dct2(example)-mydct(example);
example2=double(hall_gray(1:10,1:20));
answ=dct2(example2);
function [back] = mydct(example)
[x y]=size(example);
D=zeros(x,y);
for h=1:x
for l=1:y
if h==1
D(h,l)=sqrt(1/x);
else
D(h,l)=sqrt(2/x)*cos((h-1)*(2*l-1)*pi/(2*x));
end
end
end
back=D*example*D';
end
得到的difference最大值为1.232902668846236e-12,可以忽略不计,所以两者功能
基本相同,只不过库函数可以计算非方阵的矩阵。
3. 如果将DCT 系数矩阵中右侧四列的系数全部置零,逆变换后的图像会发生什么变化?选
取一块图验证你的结论。如果左侧的四列置零呢?
相关程序如下
clear all ,close all,clc;
load('JpegCoeff.mat');
load('hall.mat');
middle=dct2(double(hall_gray)-ones(size(hall_gray))*128);
[x y]=size(middle);
middle1=[zeros(x,4),middle(:,(5:y))];
middle2=[middle(:,(1:(y-4))),zeros(x,4)];
transform=idct2(middle)+ones(size(middle))*128;
transform1=idct2(middle1)+ones(size(middle))*128;
transform2=idct2(middle2)+ones(size(middle))*128;
figure;
imshow(uint8(transform));
figure;
imshow(uint8(transform1));
figure;
imshow(uint8(transform2));
左侧置零后图像,明显变灰
右侧置零后图像,没有太大改变
出现上述情况的原因是,dct变换后左侧有很多直流分量,置零后,会使图像像128靠近,
所以会变灰,而右侧较多高频分量,置零后,虽然会减少图像的高频分量,但人眼对高频分
量并不敏感,所以会感觉图像变化不大。
4. 若对DCT 系数分别做转置、旋转90 度和旋转180 度操作(rot90) ,逆变换后恢复的
图像有何变化?选取一块图验证你的结论。
相关程序如下
clear all, close all, clc;
load('hall.mat');
middle=dct2(double(hall_gray)-128);
middle1=rot90(middle);
middle2=rot90(middle,2);
tt=idct2(middle)+128;
transform=idct2(middle')+128;
transform1=idct2(middle1)+128;
transform2=idct2(middle2)+128;
figure;
imshow(uint8(transform));
figure;
imshow(uint8(transform1));
figure;
imshow(uint8(transform2));
得到如下结果
转置
旋转90
旋转180
5. 如果认为差分编码是一个系统,请绘出这个系统的频率响应,说明它是一个高通滤波器。
DC 系数先进行差分编码再进行熵编码,说明DC 系数的高频频率分量更多
相关程序为
clear all,close all, clc;
freqz([-1 1],1);
我们得到这个滤波器的频率响应如下
可见此滤波器为高通滤波器。
6. DC 预 测 误 差 的 取 值 和 Category 值 有 何 关 系 ? 如 何 利 用 预 测 误 差 计 算 出 其
Category ?
如果DC系数为0,则Category为0,若DC系数不为0,那么
Category=floor(log2(abs(DC(count)))+1)
7. 你知道哪些实现Zig-Zag 扫描的方法?请利用MATLAB 的强大功能设计一种最佳方法。
这个没有想到如何利用已经优化过的矩阵算法进行运算,根据定义,我们可以得到如下程序
function [back] = zigzag(example)
back=zeros(64,1);
seq=[1,3,4,10,11,21,22,36,2,5,9,12,20,23,35,37,...
6,8,13,19,24,34,38,49,7,14,18,25,33,39,48,50,...
15,17,26,32,40,47,51,58,16,27,31,41,46,52,57,59,...
28,30,42,45,53,56,60,63,29,43,44,54,55,61,62,64];
a=zeros(64,1);
for count=1:8
a((count-1)*8+1:count*8)=example(:,count);
end
for count=1:64
back(seq(count))=a(count);
end
end
以及逆zigzag程序
function [back] = inv_zigzag(example)
back=zeros(8,8);
seq=[1,3,4,10,11,21,22,36,2,5,9,12,20,23,35,37,...
6,8,13,19,24,34,38,49,7,14,18,25,33,39,48,50,...
15,17,26,32,40,47,51,58,16,27,31,41,46,52,57,59,...
28,30,42,45,53,56,60,63,29,43,44,54,55,61,62,64];
middle=zeros(64,1);
for count=1:64
middle(count)=example(seq(count));
end
for count=1:8
back(:,count)=middle((count-1)*8+1:count*8);
end
8. 对测试图像分块、DCT 和量化,将量化后的系数写成矩阵的形式,其中每一列为一个块
的DCT系数Zig-Zag扫描后形成的列矢量,第一行为各个块的DC系数。
相关程序如下
clear all, close all, clc;
load('JpegCoeff.mat');
load hall.mat hall_gray;
[h l]=size(hall_gray);
h=8*ceil(h/8);
l=8*ceil(l/8);
%若图像横纵不为8的倍数,则要补全
example=zeros(h,l);
[h l]=size(hall_gray);
example(1:h,1:l)=hall_gray;
example=double(example)-128;
answer=zeros(64,ceil(h/8)*ceil(l/8));
for count=1:ceil(h/8)
for count2=1:ceil(l/8)
answer(:,(count-1)*ceil(l/8)+count2)=...
zigzag(round((dct2(example((count-1)*8+1:count*8,(count2-1)*8+1:count
2*8))./QTAB)));
end
end
9. 请实现本章介绍的JPEG 编码(不包括写JFIF 文件),输出为DC 系数的码流、AC 系
数的码流、图像高度和图像宽度,将这四个变量写入jpegcodes.mat 文件。
相关程序如下
T2_8
[h l]=size(answer);
DC=answer(1,:);
%差分运算如下
for count=2:l
DC(count)=answer(1,count-1)-answer(1,count);
end
DCCode=[];
for count=1:l
%找出cate,确定huff编码
if DC(count)==0
cate=1;
else
cate=floor(log2(abs(DC(count)))+2);
end
huff=DCTAB(cate,2:DCTAB(cate,1)+1);
coo=trans(DC(count));
DCCode=[DCCode huff coo];
end
DCCode=logical(DCCode);
ACCode=[];
AC=answer(2:64,:);
for count2=1:l
run=0;
last=find(AC(:,count2)~=0, 1, 'last' );
for count=1:last
if AC(count,count2)==0
if run>=15
ACCode=[ACCode 1 1 1 1 1 1 1 1 0 0 1];
run=0;
else
run=run+1;
end
else
%找出huff编码
if AC(count,count2)==-1||AC(count,count2)==1
cate=1;
else
cate=floor(log2(abs(AC(count,count2)))+1);
end
coo=trans(AC(count,count2));
ACCode=[ACCode
ACTAB(run*10+cate,4:ACTAB(run*10+cate,3)+3)...
coo];