数字图像处理(作业二)——离散余弦变换(DCT)的应用

一、离散余弦变换能力

实验要求:
计算图像的2维离散余弦变换,将其中数值最小的10%、30%……个系数设定为0,作反变换看它们与原始图像的区别,并计算均方根误差
重点:
实现将数值最小的10%个系数设定为0的步骤:
1.将矩阵排成一个向量,并利用sort排序
2.在排完序的向量从前到后取出数值,并在矩阵中匹配,匹配相同的位置的数置零
代码:

clc;
clear;

A=imread('picture.jpeg');
A=rgb2gray(A);
subplot(2,3,1);
imshow(A,[]);title('原图')

D_A=dct2(A);
[M,N]=size(D_A);
A_array=reshape(abs(D_A),[1,M*N]);  %将矩阵变换向量形式
A_array=sort(A_array);              %将向量按升序排列

n=0.1;
D_A1=D_A;
value=A_array(round(M*N*n));        %取出指定位置的阈值
for i=1:M
    for j=1:N
        if abs(D_A1(i,j))<value     %小于阈值的直接归0
            D_A1(i,j)=0;
        end
    end
end
A1=idct2(D_A1);
error1=sqrt(sum(sum((A1-double(A)).^2))/(M*N));
x_1=['均方根误差' num2str(error1)];
subplot(232);
imshow(A1,[]);title('0.1删除');xlabel(x_1);

n=0.3;
D_A3=D_A;
value=A_array(round(M*N*n));
for i=1:M
    for j=1:N
        if abs(D_A3(i,j))<value
            D_A3(i,j)=0;
        end
    end
end
A3=idct2(D_A3);
error3=sqrt(sum(sum((A3-double(A)).^2))/(M*N));
x_3=['均方根误差' num2str(error3)];
subplot(233);
imshow(A3,[]);title('0.3删除');xlabel(x_3);

n=0.5;
D_A5=D_A;
value=A_array(round(M*N*n));
for i=1:M
    for j=1:N
        if abs(D_A5(i,j))<value
            D_A5(i,j)=0;
        end
    end
end
A5=idct2(D_A5);
error5=sqrt(sum(sum((A5-double(A)).^2))/(M*N));
x_5=['均方根误差' num2str(error5)];
subplot(234);
imshow(A5,[]);title('0.5删除');xlabel(x_5);

n=0.99;
D_A7=D_A;
value=A_array(round(M*N*n));
for i=1:M
    for j=1:N
        if abs(D_A7(i,j))<value
            D_A7(i,j)=0;
        end
    end
end
A7=idct2(D_A7);
C=(A7-double(A)).^2;
error7=sqrt(sum(sum(C))/(M*N));
x_7=['均方根误差' num2str(error7)];
subplot(235);
imshow(A7,[]);title('0.99删除');xlabel(x_7);

结果:
在这里插入图片描述
分析:
1.离散余弦变换较好地将大部分的信息存在了较少的系数中

二、彩色图像操作

实验要求:
将彩色图像从RGB模型转换到YCbCr模型,对各通道做DCT,CbCr去掉70%的系数,Y去掉30%的系数
重点:
1.ycbcr2rgb(YCBCR1)中要求YCBCR1是uint8类型,如果是double的话就没了
代码实现:

clc;
clear;
A=imread('picture.jpeg');

%显示原图像并取出RGB分量
subplot(121);
imshow(A,[]);
R=A(:,:,1);
G=A(:,:,2);
B=A(:,:,3);

%将RGB转换为YCBCR
YCBCR=rgb2ycbcr(A);
Y=YCBCR(:,:,1);
CB=YCBCR(:,:,2);
CR=YCBCR(:,:,3);

%对Y CB CR作离散余弦变换
Y_D=dct2(Y);
CB_D=dct2(CB);
CR_D=dct2(CR);

%对Y分量进行量化
ny=0.2;
[M,N]=size(Y);
Y_array=reshape(abs(Y_D),[1,M*N]);  
Y_array=sort(Y_array);                 %构造幅值从小到大的向量
value_Y=Y_array(round(M*N*ny));        %对阈值进行索引
Y_D1=Y_D;
for i=1:M
    for j=1:N
        if abs(Y_D1(i,j))<value_Y
            Y_D1(i,j)=0;
        end
    end
end
Y1=idct2(Y_D1);                        %小于阈值的都归零

%对CB分量进行量化
ncb=0.999;
[M,N]=size(CB_D);
CB_array=reshape(abs(CB_D),[1,M*N]);    
CB_array=sort(CB_array);
value_CB=CB_array(round(M*N*ncb));
CB_D1=CB_D;
for i=1:M
    for j=1:N
        if abs(CB_D1(i,j))<value_CB
            CB_D1(i,j)=0;
        end
    end
end
CB1=idct2(CB_D1);

%对CR分量进行量化
ncr=0.999;
[M,N]=size(CR_D);
CR_array=reshape(abs(CR_D),[1,M*N]);
CR_array=sort(CR_array);
value_CR=CR_array(round(M*N*ncr));
CR_D1=CR_D;
for i=1:M
    for j=1:N
        if abs(CR_D1(i,j))<value_CR
            CR_D1(i,j)=0;
        end
    end
end
CR1=idct2(CR_D1);

%YCBCR1=cat(3,Y1,CB1,CR1);
YCBCR1(:,:,1)=(Y1);
YCBCR1(:,:,2)=(CB1);
YCBCR1(:,:,3)=(CR1);
YCBCR1=uint8(YCBCR1);
RGB=ycbcr2rgb(YCBCR1);
R1=RGB(:,:,1);
G1=RGB(:,:,2);
B1=RGB(:,:,3);
error_R=sqrt(sum(sum((R-R1).^2))/(M*N));
error_G=sqrt(sum(sum((G-G1).^2))/(M*N));
error_B=sqrt(sum(sum((B-B1).^2))/(M*N));
x_error=['R' num2str(error_R) ' G' num2str(error_G) ' B' num2str(error_B)];
subplot(122);
imshow(RGB,[]);title('process Y:0.2 CB:0.999 CR:0.999');xlabel(x_error);

结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
分析:
1.可以发现人眼对Y分量比较敏感,对CbCr较不敏感

三、基于DCT的不可见的鲁棒水印

实验要求:
实现基于DCT的不可见的鲁棒水印
重点:
1.由于添加了一些随机数,故最大的那些值可能在次序上发生了变化,故做相关分析时应先对他们进行排序
代码实现:

clc;
clear;

A=imread('picture.jpeg');
A=rgb2gray(A);

K=20;
a=0.5;
%对A作离散余弦变换
A_D=dct2(A);
A_Dd=A_D;
%定位前k个最大系数(幅值)
[M,N]=size(A_D);
A_array=reshape(abs(A_Dd),[1,M*N]);
A_array=sort(A_array);
%生成随机数
Ra=(randn(1,K));
%添加水印
for k=1:K
    for i=1:M
        for j=1:N
            if abs(A_D(i,j))==A_array(end+1-k)
                A_D(i,j)=A_D(i,j)*(1+a*Ra(k));
                t=['the i is ',num2str(i),' the j is ',num2str(j)];
                disp(t);
            end
        end
    end
end
A1=idct2(A_D);
subplot(121);
imshow(A,[]);title('原图像');

disp('\r\n');

%提取水印
A1_D=dct2(A1);
[M1,N1]=size(A1_D);
%找到前20个最大系数
A1_array=reshape(abs(A1_D),[1,M1*N1]);
A1_array=sort(A1_array);
for k=1:K
    for i=1:M1
        for j=1:N1
            if abs(A1_D(i,j))==A1_array(end+1-k)
                w1(k)=(A1_D(i,j)-A_Dd(i,j))/(a*A_Dd(i,j));
                t=['the i is ',num2str(i),' the j is ',num2str(j)];
                disp(t);
            end
        end
    end
end
subplot(122);
imshow(A1,[]);title('加水印后的图');

%求相关系数前一定要排序,因为次序可能会发生变化
R=corrcoef(sort(Ra),sort(w1));
str1=['相关系数为' num2str(R(1,2))];
disp(str1);

结果:
在这里插入图片描述
在这里插入图片描述
分析:
1.a不能过大,不然就图像就会发生变化
2.图像没有处理但是相关系数却不是1,原因不得而知。。。

matlab源文件开头务必加上clc和clear!

发布了99 篇原创文章 · 获赞 29 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_44586750/article/details/103168949