当前位置: 首页 > news >正文

手把手复现蓝桥杯‘缺失的数据’:用Python OpenCV和PyWavelets搞定数字水印提取

数字水印实战:用Python OpenCV和PyWavelets实现CTF题目复现

数字水印技术作为信息隐藏领域的重要分支,在版权保护、数据安全等方面有着广泛应用。本文将从一个典型的CTF竞赛题目出发,完整复现数字水印的提取过程,帮助读者掌握OpenCV和PyWavelets库在图像处理中的实际应用。

1. 环境准备与基础知识

在开始之前,我们需要搭建合适的开发环境。推荐使用Python 3.8或更高版本,并安装以下关键库:

pip install opencv-python numpy pywavelets

数字水印技术主要分为空域方法和频域方法两大类。空域方法直接修改像素值,而频域方法(如本文使用的小波变换)则通过修改变换域系数来嵌入水印,具有更好的鲁棒性。

Arnold变换是一种常用的图像置乱技术,其数学表达式为:

$$ \begin{bmatrix} x' \ y' \end{bmatrix}

\begin{bmatrix} 1 & b \ a & ab+1 \end{bmatrix} \begin{bmatrix} x \ y \end{bmatrix} \mod N $$

其中a、b为参数,N为图像尺寸。通过多次迭代,可以实现图像的置乱和复原。

2. 核心算法解析

2.1 Arnold变换实现

Arnold变换的核心代码实现如下:

def arnold(self, img): r, c = img.shape p = np.zeros((r, c), np.uint8) a, b = 1, 1 for k in range(self.key): for i in range(r): for j in range(c): x = (i + b * j) % r y = (a * i + (a * b + 1) * j) % c p[x, y] = img[i, j] return p

对应的逆变换为:

def deArnold(self, img): r, c = img.shape p = np.zeros((r, c), np.uint8) a, b = 1, 1 for k in range(self.key): for i in range(r): for j in range(c): x = ((a * b + 1) * i - b * j) % r y = (-a * i + j) % c p[x, y] = img[i, j] return p

注意:key参数决定了变换的迭代次数,必须与加密时使用的次数一致才能正确恢复图像。

2.2 小波变换应用

离散小波变换(DWT)将图像分解为不同频率的子带,是数字水印嵌入的常用方法。我们使用PyWavelets库实现三级小波分解:

c = pywt.wavedec2(img2, 'db2', level=3) [cl, (cH3, cV3, cD3), (cH2, cV2, cD2), (cH1, cV1, cD1)] = c

水印提取的关键步骤是对系数进行加权处理:

ca1 = (cl - dl) * a1 ch1 = (cH3 - dH3) * a2 cv1 = (cV3 - dV3) * a3 cd1 = (cD3 - dD3) * a4

3. 完整水印提取流程

3.1 图像预处理

首先读取并预处理原始图像和水印图像:

img = cv2.imread('a.png') watermark = cv2.imread('newImg.png') img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) mark_gray = cv2.cvtColor(watermark, cv2.COLOR_RGB2GRAY)

3.2 水印提取实现

完整的水印提取类实现如下:

class WaterMarkDWT: def __init__(self, origin: str, watermark: str, key: int, weight: list): self.key = key self.img = cv2.imread(origin) self.mark = cv2.imread(watermark) self.coef = weight # ... Arnold变换和逆变换方法 ... def get(self, size: tuple = (1200, 1200), flag: int = None): img = cv2.resize(self.img, size) img1 = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) img2 = cv2.cvtColor(self.mark, cv2.COLOR_RGB2GRAY) # 小波分解 c = pywt.wavedec2(img2, 'db2', level=3) [cl, (cH3, cV3, cD3), (cH2, cV2, cD2), (cH1, cV1, cD1)] = c d = pywt.wavedec2(img1, 'db2', level=3) [dl, (dH3, dV3, dD3), (dH2, dV2, dD2), (dH1, dV1, dD1)] = d # 系数处理 a1, a2, a3, a4 = self.coef ca1 = (cl - dl) * a1 ch1 = (cH3 - dH3) * a2 cv1 = (cV3 - dV3) * a3 cd1 = (cD3 - dD3) * a4 # 确保系数形状一致 ca1 = cv2.resize(ca1, (cD3.shape[1], cD3.shape[0])) # 小波重构 waterImg = pywt.waverec2([ca1, (ch1, cv1, cd1)], 'db2') waterImg = np.array(waterImg, np.uint8) waterImg = self.deArnold(waterImg) # 形态学处理 kernel = np.ones((3, 3), np.uint8) if flag == 0: waterImg = cv2.erode(waterImg, kernel) elif flag == 1: waterImg = cv2.dilate(waterImg, kernel) return waterImg

3.3 参数调优技巧

水印提取效果受多个参数影响:

参数作用典型值范围
keyArnold变换迭代次数10-50
a1近似系数权重0.1-0.3
a2水平细节权重0.1-0.3
a3垂直细节权重0.3-0.6
a4对角细节权重0.2-0.5

实际应用中,可以通过以下方法优化提取效果:

  1. 逐步调整权重参数,观察水印清晰度变化
  2. 尝试不同的形态学处理方法(腐蚀、膨胀)
  3. 对小波重构结果进行直方图均衡化

4. 实战应用与扩展

4.1 自定义图像测试

读者可以尝试用自己的图像进行测试:

if __name__ == '__main__': # 使用自定义图像 img = 'your_image.png' watermark = 'your_watermarked_image.png' k = 25 # 尝试不同迭代次数 xs = [0.15, 0.25, 0.45, 0.35] # 调整权重 W1 = WaterMarkDWT(img, watermark, k, xs) extracted_watermark = W1.get() cv2.imwrite('extracted_watermark.png', extracted_watermark)

4.2 常见问题解决

在实际操作中可能会遇到以下问题:

  • 图像尺寸不匹配:确保原始图像和水印图像尺寸相同,或使用resize统一尺寸
  • 水印不清晰:尝试调整权重系数,增加Arnold变换的迭代次数
  • 噪声干扰:对小波重构结果进行中值滤波处理

4.3 技术扩展方向

基于本案例,可以进一步探索:

  1. 鲁棒性测试:对含水印图像进行压缩、裁剪等操作,测试提取效果
  2. 彩色图像水印:将算法扩展到RGB三通道
  3. 盲水印提取:研究不需要原始图像的提取方法

数字水印技术的实际应用远不止于CTF竞赛,在版权保护、内容认证等领域都有重要价值。通过这个实战项目,我们不仅掌握了相关Python库的使用,更重要的是理解了数字水印的核心原理。

http://www.gsyq.cn/news/1500966.html

相关文章:

  • 动手搭一个可调直流电源:用Arduino+晶闸管实现AC-DC可控整流(附代码和波形分析)
  • 别再只看K线了!用Python复刻同花顺里的VR、VMA等10个量价指标(附完整代码)
  • 神经网络场论与弦论路径积分的融合研究
  • 别再只看K线了!用Python复刻同花顺的VR和VSTD指标,量化你的风险感知力
  • 工厂照明节能改造:成本控制、分区设计与零碳工厂照明指标
  • 告别混乱!用Quicker+Zotero6打造你的五星级文献管理系统(附详细配置脚本)
  • OpenGL实战:用中点Bresenham算法手搓一个椭圆(附完整C++代码)
  • MC9S12XE Flash模块实战:从底层驱动到安全解锁与EEE仿真
  • 如何快速提升戴森球计划工厂效率:3000+专业蓝图库完整指南
  • YOLOv5 6.0轻量手势数字检测包:1908张清洗图+4MB终版权重+完整训练可视化
  • 2026年 PLC控制柜实力厂家推荐榜:技术硬核与稳定可靠之选,plc控制柜源头厂家、自动化控制系统厂家专业榜单解析 - 品牌发掘
  • 如何用VDesk实现3倍工作效率提升:Windows虚拟桌面的智能管理实践
  • SAP BOM查询实战:CS11到CS15,哪个事务码才是你的菜?(附BAPI调用避坑点)
  • 怎样快速掌握AI全自动短视频制作:Pixelle-Video新手完整指南
  • CPT Markets:聚焦细节,看看外汇领域风控思路的关键路径
  • Android步行/驾车路线规划Demo:百度地图SDK集成即用工程
  • 还在人工剪视频?2026年五大跨境电商AI视频生成工具推荐
  • Visual Studio 2019编译报错MSB4018?别慌,一个空文件夹就能搞定
  • 2026 年 5 月开源模型 Token 服务性能榜出炉!实测 30 + 服务商,看清Token服务三层架构下真实服务实力
  • C++写的轻量QR码编码器,纯头文件+源码,不依赖第三方库
  • Vue项目里用SM4加密用户密码,我是这样和后端联调的(附完整代码)
  • 别再傻等在线工具了!手把手教你用FastANI本地批量计算基因组ANI(附避坑指南)
  • 成都会议桌定制实测评测:三家本土企业核心能力对比 - 优质品牌商家
  • 找标题AE模版不用愁!12个优质平台实用技巧汇总
  • Teachable Machine:浏览器端零代码机器学习平台架构深度解析
  • 3个步骤让Windows电脑变身AirPlay接收器:开源项目airplay2-win使用指南
  • 大模型本地部署,vLLM_推理优化,动手实验
  • 别再硬猜了!教你写一个智能的AES密钥内存扫描器(Java实现,支持128/256位)
  • 使用Qt6 QML以及第三方库FluentUI、PCapPlusPlus开发一个自定义抓包软件
  • 2026年近期临沂全季5.0千里书卷品牌厂商选型指南 - 品牌鉴赏官2026