加密域可逆信息隐藏经典算法(附加代码)
本文介绍加密域可逆信息隐藏经典算法,张新鹏教授的《Reversible Data Hiding in Encrypted Image》。主要分为图像加密、信息嵌入、信息提取与图像恢复三个过程。(图片必须是bmp格式的)
(代码和图片下载:链接:https://pan.baidu.com/s/1T24P3IU2pVN8b0UNNXJ5VQ 提取码:7aq2)
总体展示如下
算法流程如下
图像加密
假设图像大小为nm。因为像素每位都是由8位组成的,所以随机生成一个01矩阵(大小为8×n×m)作为加密秘钥。将原图像与加密秘钥进行异或,完成加密。
%生成加密秘钥
en_key =zeros(8,n,m);
for i=1:8
en_key(i,(1:n),(1:m)) = rand(n,m) < 0.5;
end
en_key = double(en_key);
%对图像进行加密
encrypted_img_bin = zeros(8,n,m);
for i=1:8
for j=1:n
for k=1:m
encrypted_img_bin(i, j, k) = xor(original_img_bin(i, j, k), en_key(i,j,k));
% encripted_img_bin(i, j, k) = mod(original_img_bin(i, j, k)+ en_key(i,j,k),2);
end
end
end
%将加密的二进制图像变成十进制
encrypted_img =zeros(n,m);
for i=1:8
for j=1:n
for k=1:m
encrypted_img(j,k) = encrypted_img(j,k) + 2^(i-1) * encrypted_img_bin(i,j,k);
end
end
end
信息嵌入
将加密的图像分为块,每个块的大小为8(8*8),即s=8;每个块内嵌入一个像素。则能嵌入的信息大小为n×m/s^2。随机生成一个01矩阵作为信息。在嵌入信息之前,随机生成一个01矩阵(大小为n×m),0就是集合S0,1就是集合S1。把每个块内的像素都分为两个集合S0和集合S1。之后在每个块内开始嵌入信息。如果嵌入的信息是0,就把这个块内属于集合S0的像素的最低三位取反,S1集合不变。如果嵌入的信息是1,就把这个块内属于集合S1的像素的最低三位取反,S0集合不变。
%生成集合概率 如果 < 0.5 为S0集合, 否则为S1集合;
set = rand(n,m) < 0.5;
%生成嵌入信息 信息大小为[n/blocksize, m/blocksize]
message = rand(n/blocksize, m/blocksize) < 0.5;
%向加密图像中嵌入信息,
for i=1:n/blocksize
for j=1:m/blocksize
if(message(i,j) == 0) %嵌入信息为0
%将这块内的S0集合的后三位取反
for k1=(i-1)*blocksize+1:i*blocksize
for k2=(j-1)*blocksize+1:j*blocksize
if(set(k1,k2) == 0)
for k3 =1:modify_bit
encrypted_img_bin(k3,k1,k2) = ~encrypted_img_bin(k3,k1,k2); %取反
end
end
end
end
else %嵌入信息为1
%将这块内的S1集合的后三位取反
for k1=(i-1)*blocksize+1:i*blocksize
for k2=(j-1)*blocksize+1:j*blocksize
if(set(k1,k2) == 1)
for k3 =1:modify_bit
encrypted_img_bin(k3,k1,k2) = ~encrypted_img_bin(k3,k1,k2); %取反
end
end
end
end
end
end
end
%将嵌入信息的加密图像变成十进制
encrypted_img = zeros(n,m);
for i=1:8
for j=1:n
for k=1:m
encrypted_img(j,k) = encrypted_img(j,k) + 2^(i-1) * encrypted_img_bin(i,j,k);
end
end
end
信息提取与图像恢复
首先先把嵌入信息的加密图像解密。把嵌入信息的加密图像与开始生成的随机秘钥异或,得到解密后的嵌入信息图像。
%解密已嵌入信息的加密图像
decrypted_img_bin = zeros(8,n,m);
for i=1:8
for j=1:n
for k=1:m
decrypted_img_bin(i,j,k) = xor(encrypted_img_bin(i,j,k), en_key(i,j,k));
end
end
end
%将解密后的已嵌入信息的加密图像转化为十进制
decrypted_img = zeros(n,m);
for i=1:8
for j=1:n
for k=1:m
decrypted_img(j,k) = decrypted_img(j,k) + 2^(i-1) * decrypted_img_bin(i,j,k);
end
end
end
之后,把每个块内属于S0集合的像素的最低三位取反,S1集合的不变,形成一个新的块block0。把每个块内属于S1集合的像素的最低三位取反,S0集合不变,形成一个新的图像block1。在block0和block1中,就必定有一个是原始块,一个是更加混乱的块。如果block0是原始块,就表明嵌入的是0,否则嵌入的就是1。现在需要的是判断哪一个是原始块。我们可以根据在自然图像中,由于空间相关性的原因,原始块的波动函数普遍低于受严重干扰版本的波动函数。利用波动函数进行判断,波动函数值小的那个就是原始块。
%提取数据后恢复的图像
%利用波动公式判断每个块中嵌入的数据是0还是1
recover = zeros(n,m);
infermessage = zeros(n/blocksize,m/blocksize);
for i=1:n/blocksize
for j=1:m/blocksize
H0_img = zeros(n,m);
H1_img = zeros(n,m);
for k =(i-1)*blocksize+1:i*blocksize
for k1=(j-1)*blocksize+1:j*blocksize
%转化为十进制
for k2=1:8
if(set(k,k1) == 0)
if(k2 > modify_bit )
H0_img(k,k1) = H0_img(k,k1) + (decrypted_img_bin(k2,k,k1)) * 2 ^(k2-1);
else
H0_img(k,k1) = H0_img(k,k1) + ~(decrypted_img_bin(k2,k,k1)) * 2 ^(k2-1);
end %将H0集合后面三位取反
H1_img(k,k1) = H1_img(k,k1) + (decrypted_img_bin(k2,k,k1)) * 2 ^(k2-1); %H1集合不变
end
if(set(k,k1) == 1)
if(k2 > modify_bit )
H1_img(k,k1) = H1_img(k,k1) + (decrypted_img_bin(k2,k,k1)) * 2 ^(k2-1);
else%将H1集合后面三位取反
H1_img(k,k1) = H1_img(k,k1) + ~(decrypted_img_bin(k2,k,k1)) * 2 ^(k2-1);
end
H0_img(k,k1) = H0_img(k,k1) + (decrypted_img_bin(k2,k,k1)) * 2 ^(k2-1); %H0集合不变
end
end
end
end
f0 = 0;
f1 = 0;
%利用波动公式判断嵌入的数据是原图数据是H1集合还是H0集合
for k2=(i-1)*blocksize+2:i*blocksize-1
for k3=(j-1)*blocksize+2:j*blocksize-1
f0 = f0 + abs( H0_img(k2,k3)-( H0_img(k2-1,k3) + H0_img(k2,k3-1) + H0_img(k2+1,k3) + H0_img(k2,k3+1))/4 );
f1 = f1 + abs(H1_img(k2,k3)-(H1_img(k2-1,k3) + H1_img(k2,k3-1) + H1_img(k2+1,k3) + H1_img(k2,k3+1))/4 );
end
end
if(f0 < f1)
for k1 = (i-1)*blocksize+1:i*blocksize
for k2=(j-1)*blocksize+1:j*blocksize
recover(k1,k2) = H0_img(k1,k2);
end
end
infermessage(i,j) = 0;
else
for k1 = (i-1)*blocksize+1:i*blocksize
for k2=(j-1)*blocksize+1:j*blocksize
recover(k1,k2) = H1_img(k1,k2);
end
end
infermessage(i,j) = 1;
end
end
end
将提取的信息与原信息进行对比,找出错误块。并计算峰值信噪比(PSNR)。
%原始图与从嵌入数据恢复的图像之间均方误差
s = 0;
for i=1:n
for j=1:m
s = s + ( double(original_img(i,j)) - decrypted_img(i,j))^2;
end
end
mse1 = s/(n*m);
psnr1= 10*log10(255^2/mse1)%峰值信噪比 评价图像的指标
%PSNR值越大,就代表失真越少。
%原图像与提取数据恢复的图像之间均方误差
s = 0;
for i=1:n
for j=1:m
s = s + ( double(original_img(i,j)) - recover(i,j))^2;
end
end
mse1 = s/(n*m);
psnr1= 10*log10(255^2/mse1)%峰值信噪比 评价图像的指标
%PSNR值越大,就代表失真越少。
交流可加QQ:1114693754