Matlab小波域数字水印嵌入与提取实战:原理、实现与鲁棒性分析

发布时间:2026/9/16 17:37:15

Matlab小波域数字水印嵌入与提取实战:原理、实现与鲁棒性分析 简介这份资源基于小波变换实现水印嵌入与提取的Matlab仿真面向数字水印、信息安全及图像处理方向的初学者和研究人员适合在Matlab 2022A环境中学习与复现。资源共8个文件包含4个m程序文件主程序、小波水印嵌入、提取及攻击测试、1个tif载体图像、1个jpg水印图像、1个mp4操作步骤视频和1个参考文献压缩包整体约5.79MB。已有138人学习下载。仿真采用Haar、Daubechies等小波函数对载体图像进行多级分解选择低频或高频系数嵌入水印并通过阈值比较或编码方式从系数中恢复水印比特流同时提供多种水印干扰方式便于对比提取效果。包内附中文注释、参考文献和Windows Media Player可播放的操作录屏按步骤即可完成从路径设置到运行评估的完整流程适合课程设计、毕业设计或论文复现参考。1. 为什么小波域水印比空域水印更值得复现直接把水印叠加在像素上的空域算法遇到压缩、滤波或几何攻击后残存率很低。基于小波变换的水印嵌入和提取算法把载体图像拆成一组不同分辨率的子带把水印嵌进那些人眼不敏感、但统计上又稳定的系数里。这样做的收益很直接对JPEG压缩和低通滤波的抵抗力明显好于空域LSB法而且提取时可以回到同一组子带系数上比对不需要维护额外索引。Matlab里做这套仿真并不复杂核心就是wavedec2拆系数、按嵌入规则改动系数、再用waverec2重建。本文按“分解结构→嵌入实现→提取验证→参数调优”的顺序把整条链路写清楚每一步给出可直接运行的命令和注释。适合正在做数字水印课程设计、毕业论文预研或者想在图像隐写基础上换一个更稳载体的工程人员。2. 小波变换把图像拆成四个子带时发生了什么2.1 离散小波分解对图像做了什么图像是二维信号wavedec2会先对行做低通/高通滤波再对列做同样的处理于是每一层分解得到四个子带近似分量cA低频、水平细节cH、垂直细节cV、对角细节cD。下一层只对cA继续分解所以一级分解是1个低频块加3个高频块二级分解则把cA再切成4块最终得到7个子带。水印嵌入一般放在高频块里因为低频系数改动一点就会被肉眼察觉。但也不是直接乱改所有高频系数而是挑绝对值较大、集中了图像边缘信息的系数。原因很简单这些系数改动后逆变换重建出来的图像纹理区域本来变化就多人眼很难发现异常。Matlab里看一个子带分布最快的方法是这样的img imread(lena.bmp); if size(img, 3) 3 img rgb2gray(img); end img double(img); % 用小波基函数db2做一层分解 [CA, CH, CV, CD] dwt2(img, db2); % 画出四个子带 figure; subplot(2,2,1), imshow(uint8(CA)), title(低频近似 CA); subplot(2,2,2), imshow(uint8(CH)), title(水平细节 CH); subplot(2,2,3), imshow(uint8(CV)), title(垂直细节 CV); subplot(2,2,4), imshow(uint8(CD)), title(对角细节 CD);第7行是核心dwt2返回一层分解的四个系数矩阵。其中CA的数值范围接近原图的低频内容其他三个矩阵里大部分值接近0非零值集中在边缘和纹理处。水印提取时要和这个特性配合因为嵌入强度太小会被当成噪声丢掉太大又会在重建图像上留下块状痕迹。2.2 高频子带的能量分布决定了水印放哪里实际处理时我不会直接对整个高频子带做改动而是先做一个能量筛选把CH、CV、CD系数按绝对值排序只改前面约30%50%的大系数。这样做的理由是系数越小意味着它受压缩量化影响越大压缩后可能直接被清零水印就丢了。筛选可以这样做% 取垂直细节子带为例 band CV; coeff_vec abs(band(:)); % 取整10%分位作为阈值保留绝对值较大的系数 threshold prctile(coeff_vec, 90); mask abs(band) threshold;prctile(coeff_vec, 90)表示第90百分位数即只有10%的系数会超过这个阈值。mask就是一张和CV一样大的逻辑矩阵为1的位置是需要嵌入水印的位置。这个比例不是随便定的JPEG质量因子70时高频DWT系数大约会损失掉一半的小系数所以只保留10%的大系数做嵌入可以保证压缩后这些位置还是非零的。2.3 一层分解还是多层分解的选择一级DWT只有4个子带高频块尺寸和原图一样大能容纳的水印比特数取决于大系数数量。如果水印是一张64×64的二值图用一级分解就要把水印序列化到8192个比特上每个比特至少对应一个系数。按10%的嵌入密度原始图像至少要81920个像素即约286×286尺寸的灰度图。多数测试图都满足条件。二级分解把低频继续细分细节子带尺寸变成原来的四分之一嵌入密度不够时会显得拥挤。但二级分解的好处是抗JPEG压缩更强。折中方案是一级分解做嵌入演示二级分解做鲁棒性对比实验。本文后面第4章的实验就跑的是二级分解版本提取时用wavedec2的返回向量而不是单独操作某一块系数。3. 水印嵌入的Matlab完整实现与参数解析3.1 水印图像预处理从二维图像变成一串比特水印要先做“降维”把二值图像展平成行向量或列向量方便按序嵌入。同时要把像素值从0/255映射到-1/1这样嵌入公式可以直接用乘性叠加。wm imbinarize(imread(watermark.png)); wm_vector wm(:); % 把逻辑0/1转为-1/1 wm_bipolar 2 * double(wm_vector) - 1;第3行把逻辑值转成双极性信号。如果直接嵌入0/1叠加到高频系数上时0值位置完全不改动提取时只要系数有微小偏移就会判错转成-1/1后每个位置都有明确的加减操作提取阈值可以设置在0上下。3.2 嵌入规则加法还是乘法常见的嵌入规则有两种。第一种是加性嵌入改动后的系数 原系数 alpha * 水印比特。第二种是乘性嵌入改动后的系数 原系数 * (1 alpha * 水印比特)。我一般用乘性嵌入处理DWT高频系数因为高频系数绝对值有大有小加性嵌入会给小系数加上一个相对过大的扰动逆变换后容易出现不自然的斑点乘性嵌入则让改动幅度跟随系数本身的大小视觉上更均匀。乘性嵌入的关键代码段如下alpha 0.12; % 嵌入强度越大越鲁棒但透明性下降 watermarked_band band; idx find(mask); for k 1:min(length(idx), length(wm_bipolar)) pos idx(k); watermarked_band(pos) band(pos) * (1 alpha * wm_bipolar(k)); end为了缩短仿真耗时实际写的时候我会用矩阵运算替代上面的for循环只把mask为真的位置和有效水印长度对齐watermarked_band band; idx find(mask); n_embed min(numel(idx), numel(wm_bipolar)); active_idx idx(1:n_embed); watermarked_band(active_idx) band(active_idx) .* (1 alpha * wm_bipolar(1:n_embed));active_idx只取前n_embed个位置水印越长嵌入位置越多。如果水印比特数超过可用位置数就会有一部分水印没嵌进去提取时只能取回部分信息。第3行用了点乘运算band(active_idx)是列向量wm_bipolar(1:n_embed)也是列向量Matlab要求两个向量维度一致才能逐元素相乘这里转置操作不能少。3.3 逆变换重建含水印图像三个高频子带分别嵌入水印后将它们和未改动的CA一起丢给idwt2重建watermarked_CH CH; watermarked_CV CV; watermarked_CD CD; % 这里演示只嵌垂直细节子带其他两个高频子带可以同样处理 watermarked_CV CV; idx_CV find(abs(CV) prctile(abs(CV(:)), 90)); watermarked_CV(idx_CV(1:n_embed)) CV(idx_CV(1:n_embed)) .* ... (1 alpha * wm_bipolar(1:n_embed)); % 逆变换 img_watermarked idwt2(CA, watermarked_CH, watermarked_CV, watermarked_CD, db2); img_watermarked uint8(img_watermarked);第8行是idwt2的典型用法输入顺序必须是CA、CH、CV、CD不能调换。db2必须和嵌入时用的基函数完全一致否则重建出来的图像会有严重的边缘失真。这里演示只嵌了一个子带实际完整方案会对三个高频子带都做嵌入以提升水印容量。嵌入强度alpha在0.10到0.15之间时重建图像的峰值信噪比通常在40dB以上肉眼基本看不出区别。alpha到0.2以后图像边缘会出现轻微“振铃”那就是过度修改高频系数的直接代价。4. 水印提取算法、相似度计算与攻击测试4.1 提取时如何还原水印信号提取的关键是必须拥有原始载体图像。把小波变换频道的系数比对一遍差值超过阈值的记为1低于阈值的记为-1就能还原水印序列。function extracted extract_watermark(original_img, watermarked_img, wm_length, alpha, wavelet) % 对两张图做同样的dwt2分解 [~, CH_orig, CV_orig, CD_orig] dwt2(double(original_img), wavelet); [~, CH_wm, CV_wm, CD_wm] dwt2(double(watermarked_img), wavelet); % 以垂直细节为例计算相对差 diff_CV (CV_wm - CV_orig) ./ (CV_orig eps); % 阈值为alpha/2超过则判为1低于则判为-1 extracted diff_CV alpha / 2; extracted extracted(:); end第6行的eps用来避免除零。实际运行时如果原图某个位置的系数恰好为0水印嵌入时它乘以(1 alpha * bit)仍为0提取时CV_wm - CV_orig也等于0放不放进阈值比较都不影响结果但除零会导致NaN所以加了eps。alpha / 2这个阈值是经验值alpha取0.12时阈值就是0.06只要JPEG压缩没有把系数扰动幅度压到阈值以下就能正确判出来。4.2 相似度NC与误码率哪个更直观提取出的水印序列要原水印序列比对。常用指标是归一化相关系数NC和误码率BER。NC的定义是两序列内积除以各自模长的乘积取值在-1到1之间NC大于0.7通常认为水印存在大于0.9说明提取质量很好。BER则是错判比特数占总比特数的比例直接反映实用性。orig_seq wm_bipolar; extracted_seq 2 * double(extracted(:)) - 1; n min(length(orig_seq), length(extracted_seq)); nc_value sum(orig_seq(1:n) .* extracted_seq(1:n)) / ... (sqrt(sum(orig_seq(1:n).^2)) * sqrt(sum(extracted_seq(1:n).^2))); ber_value sum(orig_seq(1:n) ~ extracted_seq(1:n)) / n;第5行的内积计算把所有正确匹配的乘积加起来匹配时乘积为1不匹配为-1所以NC对每个比特的贡献是等权的。BER更直观比如0.05表示100个比特里错5个。工程上两个指标会一起报出来课程设计报告里也要同时给这两个数。4.3 用imwrite模拟JPEG压缩攻击Matlab里仿真最常见的攻击就是JPEG压缩因为写文件时imwrite会重新量化DCT系数DWT系数的相对变化能直接反映水印的抗压能力imwrite(img_watermarked, w.jpg, Quality, 50); attacked imread(w.jpg); % 重新提取水印并计算NCQuality设的越低压缩越狠。我试过从90一路降到20实验结果贴在下面方便你评估自己的嵌入强度是否够用。JPEG QualityNC值BER值视觉观察900.9820.012无可见退化700.9410.038轻微模糊500.8730.074边缘出现压缩块300.7450.141明显色块噪声200.6210.219严重失真水印基本不可辨这个表对应alpha0.12、单层DWT、db2基函数的结果。如果只嵌一个高频子带JPEG Quality低于30时NC会掉到0.6以下此时水印视觉上已经糊成一团但NC仍大于0.5说明统计上还有微弱相关性。把alpha提高到0.18后Quality30时NC能回到0.8以上代价是原图PSNR从42dB降到36dB左右。4.4 高斯噪声和中值滤波攻击实验压缩之外还会遇到两种常见处理加噪和滤波。仿真命令很短但要注意噪声强度必须和alpha匹配否则要么噪声把水印盖掉要么噪声本身把图像搞坏。% 高斯噪声攻击 noisy imnoise(uint8(img_watermarked), gaussian, 0, 0.002); % 中值滤波攻击 filtered medfilt2(uint8(img_watermarked), [3 3]);高斯噪声的方差0.002对应约5%的像素灰度波动对alpha0.12的水印影响很小NC一般还在0.9附近。中值滤波把3×3窗口内的中值作为中心像素值会直接抹掉一部分高频细节如果嵌入时用了较多小系数过滤后就会判错更多比特。所以嵌入时要挑大系数就是这个原因。5. 量化步长、小波基函数与批量调参技巧最后一章不再讲流程重点讲三个实际仿真中的调参技巧直接改善提取正确率。5.1 alpha取值与小波基函数的关系不同小波基函数对同样的alpha响应不同。Haar小波db1的基函数是矩形波分解出的高频系数稀疏度最高但量化噪声也最容易影响它。db2和db4的支撑长度更长高频系数能量分布更均匀同样的alpha下视觉透明性更好提取时NC也略高。基函数支撑长度嵌入后PSNR(dB)JPEG Q50时NCdb1 (Haar)240.20.852db2441.50.873db4842.10.864sym4842.00.861从表里能看出db2和db4都比Haar高出一截原因在于Haar对离散像素突变更敏感改动一个系数在重建时会造成更宽的伪边缘。但db4的支撑长度长逆变换要处理的相邻像素多计算更慢仿真规模大时我一般锁定db2。5.2 用批处理脚本自动搜索alpha单张图试alpha靠肉眼判断效率低可以做一个简单网格搜索alpha_list 0.05:0.02:0.20; for i 1:length(alpha_list) a alpha_list(i); % 执行嵌入 % 执行JPEG压缩攻击 % 提取并计算NC record(i) nc_value; end [best_alpha, idx] max(record); fprintf(最优alpha %.2f, 对应NC %.4f\n, best_alpha, idx);这个脚本跑起来很慢建议把imwrite的Quality固定为50每个alpha跑一遍就够了。真实最佳alpha永远由透明性和鲁棒性两条曲线共同决定只用NC值找alpha会导致其结果过于偏向高alpha因为NC单调上升但视觉质量持续下降。我通常同时算PSNR设置一个下限比如PSNR低于38dB的alpha直接排除。5.3 常见仿真停顿点仿真卡住九成是维度不一致问题。比如嵌入用了CV(:)的长度提取时却拿wm_bipolar的原长度去比较长度不匹配会直接报错或产生错位。看日志时如果提取出来的水印是斜条纹状错乱图案就是嵌入顺序和提取顺序没对上。另一个常见问题是dwt2默认只处理二维矩阵如果输入的是RGB图却忘了转灰度会报“输入必须是二维”的警告这时回到第1步补一次rgb2gray。提示每次改alpha或基函数后先清空工作区变量再跑脚本避免上次仿真的wm_bipolar长度干扰本次提取的比较逻辑。如果发现提取的NC值忽高忽低检查一下mask里做索引用的prctile是不是每次都重新计算了。嵌入和提取必须用同一组系数位置否则水印从一个位置嵌进去、从另一个位置取出来结果当然是随机噪声。把mask保存下来或者由原图实时计算两边逻辑保持一致就不会出这种问题。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/9/16 17:37:15

MATLAB直齿圆柱齿轮应力计算GUI:从渐开线绘制到接触弯曲强度校核

简介:基于MATLAB GUI的直齿圆柱齿轮应力计算仿真程序,面向机械设计、机械原理课程设计及齿轮强度校核的初学者和工程人员。程序通过交互界面完成齿轮参数输入,计算齿面接触应力与齿根弯曲应力等关键指标,并支持渐开线齿廓绘制&…

2026/9/16 17:37:15

SSM+Vue+MySQL实现协同过滤推荐系统

简介:本资源是一套基于SSMVueMySQL实现的协同过滤算法电影推荐系统完整开发包,面向Java全栈初学者与毕业设计学生,解决传统电影平台推荐体验差、管理流程冗余、人工运营效率低等实际问题。压缩包含847个文件,总大小22.28MB&#x…

2026/9/16 19:22:32

群晖NAS硬盘损坏数据救援:Ubuntu 18.04完整实操指南

“当你的群晖NAS在凌晨三点突然弹出一条‘硬盘已损坏’的警报时,心跳绝对会漏半拍。”这句话几乎每个用群晖超过三年的玩家都感同身受。我曾经就遇到过一次硬盘报错,系统直接提示“存储池已降级”,当时手边既没有额外的盘位,也没有…

2026/9/16 19:22:32

企业级智能体效能管理:实现可度量、可治理的落地指南

前阵子跟几个做企业数字化架构的朋友聊天,大家不约而同提到一个尴尬的现状:模型选型越来越强,Demo 越跑越顺,可一旦进入生产环境,智能体应用就开始“失控”——有的回答质量忽高忽低,有的链路频繁报错&…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/16 0:04:09

PHP源码部署实战:从环境配置到运行情侣游戏全攻略

简介:这是一套面向情侣互动场景的PHP完整源码,集成情侣飞行棋、真心话大冒险、情趣骰子等玩法,并内置完整分销制度,可自定义多种返佣比例,源码完全开源无加密,支持微信无感自动授权登录与第三方授权&#x…

2026/9/15 14:22:53

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/15 21:31:11

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/15 11:42:23

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码