1. 引言
随着网络技术和媒体记录设备的发展,越来越多的多媒体信息通过网络和存储设备发布和分享。未经授权的个人或组织可以方便地复制、修改或转发这些信息,这就可能造成侵犯版权问题,迫切需要一种方便快捷的可行技术来保护数字媒体的版权,从而为数字媒体生产者维持健康的生产环境。数字水印是一种将版权信息隐藏在数字媒体中,并可在需要时提取的版权保护技术,从而检测和认证数字媒体的版权是否合法。明水印会影响图像本身的内容,并且其显著的存在性使其易被恶意篡改,透明的隐水印可以对抗版权侵犯并保持媒体的内容完整性。早期的空域水印技术如最低有效位修改(LSB) [1] 可以简单有效地在图像中隐藏数据,但对JPEG压缩、滤波、加噪等图像处理敏感;一些基于块的方法 [2] 对JPEG压缩和滤波有鲁棒性,但不能实现盲提取。变换域水印技术在离散傅立叶变换(DFT) [3]、离散余弦变换(DCT) [4]、离散小波变换(DWT) [5] [6] 等变换域隐藏水印,对JPEG压缩及其他信号处理操作有较好的鲁棒性,然而多数变换域水印技术是基于分块和伪随机置乱的,仍然对几何攻击和位置变化敏感。Tsai等 [7] 提出了基于特征的水印方案,可以在多个无交叠的区域嵌入100位的水印从而增强鲁棒性。Kang等 [8] 提出的DWT-DFT复合水印方案对仿射变换和JPEG压缩均有较好鲁棒性,然而其60位的水印容量相对较低。近年来还有一些研究者提出了基于深度学习的数字水印方法 [9],对信号处理操作和几何变换攻击都有较好鲁棒性,但只能在有限大小的图像时进行水印的嵌入和提取。随着图像采集技术的发展,图像的尺寸和分辨率正变得越来越大,一个实用的水印方法应该可以应用到高分辨率图像上。微信小程序无须安装,即开即用,用完即走,最大程序减少在手机上所占用的资源,而且微信用户粘性高,对一些偶尔使用的功能,越来越多的用户选择微信小程序来替代专用的APP,这对资源有限的手机等移动终端而言更为重要。
本文首先基于2D-DWT实现了一个高分辨率图像数字水印算法,其次将该程序制作成动态链接库,以便于基于ASPNET的WebService调用,微信小程序通过WebService调用水印嵌入和水印提取、验证等程序,最终以微信小程序为入口,实现在线的水印嵌入、提取和验证。
本文组织如下,第1节介绍系统总体设计,第2节介绍图像水印嵌入和提取的算法流程。第3节介绍微信小程序的设计与实现;第4节是实验结果及系统展示;最后是总结和展望。
2. 系统总体结构
系统总体结构如图1所示,采用客户端/服务端(C/S)结构,微信小程序搭载在微信APP上,运行在客户端,提供用户接口,用户可以在本机上选择图像和水印文件,并输入密码并将图像、水印和密码通过网络发送到服务端Web Service搭载于Windows系统的IIS上,基于.NET技术创建,负责与小程序的通信,并调用服务器上的动态链接库执行水印嵌入、提取和验证等操作;动态链接库基于C++和Opencv库实现了图像水印的嵌入、提取和验证等核心功能,其中的图像处理函数调用了Opencv库中API,其中运算复杂度比较高的小波变换和逆变换用CUDA (Compute Unified Device Architecture) SDK和GPU进行B并行化加速。

Figure 1. The overall structure of the system
图1. 系统总体结构
3. 基于2D-DWT的高分辨率图像水印算法
3.1. 基于2D-DWT的水印嵌入算法流程
基于2D-DWT的图像数字水印嵌入算法的流程图如图2(a)所示。为了提高水印的鲁棒性,水印嵌入于二级小波变换的最后一级的近似系数LL中,二级小波变换后的LL系数长和宽均为图像的1/4,假如LL中每个系数隐藏一个位的水印,能隐藏的信息量不超过最后一级LL系数的数量。因此隐藏水印的第一步是确定所隐藏水印的大小,对水印尺寸进行归一化,保证水印位数小于LL系数数量。确定嵌入水印的边长a后,对原始二值水印图像进行缩放,使之长边为a,并将水印置于左上角填0扩充为边长为a的正方形,即如果宽大于高,则在下方填0,否则在右侧填0,如果原来就是正方形图像,则缩放即可。在嵌入和提取水印时,需要用户提供一个6位的数字密钥,以便对水印以及嵌入水印的位置进行加密,其中前两位记为key1,用作对水印进行Arnold变换的变换次数;后四位记为key2,用作对嵌入位置加密时的伪随机置乱的种子数,以提高水印的安全性。Arnold变换的计算公式如式(1):
(1)
其中
为水印中某一位的原始坐标,
为变换后该位的坐标,n = key1为变换次数。mod a表示用a取余,因为坐标超出宽和高的范围将产生越界异常。
为了避免色差变化对图像造成视觉上的失真,本文将水印隐藏于彩色图像HSV空间的V通道。首先将图像转换到HSV空间,然后对V通道执行二级2D-DWT。本文基于文献 [10] 的方法对小波变换进行GPU加速,加速后GPU版的2D-DWT比CPU版的2D-DWT快两个数量级,从而可以保证水印嵌入和提取的实时性,提升用户体验。首先将以行优先顺序将LL2转换为一维向量,然后以key2为种子对一维向量的下标进行伪随机置乱,提取置乱后的下标序列的前N个元素(N为水印的位数),以式(2)方式改写这N个细节系数。
(2)
(a)
(b)
Figure 2. Flow chart of watermark embedding, extraction and verification algorithm based on 2D-DWT
图2. 基于2D-DWT的水印嵌入、提取及验证算法流程图
其中round(∙)表示四舍五入取整,q为质量因子,q越大水印越稳健,但水印透明性下降,q越小透明性越好,但可能在图像经历JPEG压缩等信号处理后难以提取到高质量的水印,本文中取经验值q = 50,以在水印的稳健性和透明性之间取得良好折衷。v和v'分别表示改写前和改写后的细节系数,bit指水印中的某一位。这样,改写完N个指定下标的细节系数后,执行二级2D-DWT逆变换,得到含水印的V通道,最后将V通道与原来HS通道合并转换回RGB空间即得到了含水印的图像。
3.2. 基于2D-DWT的水印提取及验证算法流程
基于2D-DWT的图像数字水印提取及验证算法的流程图如图2(b)所示。首先与2.1节相同的方式确定水印的边长,并用同样方式将图像转换到HSV空间,将V通道用同样的二级2D-DWT进行小波变换,在二级近似系数LL2中提取水印。提取水印时,用户必须输入与嵌入水印相同的密钥key,记key的前2位为key1,后四位为key2。用key2对以行优先顺序排列的LL2下标进行伪随机置乱,从前N个下标对应的系数中提取水印值,如式(3)
(3)
(4)
将提取到的N位水印按行序排列成正方形,执行如式(5)所示的反向Arnold变换得到置乱前的正方形水印。
(5)
验证水印需要将原始水印缩放到同一尺度,然后与提取的水印在左上角对齐,在两者的交叠区域计算相似度,计算公式如式(6)。
(6)
其中N为交叠区域的总像素个数,wi和
为原水印和提取到的水印对应位的值。用阈值th来验证两水印是否匹配。
4. 图像数字水印微信小程序的设计与实现
4.1. 制作动态链接库
因为水印的嵌入和提取涉及运算复杂的小波变换,无法直接实现单机版的微信小程序,因此本文将这些复杂运算程序部署在服务器上,在网络上开放API接口供小程序调用。我们把水印的嵌入、提取、以及验证封装成三个程序模块,并把这三个模块制作成动态链接库,供服务器的WebService调用。其中水印的嵌入程序接受三个参数,包括图像文件,水印文件,以及用户设置的6位数字密钥,返回整数值1表明嵌入操作成功,含水印的图像将替换原来的图像文件,返回其他整数表示水印嵌入失败;水印的提取则接受两个参数,含水印图像以及6位数字密钥,返回整数1表示提取成功,提取的水印将替换原来的含水印图像文件;水印验证模块接受两个参数,即原水印和提取的水印,将原水印归一化到长边与提取的水印相同,左上角对齐后对交叠部分按式(6)计算相似度,返回相似度计算结果。所有程序用C++实现,并调用了OpenCV库和CUDA库。
4.2. 创建Web Service
本文基于微软的.NET技术创建Web Service,编程语言为C#,Web Service可以把应用的API接口发布在网络上,运行在其他主机上的程序可以通过网络访问这些API接口,跨域调用服务器上开放的应用程序。Web Service监听网络上的调用请求,并把运行结果返回给请求方。
Web Service首先导入上一步生成的动态链接库,并在导入语句中定义水印的嵌入、提取、以及验证三个模块的入口点,这样Web Service中的WebMethod就可以调用这些模块。根据微信小程序的功能需要,Web Service中定义了4个WebMethod,除了水印的嵌入、提取、以及验证三个接口外,另外还定义了一个接收微信小程序上传图像的接口,以便服务器接收图像和水印。
最后Web Service被部署到Windows自带的Internet Information Services (IIS)上,微信小程序通过服务器的地址或域名来访问Web Service提供的应用服务。
4.3. 图像数字水印微信小程序开发
微信小程序用微信开发者工具进行开发,本文在小程序中设计了两个页面:一个提供水印嵌入的页面和一个提供水印提取及验证的页面,两个页面通过底部的标签实现页面切换。在框架全局文件的公共设置app.json文件中对两个页面的路径,标题栏背景色、标题、文字颜色等窗口表现,底部标签的显示的文字以及链接页面的路径,网络超时参数设置等进行配置。每个页面包含文件名相同、但扩展名不同的4个文件,分别是js页面逻辑、json页面配置、wxml页面结构、wxss页面样式表。wxml定义了页面的布局结构,外观设计通过此文件实现,js实现业务逻辑。
本文设计的水印嵌入的界面如图4所示,wxml文件中首先是view控件,class属性设置为labels,labels定义在wxss文件中,这个view控件内包含文字“选择原始图片”,下面是一个包含了两个image子控件的view控件,class属性设置为set-background,在wxss文件中定义了高度、对齐方式、背景色等属性。两个image子控件始终有一个处于隐藏状态,其中一个显示十字丝印图标,另一个用于显示选择的图像,都用bindtap绑定了chooseOriginImage函数,这样点击图片就可以调用wx.chooseImage在手机相册中选择图像并显示在该view内。下面两个view跟上面两个类似,用于选择和显示水印图像,同时含水印图像也显示在下面的view中。下面又是一个class为labels的view,这个view包含一个用于显示提示文字view子控件和一个用于输入密码的input子控件,input子控件的type设置为“number”,password设置为“true”,这样密码只能输入数字类型的字符,输入的密码自动隐藏以提高安全性。最底下是一个button控件,绑定了函数onClickButton。页面右上角有一个固定大小的view控件,class定义为add_icon,因两个页面均定义了这个刷新的view, add_icon定义于顶层app.wxss文件中,绑定了refresh函数,view内部包含一个image子控件用于显示刷新图标。本文设计的水印提取和验证的界面如图5所示,界面设计基本与图4相同,区别是图5底部包含两个按钮,先提取水印,由用户决定是否进行验证。
js文件调用到的几个微信小程序接口方法包括:
1) wx.chooseImage:在手机相册中选择图像,参数包括图像数量,本文设置为1,sizeType设置为original不压缩,sourceType设置为album从相册选择,选择完成后将显示在相应的image控件中,并且调用wx.uploadFile接口上传到服务器。
2) wx.uploadFile:上传手机中的本地文件到服务器,参数url指定WebService的域名以及获取上传图像对应的方法名,形如https://域名/Service.asmx/Get_photo,其中Service.asmx是WebService的默认文件,Get_photo为对应的WebMethod名称;参数filePath指定本地文件路径;参数name指定上传文件的键,服务端根据这个键来获取文件;参数header里指定“content-Type”为“multipart/form-data”。文件上传成功返回该文件在服务器上的路径,因WebService以XML格式返回数据,调用SAX (simple API for XML)库函数从返回的XML文件中解析出路径信息。
3) wx.request:在进行水印嵌入、提取或验证时均需要用到此接口。参数url指定WebService的域名及要调用的WebMethod, 形式同wx.uploadFile的url参数;水印嵌入、提取或验证对应的WebMethod均需要传入参数,参数以键值对的方式在wx.request的data参数中指定,其中的键必须与服务端WebMethod的形式参数同名;method参数设置为“POST”;参数header里指定“content-Type”为“application/x-www-form-urlencoded”;返回值由SAX库解析。对于水印嵌入和提取,返回值为整数1时执行成功,执行成功后将调用wx.downloadFile从服务器下载含水印的图像或提取的水印;
4) wx.downloadFile:参数url形如https://域名/二级目录/文件名,下载成功后临时文件路径在res.tempFilePath中,可调用wx.saveImageToPhotosAlbum将图像文件保存至相册;
5) wx.saveImageToPhotosAlbum:参数filePath指定待保存至相册的临时文件路径,调用成功后该图像文件可在相册中找到。
5. 实验结果
5.1. 基于2D-DWT的图像数字水印算法性能评估
本文用100张高分辨率图像和两个自定义水印对基于2D-DWT的图像数字水印算法性能进行了测试,图像的大小从15,451,537到60,164,016不等。用峰值信噪比(PSNR)来评价含水印图像的质量,PSNR用来衡量嵌入水印后的图像与原始图像相比较质量受影响程度,PSNR越大则质量越好,PSNR较低则表明添加水印对图像画质有较大影响;用归一化相关系数(NC)来评价提取的水印质量,该系数用于衡量提取的水印与原始水印的一致性,为[0, 1]间的实数,NC越接近1两者一致性越高(NC = 1时两者完全相同),NC越接近0则两者差别越大。
(7)
(8)
其中C和S表示载体图像和含水印图像;W和W'归一化的原始水印及提取到的水印。
表示内积运算。M和N分别为图像和水印的像素数量。程序用C++基于OPENCV库实现,小波变换和逆变换用GPU用CUDA进行了并行化加速。在测试图像集上的统计结果如表1所示。

Table 1. Performance evaluation results of image digital watermarking algorithm based on 2D-DWT
表1. 基于2D-DWT的图像数字水印算法性能评估结果
该算法对一些常见的信号处理表现出一定的鲁棒性,表2为测试图像集上鲁棒性统计结果,以提取到的水印的NC来表征。图3为可视化结果展示。

Table 2. Robustness test results of image digital watermarking algorithm based on 2D-DWT
表2. 基于2D-DWT的图像数字水印算法鲁棒性测试结果

Figure 3. Visualization results of high-resolution image embedding and watermark extraction
图3. 高分辨率图像嵌入和提取水印可视化结果展示
5.2. 微信小程序结果展示
用微信扫一扫选择微信小程序码图片,或在微信小程序中搜索“图像数字隐水印添加与验证”即可打开小程序并使用。按图4(a)所示步骤选择图像和水印,输入密码,点击底部按钮,则如图4(b)原图像展示于界面上方,水印展示于下方,水印隐藏完成后含水印图像将替换原来的水印图像展示于界面下方(如图4(c)),以便用户比较添加水印前后的图像,点击底部【保存含水印图像】按钮将含水印图像保存到相册后界面清空返回图4(a)所示的初始状态。
(a) 水印添加操作步骤
(b) 等待水印嵌入
(c) 嵌入完成
Figure 4. Screenshot of the watermark adding interface
图4. 水印添加界面截图
点击页面右下方的【水印验证】标签,将进入水印提取及验证标签页,如图5所示,先在本机中选择含水印图像,然后在密码输入框输入与嵌入水印时一致的6位数字密码,再点击界面左下方的【提取水印】按钮即可从含水印图像中提取隐藏的水印图像。水印提取完成后会弹出如图5(b)所示的对话框,点击【确定】按钮将下载提取到的水印图像,并替换原含水印图像展示于界面上半部分,如图5(c)所示。
水印验证的功能与水印提取的功能在同一个标签页内完成,水印提取完成后可与原水印图像进行比对验证,验证过程很简单,点击页面下半部分的十字丝印图标在本机上选择原始的水印图像,选择完成后的界面如图5(d)所示。点击右下方的【验证水印】按钮,服务端进行两水印图像的相似度比较,比较的结果将弹出对话框显示。验证完成后界面被重置,回到初始状态,在验证和提取过程中,也可以随时点击右上角的重置按钮,重置界面回到初始状态。
(a) 提取水印操作步骤
(b) 水印提取成功提示
(c) 水印验证操作示意
(d) 水印验证界面
Figure 5. Screenshot of the watermark extraction and verification interface
图5. 水印提取及验证界面截图
6. 结束语
本文基于2D-DWT实现了高分辨率图像的数字隐水印算法,包括水印的嵌入、提取和验证等功能,通过Web Service技术将实现的程序API接口发布在网络服务器上,并设计了微信小程序来调用这些程序功能。基于CUDA对算法中的最复杂的2D-DWT进行了GPU并行运算加速,使程序运行过程中实现实时响应,从而提高用户体验。基于2D-DWT的图像数字水印算法虽然对JPEG压缩、加噪、滤波等信号处理有一定的鲁棒性,但在旋转、缩放、平移等几何变换攻击下不具备鲁棒性,因此,我们未来的工作是基于深度学习实现对信号处理操作和几何变换攻击均具备较好鲁棒性的算法,并把实现的算法部署到服务器供微信小程序调用。
基金项目
浙江省自然科学基金资助项目(LY20F020002),浙江省大学生科技创新活动计划暨新苗人才计划(2019R408052),浙江省大学生科技创新活动计划暨新苗人才计划(2020R408016)。
NOTES
*通讯作者。