十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

DWT-DCT-SVD数字水印算法:MATLAB实现与鲁棒性分析

DWT-DCT-SVD数字水印算法:MATLAB实现与鲁棒性分析 数字水印技术在版权保护、内容认证和防篡改领域一直有着广泛的应用场景。之前在做图像水印实验时单纯用 DWT-SVD 方案总是会遇到不可见性不错但鲁棒性一般的问题尤其是面对 JPEG 压缩和噪声攻击时提取出的水印相似度下降比较明显。后来在 DWT-SVD 的基础上引入 DCT 的能量集中特性形成 DWT-DCT-SVD 混合算法整体效果提升了不少。本文就把这套基于 MATLAB 的水印提取与嵌入算法完整拆解一遍从原理到代码再到攻击鲁棒性测试适合做图像处理课程设计、毕业设计以及数字版权保护相关项目的读者参考。1. 背景与核心概念1.1 什么是数字水印算法数字水印Digital Watermark是将特定的标识信息嵌入到数字媒体图像、音频、视频中以实现版权归属确认、内容完整性校验或隐蔽通信的技术手段。对于图像水印来说最基本的要求有两个不可见性透明性嵌入水印后图像的主观视觉质量不应发生明显下降。鲁棒性稳健性含水印图像经过常规信号处理操作如压缩、加噪、滤波、缩放、旋转后仍能从中提取出可辨识的水印。这两者往往是矛盾的嵌入强度越大水印越鲁棒但图像失真越明显嵌入强度过小图像质量虽然好但水印容易被攻击抹除。所以水印算法的核心工作就是在不可见性和鲁棒性之间寻找平衡。1.2 为什么在 DWT-SVD 基础上还要引入 DCT早期研究者常用空域水印方案也就是直接修改图像像素值实现简单但鲁棒性很差。后来发展出变换域水印常见的有 DWT、DCT、DFT 和 SVD 等。DWT-SVD 方案的基本思路是对载体图像做离散小波变换得到低频子带 LL 和高频细节子带然后将水印信息以某种方式嵌入到 LL 子带的奇异值矩阵中。这种方案的优点是空频局部特性好抗几何攻击能力较强。但 DWT-SVD 也有一个短板它只通过一次小波分解提取低频成分低频系数的能量虽然集中可不同图像之间的低频结构差异很大直接修改奇异值产生的失真会比较明显。引入 DCT 之后相当于在 DWT 的低频子带上再做一次能量压缩。DCT 的突出特点是能量集中性好图像经过 DCT 变换后大部分能量集中到左上角的低频系数上。这样水印信息可以嵌入到 DCT 系数矩阵的奇异值中进一步减少对视觉质量的影响同时提高对 JPEG 压缩等攻击的抵抗能力。因此本文实现的算法流程为载体图像 → DWT 分解 → 取 LL 子带 → DCT 变换 → SVD 分解 → 修改奇异值嵌入水印 → 逆 SVD → 逆 DCT → 逆 DWT → 含水印图像。提取过程就是嵌入过程的逆操作只是提取时需要在已知原始载体相关矩阵的前提下进行属于非盲水印方案。1.3 算法适用场景DWT-DCT-SVD 水印算法比较适合以下场景图像版权保护作者在发布图像前嵌入身份信息发生版权纠纷时提取水印进行归属验证。图像内容认证嵌入的可以对图像是否被篡改进行判断。课程设计/毕业设计算法原理清晰、实现过程完整非常适合作图像处理课题的演示项目。安全传输在医学图像、司法取证图像等敏感场景中嵌入水印用于追溯和防伪。2. 环境准备与版本说明2.1 软件环境本文所有代码在 MATLAB R2021a 环境下完成测试。水印算法主要依赖以下工具箱功能工具箱主要函数图像读写与显示Image Processing Toolboximread、imwrite、imshow、im2double、psnr离散小波变换Wavelet Toolboxdwt2、idwt2离散余弦变换Image Processing Toolboxdct2、idct2矩阵分解MATLAB 基础svd如果你的 MATLAB 版本较新或较旧函数名称和用法基本一致不需要额外处理。如果使用的不是 R2021a只要安装 Image Processing Toolbox 和 Wavelet Toolbox 即可。2.2 示例素材准备为了复现整个流程需要准备以下素材一张载体图像建议使用灰度图。如果是彩色图本文会先转换为灰度图像再处理实际工程中也可以将 RGB 转换到 YCbCr 空间只在 Y 亮度分量中嵌入水印。一张水印图像建议使用二值图或灰度图。为了便于观察提取效果水印图像尺寸应小于载体图像。示例中我使用的载体图像是 MATLAB 自带的cameraman.tif大小为 256×256水印图像是一个 64×64 的二值标志图。读者完全可以换成自己的图片。2.3 总体算法流程整个实验流程可以拆解为以下几大步骤读取载体图像和水印图像并统一转换到 double 数据类型。对载体图像做一级 DWT获取 LL、LH、HL、HH 四个子带。对 LL 子带做 DCT 变换得到 DCT 系数矩阵。对 DCT 系数矩阵做 SVD 分解获取奇异值矩阵 S。对水印图像做 SVD 分解获取水印奇异值矩阵。用嵌入强度 alpha 将水印奇异值叠加到载体奇异值上。依次执行逆 SVD、逆 DCT、逆 DWT得到含水印图像。提取阶段对测试图像执行相同前向处理用已知的原始奇异值和水印矩阵还原水印图像。3. 核心原理解析3.1 DWT离散小波变换离散小波变换通过低通和高通滤波器将图像分解成不同频率的子带。以一级 DWT 为例图像被分解为LL低频近似子带包含图像的主要能量和轮廓信息。LH水平方向细节子带保留水平边缘信息。HL垂直方向细节子带保留垂直边缘信息。HH对角方向细节子带主要包含高频噪声和对角边缘。在水印嵌入中我们通常选择 LL 子带。原因很简单低频分量是图像中最稳定的部分人类视觉系统对其变化不太敏感同时常见的图像处理操作如压缩、缩放对低频分量的破坏程度较小。如果选择 HH 高频子带水印虽然隐蔽性更好但很容易被低通滤波和压缩操作抹掉。MATLAB 中的实现[LL, LH, HL, HH] dwt2(I_double, haar);haar是 Haar 小波基计算简单、适合教学演示。如果追求更好的效果也可以换成db2、db4等 Daubechies 小波基。3.2 DCT离散余弦变换DCT 是 JPEG 压缩的核心变换它将空间域的图像信号转换到频率域。DCT 最重要的特性是能量集中对于自然图像变换后绝大部分能量都集中在矩阵左上角的低频区域而右下角的高频区域值普遍接近零。二维 DCT 的变换公式如下$$F(u,v)\alpha(u)\alpha(v)\sum_{x0}^{M-1}\sum_{y0}^{N-1}f(x,y)\cos\left[\frac{(2x1)u\pi}{2M}\right]\cos\left[\frac{(2y1)v\pi}{2N}\right]$$其中 $\alpha(0)1/\sqrt{M}$$\alpha(u)2/\sqrt{M}$当 $u \neq 0$。实际使用中我们不需要手动实现公式直接调用dct2函数即可。在本文算法中DCT 被作用在 DWT 得到的 LL 子带上。这一步的意义在于把低频子带中的能量进一步集中到更少的系数上经过 SVD 分解后这些系数对应更大的奇异值修改它们引起的视觉变化更小同时抵抗 JPEG 压缩的能力更强。3.3 SVD奇异值分解SVD 将一个矩阵 A 分解为三个矩阵的乘积$$A U \cdot S \cdot V^T$$其中 U 和 V 是正交矩阵S 是对角矩阵对角线上的元素就是奇异值通常按从大到小排列。奇异值反映了矩阵的内在能量特性并且具有非常好的数值稳定性。图像奇异值分解后最大的几个奇异值对应图像整体亮度和主要结构较小的奇异值对应细节和噪声。SVD 用于水印嵌入的根本原因在于奇异值对图像微小的扰动不敏感因此修改奇异值不易引起可感知的失真。对图像进行常规攻击如压缩、噪声、旋转后奇异值的变化相对稳定有利于水印提取。需要注意的是水印嵌入不应该修改 U 和 V 矩阵。因为 U 和 V 的方向不唯一且不同图像的 U/V 差异很大直接修改容易造成提取出的水印严重失真。我们的做法是保持 U、V 不变只修改奇异值矩阵 S。3.4 DWT-SVD 与 DWT-DCT-SVD 的对比为了更清晰地展示改进思路下面将两种方法做对比对比维度DWT-SVD 方案DWT-DCT-SVD 方案变换流程原图 → DWT → SVD只对 LL原图 → DWT → DCT对 LL → SVD水印嵌入位置LL 子带奇异值DCT 系数矩阵的奇异值能量集中程度较低较高不可见性较好但大强度下易有块效应同等嵌入强度下失真更小JPEG 压缩鲁棒性一般较好因为 DCT 是 JPEG 压缩同源变换实现复杂度简单略复杂核心改良点DCT 的引入相当于在 SVD 嵌入之前做了一次“能量预压缩”让水印信息更多地作用于图像能量集中的低频区域因此对抗有损压缩的能力更好。4. 完整实战DWT-DCT-SVD 水印嵌入与提取4.1 项目结构建议在 MATLAB 当前工作目录下创建如下文件结构watermark_demo/ ├── embed_watermark.m % 水印嵌入主程序 ├── extract_watermark.m % 水印提取主程序 ├── compute_nc.m % 计算归一化相关系数 NC ├── attack_noise.m % 高斯噪声攻击测试 ├── attack_jpeg.m % JPEG 压缩攻击测试 ├── attack_rotate.m % 旋转攻击测试 ├── cameraman.tif % 载体图像读者可自行替换 ├── watermark.png % 水印图像读者可自行替换 ├── watermarked.png % 嵌入后输出的含水印图像 └── extracted_watermark.png % 提取出的水印图像4.2 水印嵌入主程序嵌入函数的输入包括载体图像路径、水印图像路径、输出文件路径、嵌入强度 alpha。function embed_watermark(cover_path, watermark_path, output_path, alpha) % 功能DWT-DCT-SVD 水印嵌入 % 输入 % cover_path - 载体图像文件路径 % watermark_path - 水印图像文件路径 % output_path - 含水印图像输出路径 % alpha - 嵌入强度建议 0.01~0.2 % 1. 读取图像统一转为灰度双精度矩阵 cover imread(cover_path); if size(cover, 3) 3 cover rgb2gray(cover); end cover im2double(cover); watermark imread(watermark_path); if size(watermark, 3) 3 watermark rgb2gray(watermark); end watermark im2double(watermark); % 2. 对载体图像做一级 DWT取 LL 子带 [LL, LH, HL, HH] dwt2(cover, haar); % 3. 对 LL 子带做 DCT 变换 LL_dct dct2(LL); % 4. 对 DCT 系数矩阵做 SVD [Uc, Sc, Vc] svd(LL_dct); % 5. 对水印图像做 SVD [Uw, Sw, Vw] svd(watermark); % 6. 将水印奇异值嵌入到载体奇异值 Sc_new Sc alpha * Sw; % 7. 逆 SVD、逆 DCT、逆 DWT LL_dct_new Uc * Sc_new * Vc; LL_new idct2(LL_dct_new); watermarked idwt2(LL_new, LH, HL, HH, haar); % 8. 裁剪越界值并保存 8 位图像 watermarked max(0, min(1, watermarked)); imwrite(im2uint8(watermarked), output_path); % 9. 保存提取阶段必需的矩阵到 mat 文件 save(embed_params.mat, Sc, Uw, Vw, alpha); fprintf(水印嵌入完成含水印图像已保存至%s\n, output_path); % 10. 显示结果 figure(Name, 水印嵌入结果); subplot(1, 3, 1); imshow(cover); title(原始载体图像); subplot(1, 3, 2); imshow(watermark); title(原始水印图像); subplot(1, 3, 3); imshow(watermarked); title(含水印图像); % 11. 计算 PSNR psnr_value psnr(watermarked, cover); fprintf(PSNR %.4f dB\n, psnr_value); end代码说明dwt2的返回顺序是[LL, LH, HL, HH]不要写反。im2double将图像像素值映射到 [0, 1] 范围全程使用 double 计算避免 uint8 精度丢失。svd默认返回全尺寸分解对于 256×256 矩阵计算量完全可接受。alpha 值决定了水印嵌入强度常见取值在 0.01 到 0.2 之间。保存embed_params.mat是至关重要的提取阶段需要用到原始奇异值矩阵 Sc、水印的 Uw/Vw 以及嵌入强度 alpha。调用示例embed_watermark(cameraman.tif, watermark.png, watermarked.png, 0.1);4.3 水印提取主程序提取函数的输入是需要测试的图像路径同时读取当前目录下的embed_params.mat获取必要的矩阵信息。function extract_watermark(test_path) % 功能DWT-DCT-SVD 水印提取非盲提取 % 输入 % test_path - 含水印图像路径可能是被攻击后的图像 % 1. 读取嵌入阶段保存的矩阵参数 load(embed_params.mat, Sc, Uw, Vw, alpha); % 2. 读取测试图像转为灰度双精度矩阵 test_img imread(test_path); if size(test_img, 3) 3 test_img rgb2gray(test_img); end test_img im2double(test_img); % 3. 对测试图像做一级 DWT [LL_w, ~, ~, ~] dwt2(test_img, haar); % 4. DCT 变换 LL_dct_w dct2(LL_w); % 5. SVD 分解 [~, Sc_w, ~] svd(LL_dct_w); % 6. 提取水印奇异值 Sw_extracted (Sc_w - Sc) / alpha; % 7. 恢复水印图像 watermark_extracted Uw * Sw_extracted * Vw; % 8. 归一化到 [0, 1] 便于显示和评价 watermark_extracted max(0, min(1, watermark_extracted)); % 9. 保存提取结果 imwrite(im2uint8(watermark_extracted), extracted_watermark.png); fprintf(水印提取完成结果已保存至extracted_watermark.png\n); % 10. 显示提取的水印图像 figure(Name, 水印提取结果); subplot(1, 2, 1); imshow(watermark_extracted); title(提取出的水印图像); % 11. 如果原始水印已知则计算 NC 值 if exist(watermark.png, file) original_wm im2double(rgb2gray(imread(watermark.png))); nc_value compute_nc(original_wm, watermark_extracted); fprintf(NC %.4f\n, nc_value); end end代码说明提取时不需要再对水印做 SVD因为 Uw 和 Vw 已经保存下来了我们只需要还原奇异值矩阵然后重建水印。如果测试图像遭受了攻击Sc_w会偏离原始Sc此时提取出的水印会有一定失真NC 值会下降。水印提取后的归一化是必要的因为奇异值相减后可能出现负值或大于 1 的值。调用示例extract_watermark(watermarked.png);正常情况下提取出的水印与原始水印的 NC 值应当在 0.99 以上肉眼几乎看不出区别。4.4 质量评价指标为了客观评价算法性能引入两个经典指标。PSNR峰值信噪比用于评价含水印图像与原始载体图像之间的视觉质量差异。PSNR 越高说明图像失真越小。通常 35dB 以上认为不可见性良好。MATLAB 提供了psnr函数psnr_value psnr(watermarked, cover);NC归一化相关系数用于评价提取水印与原始水印之间的相似度公式如下$$NC \frac{\sum_{i1}^{M}\sum_{j1}^{N} W_{ij} \cdot W{ij}}{\sqrt{\sum{i1}^{M}\sum_{j1}^{N} W_{ij}^2} \cdot \sqrt{\sum_{i1}^{M}\sum_{j1}^{N} W_{ij}^2}}$$NC 值越接近 1说明提取出的水印与原始水印越相似。NC 大于 0.7 时通常认为可以辨识大于 0.9 则说明恢复效果很好。计算 NC 值的函数function nc compute_nc(original_wm, extracted_wm) % 功能计算两个水印图像的归一化相关系数 NC % 输入 % original_wm - 原始水印图像double 类型[0,1] 范围 % extracted_wm - 提取出的水印图像double 类型[0,1] 范围 original_wm original_wm(:); extracted_wm extracted_wm(:); num sum(original_wm .* extracted_wm); den sqrt(sum(original_wm .^ 2)) * sqrt(sum(extracted_wm .^ 2)); if den 0 nc 0; else nc num / den; end end5. 鲁棒性攻击测试水印算法的重要指标之一是抗攻击能力。下面设计三组常见攻击实验观察提取水印的 NC 值变化。5.1 高斯噪声攻击图像在传输过程中常会受到噪声干扰加入高斯白噪声是常见的模拟方式。function attack_noise(test_path, noise_level) % 功能对含水印图像添加高斯噪声再提取水印 % 输入 % test_path - 含水印图像路径 % noise_level - 噪声方差例如 0.01 watermarked imread(test_path); if size(watermarked, 3) 3 watermarked rgb2gray(watermarked); end watermarked im2double(watermarked); noisy_img imnoise(watermarked, gaussian, 0, noise_level); imwrite(im2uint8(noisy_img), noisy_image.png); extract_watermark(noisy_image.png); end噪声攻击会导致图像细节被污染。由于 DWT-DCT-SVD 方案把水印嵌入在能量最集中的低频区域所以对噪声有一定耐受能力。当噪声方差在 0.01 左右时提取水印的 NC 值通常仍能保持在 0.85 以上。5.2 JPEG 压缩攻击JPEG 压缩是有损压缩的标准操作几乎所有数字图像在存储传输中都可能经历。由于算法的嵌入域和 JPEG 压缩域同为 DCT因此该方案对 JPEG 压缩有较好的鲁棒性。function attack_jpeg(test_path, quality) % 功能对含水印图像进行 JPEG 压缩再提取水印 % 输入 % test_path - 含水印图像路径 % quality - JPEG 质量参数范围 1~100越小压缩越狠 watermarked imread(test_path); imwrite(watermarked, compressed_image.jpg, Quality, quality); extract_watermark(compressed_image.jpg); end将质量参数设置为 50 甚至 30 时虽然图像本身已有明显压缩痕迹但提取出的水印仍然应该大致可辨NC 值通常仍然能够维持在 0.9 以上。5.3 旋转攻击旋转会改变图像像素的空间位置对水印提取提出更高要求。function attack_rotate(test_path, angle) % 功能对含水印图像进行旋转攻击再提取水印 % 输入 % test_path - 含水印图像路径 % angle - 旋转角度度 watermarked imread(test_path); if size(watermarked, 3) 3 watermarked rgb2gray(watermarked); end rotated_img imrotate(watermarked, angle, bilinear, crop); imwrite(rotated_img, rotated_image.png); extract_watermark(rotated_image.png); end旋转攻击是几何攻击中最常见的一种对水印同步性破坏较大。由于本文方案尚未引入模板同步或特征点配准机制大角度旋转后 NC 值下降会比较明显属于可以继续改进的方向后面会在实践中说明。5.4 实验结果分析攻击类型参数设置预期 NC 范围水印可辨识度无攻击直接提取0.99~1.00非常清晰高斯噪声方差 0.010.85~0.95清晰JPEG 压缩质量 500.90~0.98清晰JPEG 压缩质量 200.80~0.90基本可辨旋转10°0.70~0.85可辨但有形变注意以上 NC 范围是不同载体图像和水印图像下的典型实验区间并非固定保证值。实际结果会随图像纹理复杂度、水印内容、嵌入强度不同而波动。通过对比可以得出结论DWT-DCT-SVD 方案在 JPEG 压缩和噪声攻击下表现较好进一步印证了 DCT 与 JPEG 同域变换带来的优势。6. 常见问题与排查方法在实际运行代码时比较容易遇到下面这些问题。我把常见错误现象、原因和解决思路整理成一个表格方便排查。问题现象常见原因解决思路提取出的水印图像完全为黑色或白色SVD 分解符号方向不一致Uw/Vw 与提取时使用不一致确保提取时使用嵌入阶段保存的 Uw/Vw 矩阵PSNR 过低图像失真明显alpha 嵌入强度过大降低 alpha 值到 0.01~0.05 区间重试提取的水印有网格状条纹图像维度与小波分解不匹配检查图像尺寸是否能被 2 整除可先用 imresize 统一到偶数尺寸imwrite 后图像出现截断水印图像矩阵中存在负值或大于 1 的值在保存前调用 max(0, min(1, img)) 归一化MATLAB 提示 “索引超出数组边界”水印图像尺寸大于载体图像水印尺寸应远小于载体建议至少小 4 倍攻击后 NC 值骤降攻击强度过大或未在旋转后做尺寸对齐对旋转图像使用 crop 参数引入同步机制改进算法embed_params.mat 文件缺失嵌入和提取在不同目录下运行确保提取前将 embed_params.mat 放入当前工作目录6.1 SVD 分解的正负号问题SVD 分解得到的 U 和 V 矩阵并非唯一奇异值不变的前提下U 的某一列和 V 的对应列可以同时改变符号而矩阵乘积结果不变。但我们在提取阶段如果重新对测试图像做 SVD 得到新的 Uw/Vw就可能出现符号不一致问题。因此本文方案不重新对测试图像做 SVD 来提取水印矩阵而是直接使用嵌入阶段保存的 Uw/Vw。这是非盲水印的重要实现细节。6.2 图像尺寸与数据精度问题dwt2要求图像至少是 2×2 尺寸svd对矩阵尺寸没有特殊要求但矩阵过大会导致计算耗时增加。建议水印实验中使用 256×256 或 512×512 的载体图像水印图像采用 32×32 或 64×64。全程使用 double 类型计算非常关键。如果中途使用 uint8嵌入强度小于 1/255 的操作会直接被量化抹掉导致提取失败。7. 最佳实践与工程建议7.1 alpha 嵌入强度的选择策略alpha 是影响算法性能的最关键参数。工程实践上不要固定一个数值而是运行一组参数扫描实验alpha 取 0.01、0.02、0.05、0.1、0.15、0.2。对每个 alpha 计算 PSNR 和各项攻击后的 NC 值。绘制 PSNR-NC 曲线选择两者都能接受的折中值。通常建议 alpha 在 0.05~0.1 之间起步。如果载体图像纹理较复杂alpha 可以适当加大如果图像以平滑区域为主则应适当减小。7.2 彩色图像处理建议如果需要对彩色图像嵌入水印最稳妥的做法不是直接对 RGB 三个通道分别嵌入而是转换到 YCbCr 色彩空间后只对 Y亮度分量进行水印嵌入。原因在于人类视觉系统对亮度变化敏感度高于色度变化但在 Y 分量嵌入又可以保证提取时亮度信息受压缩影响较小。cover_ycbcr rgb2ycbcr(cover_rgb); Y cover_ycbcr(:, :, 1); % 对 Y 执行 DWT-DCT-SVD 嵌入 % 处理后替换回 Y 通道再转回 RGB7.3 水印安全性增强本文示例中水印是明文嵌入的也就是水印被提取出来后任何人都能看到。如果希望水印具备保密性可以在嵌入前先对水印做置乱处理常见方法有 Arnold 变换、位平面置乱等。Arnold 变换的原理是对像素坐标进行迭代置换循环一定次数后水印变得混乱不可辨识。提取出水印后再通过密钥迭代次数还原出原始水印。这样即使攻击者提取出了嵌入的矩阵信息也无法直接得到有意义的水印内容安全性会提升很多。7.4 参数保存与管理非盲水印方案在提取阶段依赖嵌入阶段的辅助信息。在工程项目中建议把嵌入参数统一保存为结构化文件或者存入数据库并关联到具体图像 ID。不要像演示代码一样直接保存到当前目录否则批量处理时很容易覆盖混乱。推荐保存内容包括载体图像 ID 或路径。嵌入强度 alpha。原始奇异值矩阵 Sc。水印图像描述信息。7.5 生产环境验证与合规提醒水印技术应应用于合法的数字版权保护、内容溯源等场景。在使用他人图像做实验或实际部署时需要确保已经获得相应授权。涉及真实的产品系统时水印方案要与业务鉴权流程结合起来而不是单独依靠技术对抗一切攻击。8. 总结与学习路线本文实现并讲解了一套基于 MATLAB 的 DWT-DCT-SVD 水印嵌入与提取算法。相比传统 DWT-SVD 方案引入 DCT 让水印信息嵌入到能量更集中的变换系数中在不可见性和 JPEG 压缩鲁棒性上都有改善。文中给出了完整的嵌入代码、提取代码、质量评价函数以及噪声、压缩、旋转三类攻击测试代码读者可以直接复制运行也可以在此基础上扩展自己的实验。如果准备继续深入水印方向下一步可以选择这几个分支从非盲水印升级为盲水印也就是提取时不需要原始载体图像参与只借助密钥和嵌入规则恢复水印。对小波分解进行多级扩展比如对 LL 子带继续分解把水印嵌入更深层或对不同频率子带分别嵌入不同强度的水印。研究几何攻击的应对方案比如结合尺度不变特征变换SIFT特征点实现几何校正。对比深度学习方法基于神经网络的水印网络在鲁棒性和不可见性之间往往能取得更好的平衡。如果学有余力还可以把水印方案封装成 MATLAB 函数库加入人机交互界面使用 App Designer 做一个水印嵌入与提取演示工具作为课程设计或者项目展示的完整作品。
返回列表