DCT又称离散余弦变换,是一种块变换方式,只使用余弦函数来表达信号,与傅里叶变换紧密相关。常用于图像数据的压缩,通过将图像分成大小相等(一般为8*8)的块,利用DCT对其进行变换,得到更加简洁的数据。因为图像像素间存在较大的空间相关性,DCT可以大大减小这些相关性,使图像能量集中在左上角区域,从而利于数据压缩。变换后得到的数据称为DCT系数。这一过程是无损的。
% 读取灰度图像
img = imread('lena.pgm');
% dct2 是2维dct变换函数,得到一个与图像大小相同的二维矩阵
dct_mtx = dct2(img);
% idct2 是逆2维dct变换函数,得到原图像矩阵
img_idct = idct2(dct_mtx);
io = double(imread("lena.pgm"));
T = dctmtx(8);
% 对载体图像进行DCT变换
DCT_org = blkproc(io,[8 8], 'P1*x*P2',T, T');
% 对DCT 矩阵进行逆变换
DCT_reverse = blkproc(DCT_org,[8 8], 'P1*x*P2',T', T);
数学原理转自:点击这里
一维DCT变换时二维DCT变换的基础,所以我们先来讨论下一维DCT变换。一维DCT变换共有8种形式,其中最常用的是第二种形式,由于其运算简单、适用范围广。我们在这里只讨论这种形式,其表达式如下:
其中,f(i)为原始的信号,F(u)是DCT变换后的系数,N为原始信号的点数,c(u)可以认为是一个补偿系数,可以使DCT变换矩阵为正交矩阵。
二维DCT变换其实是在一维DCT变换的基础上在做了一次DCT变换,其公式如下:
由公式我们可以看出,上面只讨论了二维图像数据为方阵的情况,在实际应用中,如果不是方阵的数据一般都是补齐之后再做变换的,重构之后可以去掉补齐的部分,得到原始的图像信息,这个尝试一下,应该比较容易理解。
另外,由于DCT变换高度的对称性,在使用Matlab进行相关的运算时,我们可以使用更简单的矩阵处理方式:
在图像的接收端,根据DCT变化的可逆性,我们可以通过DCT反变换恢复出原始的图像信息,其公式如下:
同样的道理,我们利用之前的矩阵运算公司可以推导出DCT反变换相应的矩阵形式:
隐藏方法:主要是利用载体中两个特定数的相对大小来表
示隐藏信息。发送方和接收方事先约定好嵌入过程中所使用
的两个DCT系数的位置(为了隐藏的健壮性和不可觉察性,这
两个 DCT 系数应该在 DCT 的中频系数中选择)。例如,设定
(u,v) 和 (m,n) 为所选定的两个系数的坐标。嵌入过程为:如果
Bi(u,v)> Bi(m,n) ,就代表隐藏信息“1”,如果 Bi(u,v)< Bi(m,n) 就代
表 隐 藏 信 息“0”。 如 果 需 要 隐 藏 的 信 息 位 为 1,但 是
Bi(u,v)
提取方法:接收方接收到图像后,对图像进行二维DCT变
换,通过比较每一块中约定位置的DCT系数的相对大小,得到
隐藏信息的比特串,从而提取出秘密信息。
% DCT 变换信息隐藏
io = double(imread("lena.pgm"));
imshow(io)
% 待嵌入的秘密信息msg
msg = [1,0,1,1];
% 用于计数,嵌入完成后停止操作。
count = length(msg);
org_msg = [1,0,1,1];
T = dctmtx(8);
DCTrgb = blkproc(io,[8 8], 'P1*x*P2',T, T'); % 对载体图像进行DCT变换
[row,col]=size(DCTrgb);
row=floor(row/8);
col=floor(col/8);
alpha=0.02;
k = 1;
temp=0;
for i=0:(row - 1)
for j=0: (col -1)
irow = i * 8;
jcol = j * 8;
if k <= count
if msg(k) == 0
%选择(5,2),(4,3)这两对系数,
% 策略是(5,2)的DCT系数 < (4,3)时,表示嵌入了0
% 如果(5,2) > (4,3) 那我们把两个系数交换,还表示嵌入了0
if DCTrgb(irow + 5, jcol + 2) < DCTrgb(irow + 4,jcol + 3)
temp = DCTrgb(irow + 5, jcol + 2);
DCTrgb(irow + 5, jcol + 2) = DCTrgb(irow + 4,jcol + 3);
DCTrgb(irow + 4, jcol + 3) = temp;
end
else
if DCTrgb(irow + 5, jcol + 2) > DCTrgb(irow + 4,jcol + 3)
temp = DCTrgb(irow + 5, jcol + 2);
DCTrgb(irow + 5, jcol + 2) = DCTrgb(irow + 4,jcol + 3);
DCTrgb(irow + 4, jcol + 3) = temp;
end
end
%将原本小的系数变的更小,使系数差变大
if DCTrgb(irow + 5, jcol + 2) < DCTrgb(irow + 4,jcol +3)
DCTrgb(irow + 5, jcol + 2) = DCTrgb(irow +5, jcol +2) - alpha;
else
DCTrgb(irow + 4, jcol + 3) = DCTrgb(irow + 4, jcol +3) - alpha;
end
k = k + 1;
end
end
end
wi=blkproc(DCTrgb,[8 8],'P1*x*P2',T',T); %嵌入信息的载体DCT变换,恢复图像
% 提取消息
% ext_msg是提取出的秘密信息
ext_msg = [];
T=dctmtx(8);
DCTcheck=blkproc(wi,[8 8],'P1*x*P2',T,T'); %对隐秘图像进行DCT变换
[row,col]=size(DCTcheck);
row=floor(row/8);
col=floor(col/8);
k = 1;
for i=0:(row - 1)
for j=0: (col -1)
irow = i * 8;
jcol = j * 8;
%通过比较(5,2),(4,3)这两对系数,判断隐藏的信息是1还是0
if k <= count
if DCTcheck(irow + 5, jcol + 2) < DCTcheck(irow + 4,jcol + 3)
ext_msg(k,1)=1;
end
if DCTcheck(irow + 5, jcol + 2) > DCTcheck(irow + 4,jcol + 3)
ext_msg(k,1)=0;
end
k = k + 1;
end
end
end