视觉攻击是指利用人的视觉感知特性来判断载密图像异常变化。LSB替换选用最低位平面来嵌入秘密信息,最低位平面对图像的视觉效果影响最轻微。因此,可以从图像的最低有效位组成的图像中判断是否有隐藏消息。图像的LSB和最高位以及其他点有一定的关系,特别是对自然拍摄的BMP图像。但是在选择嵌入位置时,一般都同等对待载体中所有样本点,忽略了载体本身存在的空间相关性,就能够被观察出嵌入的痕迹。
对图像进行位平面分解:位平面是指依次取出每个像素点对应位的值组成一个位平面。一副灰度图像中每个像素点的灰度值可以由8个二进制来表示,因此可以分解成8个位平面。举例,假设图像有两个像素点,灰度值分别为1和3,其对应的二进制为分别为00000001和00000011,那么该图像分解成的8个位平面以此为00、00、00、00、00、00、01、11。每个位平面均为一个二值图,即像素点的值非0即1。
bitplanek = bitget(A,k); %获取A的第k位
clc
clear
A = imread("lennahide.bmp");
figure(1);
subplot(3,3,1);
imshow(A);
title('原始图像');
[h,w] = size(A);
for k=1:8
tmp = bitget(A,k);
subplot(3,3,k+1);
imshow(tmp,[]);
B = num2str(k+1);
title('位平面%s',B);
end;
分别抽取载密图像和原图像的最低位平面,进行对比
lsbbitplanek = bitget(A,1); %获取A的第1位
clc
clear
A = imread('lena_256.tiff');
[h,w] = size(A);
figure();
tmp = bitget(A,1);
subplot(1,2,1);
imshow(tmp,[]);
title('原始图像的最低位平面');
B = imread('lsbwatermarkedlena.tiff');
[h,w] = size(B);
tmp1 = bitget(B,1);
subplot(1,2,2);
imshow(tmp1,[]);
title('载密图像的最低位平面');
在不同嵌入率10%、30%、50%、70%下进行分析对比
function [ S,P_value ] = lsbplanekunit( image,rate )
% 函数功能:先对图像以嵌入率为rate进行顺序LSB嵌入,然后进行视觉隐写分析
% 输入参数:input是原始图像,rate是嵌入率,取值在[0,1]
% 调用例子:[ S,P_value ] = lsbplanekunit( 'livingroom.tif',0.5 )
%读一幅图像
cover=imread(image);
%cover=cover(:,:,1);
ste_cover=double(cover);
[m,n]=size(ste_cover);
%依据rate计算秘密信息位的长度,并生成秘密信息msg
msglen=floor(m*n*rate);
msg= rand(1,msglen); %这里可以直接用randint,如果机器上有的话
for i=1:msglen
if msg(i)>=0.5
msg(i)=1;
else
msg(i)=0;
end
end
%使用lsb隐写算法嵌入秘密信息
p=1;
for f2=1:n
for f1=1:m
if p>=msglen
break;
end
ste_cover(f1,f2)=ste_cover(f1,f2)-mod(ste_cover(f1,f2),2)+msg(1,p);
p=p+1;
end
if p==msglen
break;
end
end
A = imread(image);
[h,w] = size(A);
figure();
tmp = bitget(A,1);
subplot(1,2,1);
imshow(tmp,[]);
title('原始图像的最低位平面');
B = ste_cover;
[h,w] = size(B);
tmp1 = bitget(B,1);
subplot(1,2,2);
imshow(tmp1,[]);
title('载密图像的最低位平面');
chi-square分析又称卡方分析。普通图像像素值的分布情况由于LSB嵌入会发生变化。使用LSB嵌入水印时,如果像素值最低位比特与水印比特相同,那么保留该像素值不做变化;否则,使用水印比特位代替像素值的最低比特位。例如,水印比特位为1时,若像素值为(128)D=(1000 0000)B,则将像素值变为(129)D=(1000 0001)B;若像素值为(17)D=(0001 0001)B,则不改变该像素值。
分析该处理过程,像素值会由2i变为2i+1,而不会变为2i-1;或者由2i+1变为2i,而不会变为2i+2。即像素值在值对2i和2i+1之间翻转。因此,若用hi表示像素值为i的像素个数,那么,使用LSB嵌入后,h2i和h2i+1会比较接近,远小于普通图像中h2i和h2i+1的距离。
令
该值在嵌入前后不发生变化,当较大时,根据中心极限定理,下式成立。
即 服从标准正态分布。因此,统计量 服从自由度为k的开方分布。k为h2i和h2i+1组成的数字对,为0时不记在内。
由于 越小,表明h2i和h2i+1越接近,因此也意味着图像含水印的概率也越高。可以利用卡方分布的概率密度函数计算载体被隐写的概率:
卡方分析不仅能够对隐写率做出分析,能且能够判断嵌入位置。但如果隐写率较低,或者嵌入位置随机分布,卡方分析就难以奏效。
对原始图像和载密图像进行灰度直方图对比,选取部分像素值,观察h2i和h2i+1的在嵌入前和嵌入后的差值情况
n = hist(A(:), 0:255)’; %获取A的像素值分布,n为像素值统计矩阵,索引为像素值,值为该像素值的个数
stem(a:b,n(a+1:b+1)); %画出直方图,a:b为像素值区间
figure(3);
I1 = imread('lena_256.tiff');
A = I1(:,:,1);
subplot(1,2,1);
[m,n]=size(A);
[counts,x] = imhist(A,32);
counts = counts/(m*n);
stem(x,counts);
I2 = imread('lsbwatermarkedlena.tiff');
B = I2(:,:,1);
subplot(1,2,2);
[a,b]=size(B);
[counts,y] = imhist(B,32);
counts = counts/(a*b);
stem(y,counts);
依次取图像的部分比例区域,逐渐扩大,如从10%开始,每次加1%,直到100%
对这部分区域进行卡方检测,编写卡方检测函数
统计h2i和h2i+1 ,计算
计算
计算自由度k下的密度函数,得到隐写概率
p = 1 - chi2cdf(r, k - 1) %p为隐写概率,chi2cdf(r, k - 1)为卡方分布的概率密度函数
绘制分析区域比例和隐写概率曲线图
plot(x, p(1, :), ‘k-’, x, p(2, :), ‘r-.’, x, p(3, :), ‘b–’, x, p(4, :), ‘g–’, x, p(5, :), ‘c–’, x, p(8, :), ‘y–’); %绘制曲线函数,x为区域比例,p为不同嵌入率下的隐写概率
axis([10 100 0 1.2]); %坐标轴
legend(‘0%’, ‘10%’, ‘20%’, ‘30%’, ‘40%’, ‘70%’); %图例
xlabel(‘Size of sample(%)’); %横坐标轴说明
ylabel(‘Probability of embedding’); %纵坐标轴说明
clc
clear
I = imread('lena512.bmp');
sz = size(I);
for k = 1:11
rt = double(k-1)/10;
row = round(sz(1)*rt);
fprintf(1,'rt:%d\n',row);
col = sz(2);
msg = randsrc(row,col,[0 1;0.5 0.5]);
stg =I;
stg(1:row,1:col) = bitset(stg(1:row,1:col),1,msg);
imwrite(stg,sprintf('stg_%d.bmp',floor(100*rt)));
i =1;
for rto = 0.1:0.01:1
row = round(sz(1)*rto);
col = round(sz(2)*rto);
p(k,i) = LsbPrb(stg(1:row,1:col));
i=i+1;
end;
end;
x = round([0.1:0.01:1]*sz(1))/sz(1)*100;
figure;
plot(x,p(1,:),'k-',x,p(2,:),'r-',x,p(3,:),'b--',x,p(4,:),'g--',x,p(5,:),'c--',x,p(8,:),'y--');
axis([10 100 0 1.2]);
legend('0%','10%','20%','30%','40%','70%');
xlabel('Size of sample(%)');
ylabel('Probability of embedding');
其中的LsbPrb.m代码如下
function p=LsbPrb(x)
n=sum(hist(x,[0:255]),2);
h2i=n([3:2:255]);
h2is=(h2i+n([4:2:256]))/2;
filter=(h2is~=0);
k=sum(filter);
idx=zeros(1,k);
for i=1:127
if filter(i)==1
idx(sum(filter(1:i)))=i;
end;
end;
r=sum(((h2i(idx)-h2is(idx)) .^2)./(h2is(idx)));
p=1-chi2cdf(r,k-1);
在不同嵌入率0%、10%、30%、50%、70%下进行检测,分析检测的结果
function [ S,P_value ] = kafangunit( image,rate )
% 函数功能:先对图像以嵌入率为rate进行顺序LSB嵌入,然后进行卡方隐写分析
% 输入参数:input是原始图像,rate是嵌入率,取值在[0,1]
% 输出参数:S存放卡方统计值,P保存对应的p值,即观察值与估计值相似程度的概率
% 调用例子:[ S,P_value ] = kafang( 'livingroom.tif',0.5 )
%读一幅图像
cover=imread(image);
%cover=cover(:,:,1);
ste_cover=double(cover);
[m,n]=size(ste_cover);
%依据rate计算秘密信息位的长度,并生成秘密信息msg
msglen=floor(m*n*rate);
msg= rand(1,msglen); %这里可以直接用randint,如果机器上有的话
for i=1:msglen
if msg(i)>=0.5
msg(i)=1;
else
msg(i)=0;
end
end
%使用lsb隐写算法嵌入秘密信息
p=1;
for f2=1:n
for f1=1:m
if p>=msglen
break;
end
ste_cover(f1,f2)=ste_cover(f1,f2)-mod(ste_cover(f1,f2),2)+msg(1,p);
p=p+1;
end
if p==msglen
break;
end
end
I = ste_cover
sz = size(I);
for k = 1:11
rt = double(k-1)/10;
row = round(sz(1)*rt);
fprintf(1,'rt:%d\n',row);
col = sz(2);
msg = randsrc(row,col,[0 1;0.5 0.5]);
stg =I;
stg(1:row,1:col) = bitset(stg(1:row,1:col),1,msg);
imwrite(stg,sprintf('stg_%d.bmp',floor(100*rt)));
i =1;
for rto = 0.1:0.01:1
row = round(sz(1)*rto);
col = round(sz(2)*rto);
p(k,i) = LsbPrb(stg(1:row,1:col));
i=i+1;
end;
end;
x = round([0.1:0.01:1]*sz(1))/sz(1)*100;
figure;
plot(x,p(1,:),'k-',x,p(2,:),'r-',x,p(3,:),'b--',x,p(4,:),'g--',x,p(5,:),'c--',x,p(8,:),'y--');
axis([10 100 0 1.2]);
legend('0%','10%','20%','30%','40%','70%');
xlabel('Size of sample(%)');
ylabel('Probability of embedding');
参考文章
https://blog.csdn.net/HizT_1999/article/details/106951364?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-0&spm=1001.2101.3001.4242
参考代码
https://github.com/kalpatian/information_hidding