【最全的】DCT变换可逆信息隐藏原理及代码(matlab实现)

DCT变换

DCT又称离散余弦变换,是一种块变换方式,只使用余弦函数来表达信号,与傅里叶变换紧密相关。常用于图像数据的压缩,通过将图像分成大小相等(一般为8*8)的块,利用DCT对其进行变换,得到更加简洁的数据。因为图像像素间存在较大的空间相关性,DCT可以大大减小这些相关性,使图像能量集中在左上角区域,从而利于数据压缩。变换后得到的数据称为DCT系数。这一过程是无损的。

DCT变换的代码实现分为两种:

1.使用dct函数

% 读取灰度图像
img = imread('lena.pgm');
% dct2 是2维dct变换函数,得到一个与图像大小相同的二维矩阵
dct_mtx = dct2(img);
% idct2 是逆2维dct变换函数,得到原图像矩阵
img_idct = idct2(dct_mtx); 

2.使用dctmtx函数

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变换的基础,所以我们先来讨论下一维DCT变换。一维DCT变换共有8种形式,其中最常用的是第二种形式,由于其运算简单、适用范围广。我们在这里只讨论这种形式,其表达式如下:
【最全的】DCT变换可逆信息隐藏原理及代码(matlab实现)_第1张图片
其中,f(i)为原始的信号,F(u)是DCT变换后的系数,N为原始信号的点数,c(u)可以认为是一个补偿系数,可以使DCT变换矩阵为正交矩阵。

二维DCT变换

二维DCT变换其实是在一维DCT变换的基础上在做了一次DCT变换,其公式如下:
【最全的】DCT变换可逆信息隐藏原理及代码(matlab实现)_第2张图片
由公式我们可以看出,上面只讨论了二维图像数据为方阵的情况,在实际应用中,如果不是方阵的数据一般都是补齐之后再做变换的,重构之后可以去掉补齐的部分,得到原始的图像信息,这个尝试一下,应该比较容易理解。

另外,由于DCT变换高度的对称性,在使用Matlab进行相关的运算时,我们可以使用更简单的矩阵处理方式:
在这里插入图片描述

二维DCT逆变换

在图像的接收端,根据DCT变化的可逆性,我们可以通过DCT反变换恢复出原始的图像信息,其公式如下:
【最全的】DCT变换可逆信息隐藏原理及代码(matlab实现)_第3张图片
同样的道理,我们利用之前的矩阵运算公司可以推导出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系数的相对大小,得到
隐藏信息的比特串,从而提取出秘密信息。

附上matlab代码一份



% 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

你可能感兴趣的:(【最全的】DCT变换可逆信息隐藏原理及代码(matlab实现))