编程语言
首页 > 编程语言> > 数字水印 改进的patchwork算法 实现

数字水印 改进的patchwork算法 实现

作者:互联网

一、算法原理

1、参考论文

甘霖,杨榆.基于变换域的Patchwork水印改进算法[J].成都信息工程大学学报,2017,32(06):623-627.

2、理论基础

(1)离散余弦变换

在水印算法中引入图像的变换域用于嵌入水印,以此增强水印的透明性。

(2)人类视觉系统特性

人类的视觉系统对不同颜色的敏感程度不同。由亮度方程 y = 0.299R+0.587G+0.144B可知,人眼对绿色光最为敏感,对红色光的敏感程度次之,对于蓝色光最不敏感。人眼对红色光和蓝色光的敏感程度之和与对绿色光的敏感程度较为接近。该论文使用红色和蓝色光部分作为 Pacthwork 算法的 A 集合,绿色光作为 B 集合,两个集合在嵌入信息时使用相逆的操作,可以在一定程度上互相抵消嵌入信息引起的图像视觉上的变化,提高水印透明性。

3、具体算法

(1)水印的嵌入

1)图片预处理
载体图像 I 与水印图像W选取正方形的 RGB 图像,并满足载体图像的边长为 8 的倍数且载体图像边长为水印图像边长的 8 倍。将载体图像 I 的 3 个颜色通道分离,得到 IR、IG、IB 3 个颜色分量; 将水印图像W 的 3 个颜色通道分离,得到 WR、WG、WB 3 个颜色分量。
2)对水印Arnold置换
对WR、WG、WB三个颜色分量进行Arnold变换,变换的过程可以看作是拉伸、压缩、折叠及拼接的过程,经过变换得到WRA、WGA、WBA。Arnold变换过程如下:
在这里插入图片描述

其中(x,y)为图像上点坐标。
3)对载体图像进行DCT变换并提取直流分量。
载体图像的各分量以8×8的大小为一个单位划分为若干子块。将子块视为一个整体,最左上角的子块位置坐标为(1,1),其相邻的右边的子块位置坐标为( 1,2) ,依此类推。对每一个子块分别应用DCT 变换,然后取出变换后的每一个子块左上角的直流分量组成一个新矩阵,位置坐标为( 1,1) 的子块的直流分量作为新矩阵( 1,1) 位置的元素,位置坐标为 (1,2) 的子块的直流分量作为新矩阵( 1,2) 位置的元素,依此类推。最终所得的矩阵称为直流分量矩阵IRD、IBD、IGD。
4)在直流分量矩阵中嵌入水印
在直流分量矩阵上嵌入水印,嵌入方法是增加/减去置乱的水印图像分量k倍的亮度。分量提取公式如下:
在这里插入图片描述
其中绿色分量在亮度处理时使用减操作,红色分量和蓝色分量使用加操作。由人类视觉系统的特性知这两个互逆的操作可以在一定程度上互相抵消嵌入信息引起的图像视觉上的变化,提高水印透明性。
5)合成嵌入水印图像
嵌入水印后的直流分量矩阵 IRDE、IBDE、IGDE按照对应位置替换各个子块的直流分量,再对各个子块分别应用反DCT 变换完成各颜色分量的水印嵌入。
最后将三个分量合成为水印图像。

(2)水印的提取

1)预处理
将含有数字水印的载体图像 P 的 3 个颜色通道分离,得到PR、PG、PB 3 个颜色分量; 将原始载体图像 I 的 3 个颜色通道分离,得到IR、IG、IB 3 个颜色分量。
2)对含有水印的图像进行分块 DCT 变换并提取直流分量
对带水印载体图像P使用和水印嵌入时相同直流分量提取方式,得到PRD、PBD、PGD。
3)从直流分量矩阵中提取置乱的水印
提取方法如下:
在这里插入图片描述
将三个分量进行逆Arnold变换后组合成提取出的水印。

二、算法实现

1、代码展示(matlab2018)

%% 初始化
clc;
clear ;
 
figure(1);      %打开窗口
%% 载入数据
I=imread("I.png");
%I=imresize(I,[512,512],'nearest'); 
subplot( 2,2,1) ,imshow(I),title('载体图像');
W=imread("W.png");
%W=imresize(W,[64,64],'nearest');
subplot(2,2,2),imshow(W),title('水印图像');
[row,col,t] = size(W);
 
%% 嵌入水印部分
%分离R,G,B通道
IR=I(:,:,1);
IG=I(:,:,2);
IB=I(:,:,3);
WR=W(:,:,1);
WG=W(:,:,2);
WB=W(:,:,3);
%设置k,不同图片k值不同
k=0.162;
 
%% 使用Arnold变换置乱水印
WRA=arnold(WR,1,1,1);
WRA=double(WRA);
WGA=arnold(WG,1,1,1);
WGA=double(WGA);
WBA=arnold(WB,1,1,1);
WBA=double(WBA);
%%
% 对载体图像进行8*8分块处理,然后对每块分别DCT变化
IRD=blkproc(IR,[8,8],'dct2');
IGD=blkproc(IG,[8,8],'dct2');
IBD=blkproc(IB,[8,8],'dct2');
IRDE=IRD;
IGDE=IGD;
IBDE=IBD;
 
%% 提取直流分量,并向矩阵中嵌入水印
 
for i=0:(row-1)
    for j=0:(col-1)
        x=i*8;
        y=j*8;
        IRDE(x+1,y+1)=IRD(x+1,y+1)+k*WRA(i+1,j+1);
        IBDE(x+1,y+1)=IBD(x+1,y+1)+k*WBA(i+1,j+1);
        IGDE(x+1,y+1)=IGD(x+1,y+1)-k*WGA(i+1,j+1);
    end
end
 
%% 对载体图像进行分块反DCT变换
IR2=blkproc(IRDE,[8,8],'idct2');
IG2=blkproc(IGDE,[8,8],'idct2');
IB2=blkproc(IBDE,[8,8],'idct2');
IR2=uint8(IR2);
IG2=uint8(IG2);
IB2=uint8(IB2);
 
 
%% 合成
I_embed = I;
I_embed(:,:,1) = IR2;
I_embed(:,:,2) = IG2;
I_embed(:,:,3) = IB2;
subplot( 223) ,imshow(I_embed),title('嵌入水印后的载体图像');
 
%% 提取水印
%% 分离通道
P=I_embed;
PR=P(:,:,1);
PG=P(:,:,2);
PB=P(:,:,3);
 
%% 将带水印图像进行DCT变换
PRD=blkproc(PR,[8,8],'dct2');
PGD=blkproc(PG,[8,8],'dct2');
PBD=blkproc(PB,[8,8],'dct2');
WR2=WR;
WB2=WB;
WG2=WG;
%% 提取水印
for i=0:(row-1)
    for j=0:(col-1)
        x=i*8;
        y=j*8;
        WR2(i+1,j+1)=(PRD(x+1,y+1)-IRD(x+1,y+1))/k;
        WB2(i+1,j+1)=(PBD(x+1,y+1)-IBD(x+1,y+1))/k;
        WG2(i+1,j+1)=(IGD(x+1,y+1)-PGD(x+1,y+1))/k;
    end
end
%% 逆arnold 
WR2=uint8(WR2);
WG2=uint8(WG2);
WB2=uint8(WB2);
WR2=rearnold(WR2,1,1,1);
WG2=rearnold(WG2,1,1,1);
WB2=rearnold(WB2,1,1,1);
%% 合成水印
W2=W;
W2(:,:,1)=WR2;
W2(:,:,2)=WG2;
W2(:,:,3)=WB2;
subplot( 224) ,imshow(W2),title('提取出的水印');
imwrite(I_embed,'I_embed.png');
imwrite(W2,'W2.png');
%% arnold变换
function arnoldImg = arnold(img,a,b,n)
[h,w] = size(img);
N=h;
arnoldImg = zeros(h,w);
for i=1:n
    for y=1:h
        for x=1:w
            %防止取余过程中出现错误,先把坐标系变换成从0 到 N-1
            xx=mod((x-1)+b*(y-1),N)+1;
            yy=mod(a*(x-1)+(a*b+1)*(y-1),N)+1;  
            arnoldImg(yy,xx)=img(y,x);              
        end
    end
    img=arnoldImg;
end
arnoldImg = uint8(arnoldImg);
end
 
function img = rearnold(arnoldImg,a,b,n)
[h,w] = size(arnoldImg);
img = zeros(h,w);
N = h;
for i=1:n
    for y=1:h
        for x=1:w           
            xx=mod((a*b+1)*(x-1)-b*(y-1),N)+1;
            yy=mod(-a*(x-1)+(y-1),N)+1  ;      
            img(yy,xx)=arnoldImg(y,x);              
        end
    end
    arnoldImg=img;
end
img = uint8(img);
end

2、实现效果

该算法实现的效果如下:
在这里插入图片描述

3、算法评估

(1)隐蔽性

直观上来看,可以发现嵌入载体后和嵌入载体前图像肉眼无法分辨差异,但是提取出的水印图像和原水印间存在一定失真。
通过计算后可以得到,嵌入载体后图像与嵌入载体前图像峰值信噪比为50.454,互相关系数为0.9919,提取出的水印图像和原图像间互相关系数为0.9944。

(2)容量

从容量上来看,假设该算法载体图像大小为mm,水印图像可为(m/8)(m/8)。

(3)鲁棒性

1)jpeg压缩攻击
压缩后的图像和提取出的水印如下图:
在这里插入图片描述
攻击后提取出的水印与原水印间互相关系数为0.913

2)放大攻击
该攻击对图片先放大2倍再缩小2倍
攻击后提取出的水印图像
在这里插入图片描述
攻击后提取出的水印与原水印间互相关系数为0.9836

3)缩小攻击
该攻击对图片先缩小2倍再放大2倍
攻击后提取出的水印图像
在这里插入图片描述
攻击后提取出的水印与原水印间互相关系数为0.8195

4)裁剪攻击
裁剪掉图片中心的25 %的面积。
攻击后的载体图像和提取出的水印图像如下所示
在这里插入图片描述
攻击后提取出的水印与原水印间互相关系数为0.8547

5)高斯滤波攻击
对载体图像进行高斯滤波
在这里插入图片描述
攻击后提取出的水印与原水印间互相关系数为0.9434

从上述各实验效果可看出该算法具有一定鲁棒性。

三、隐写分析

1、攻击前提

攻击者仅拥有载有水印图片,但是攻击者知道隐写方法为patchwork类及其拓展

2、分析方法

提取图片各分量的灰度图,并对其进行分类,由于正常图片三通道未发生过变换,与载入水印后图片存在一定差异

标签:嵌入,提取,patchwork,数字水印,水印,%%,算法,图像,分量
来源: https://blog.csdn.net/qq_44465615/article/details/116420445