当前位置:网站首页>【OpenCV 例程200篇】219. 添加数字水印(盲水印)
【OpenCV 例程200篇】219. 添加数字水印(盲水印)
2022-07-05 09:34:00 【小白YouCans】
【youcans 的 OpenCV 例程200篇】219. 添加数字水印(盲水印)
8.2 添加数字盲水印
数字水印,是指将特征信息嵌入音频、图像或是视频等数字信号中。
数字水印分为明水印和盲水印(blind watermark)。明水印包含的信息在观看图像或视频时可以看到。盲水印是以数字数据的方式嵌入图像中,在一般条件下是看不到的,需要特殊处理后才能提取到水印信息。盲水印也称为隐藏式水印,可以实现信息隐藏、版权认证、身份认证、数字签名等功能。
最低有效位(Least significant bit)盲水印,是最简单方便的盲水印实现方法。该方法的原理是将数字水印信息保存为二值图像,嵌入到原始图像的最低位,即将原始图像的最低有效位替换为水印图像。
以 8 位灰度图像为例,原始图像中像素点 P 的灰度值由 8 位二进制数 ( p 7 , p 6 , . . . , p 1 , p 0 ) (p_7, p_6,...,p_1,p_0) (p7,p6,...,p1,p0) 表示,二值水印图像中像素点的像素值由 1 位二进制数 b 0 b_0 b0 表示。用水印图像的像素值 b 0 b_0 b0 替换原始图像的最低有效位 p 0 p_0 p0,就得到嵌入水印的 8 位二进制数 ( p 7 , p 6 , . . . , p 1 , b 0 ) (p_7, p_6,...,p_1,b_0) (p7,p6,...,p1,b0)。
提取盲水印的过程与嵌入水印相反,从嵌入水印的原始图像 8 位二进制数 ( p 7 , p 6 , . . . , p 1 , b 0 ) (p_7, p_6,...,p_1,b_0) (p7,p6,...,p1,b0) 中,分离最低有效位 b 0 b_0 b0 生成水印图像。
提取盲水印的过程,则是对于嵌入水印的原始图像,将 8 位二进制数 ( p 7 , p 6 , . . . , p 1 , b 0 ) (p_7, p_6,...,p_1,b_0) (p7,p6,...,p1,b0) 的最低有效位置零。
例程 A4.11:在灰度图像添加数字盲水印
# A4.10 在灰度图像嵌入数字盲水印
img = cv.imread("../images/imgLena.tif", 0) # 加载原始图片,单通道
watermark = cv.imread("../images/logoCV.png", 0) # # 加载水印图片,单通道
markResize = cv.resize(watermark, img.shape[:2]) # 调整图片尺寸与 img 大小相同
_, binary = cv.threshold(markResize, 175, 1, cv.THRESH_BINARY) # 0/1 二值图像
# 对原始图像嵌入水印
# img (g7,g6,...g1,0) AND 254(11111110) -> imgH7: (g7,g6,...g1,0)
imgH7 = cv.bitwise_and(img, 254) # 按位与运算,图像最低位 LSB=0
# imgH7: (g7,g6,...g1,0) OR b -> imgMark: (g7,g6,...g1,b)
imgMark = cv.bitwise_or(imgH7, binary) # (g7,g6,...g1,b)
# 从嵌入水印图像中提取水印
# extract = np.mod(imgMark, 2) # 模运算,取图像的最低位 LSB
extract = cv.bitwise_and(imgMark, 1) # 按位与运算,取图像的最低位 LSB
plt.figure(figsize=(9, 6))
plt.subplot(221), plt.title("original gray"), plt.axis('off')
plt.imshow(img, cmap='gray')
plt.subplot(222), plt.title("watermark"), plt.axis('off')
plt.imshow(binary, cmap='gray')
plt.subplot(223), plt.title("embedding watermark"), plt.axis('off')
plt.imshow(imgMark, cmap='gray')
plt.subplot(224), plt.title("extracted watermark"), plt.axis('off')
plt.imshow(extract, cmap='gray')
plt.tight_layout()
plt.show()
例程 A4.12:在彩色图像各通道嵌入不同内容的数字盲水印
把彩色图像的各个通道分离处理,可以嵌入相同内容的数字水印,也可以嵌入不同内容的数字水印。
# A4.12 在彩色图像各通道嵌入不同内容的数字盲水印
img = cv.imread("../images/imgLena.tif", 1) # 加载原始图片,单通道
# 加载或生成水印信息
watermark = cv.imread("../images/logoCV.png", 0) # # 加载水印图片,单通道
markResize = cv.resize(watermark, img.shape[:2]) # 调整图片尺寸与 img 大小相同
_, binary = cv.threshold(markResize, 175, 1, cv.THRESH_BINARY) # 0/1 二值图像
mark1 = np.ones(img.shape[:2], np.uint8)
cv.putText(mark1, str(np.datetime64('today')), (50, 100), cv.FONT_HERSHEY_SIMPLEX, 2, 0, 2)
cv.putText(mark1, str(np.datetime64('now')), (50, 150), cv.FONT_HERSHEY_DUPLEX, 1, 0)
mark2 = np.ones(img.shape[:2], np.uint8)
cv.putText(mark2, "200 examples for OpenCV", (50, 300), cv.FONT_HERSHEY_SIMPLEX, 2, 0, 2)
cv.putText(mark2, "[email protected], 2022", (50, 350), cv.FONT_HERSHEY_DUPLEX, 1, 0)
# 对原始图像嵌入水印
# img: (g7,g6,...g1,0) -> imgH7: (g7,g6,...g1,0)
imgH7 = (img >> 1) << 1 # 右移->左移,图像最低位 LSB=0
# imgH7: (g7,g6,...g1,0) OR b -> imgMark: (g7,g6,...g1,b)
# 对各通道分别插入数字水印 binary,mark1,mark2
b = cv.bitwise_or(imgH7[:, :, 0], binary) # (g7,g6,...g1,b)
g = cv.bitwise_or(imgH7[:, :, 1], mark1) # (g7,g6,...g1,m1)
r = cv.bitwise_or(imgH7[:, :, 2], mark2) # (g7,g6,...g1,m2)
imgMark = cv.merge([b, g, r])
# # 从嵌入水印图像中提取水印
b, g, r = cv.split(imgMark) # 拆分为 BGR 独立通道
bMark = cv.bitwise_and(b, 1) # 按位与运算,取 B 通道的最低位 LSB
gMark = cv.bitwise_and(g, 1) # 按位与运算,取 G 通道的最低位 LSB
rMark = cv.bitwise_and(r, 1) # 按位与运算,取 R 通道的最低位 LSB
plt.figure(figsize=(9, 6))
plt.subplot(231), plt.title("original gray"), plt.axis('off')
plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
plt.subplot(232), plt.title("watermark"), plt.axis('off')
plt.imshow(binary, cmap='gray')
plt.subplot(233), plt.title("embedding watermark"), plt.axis('off')
plt.imshow(cv.cvtColor(imgMark, cv.COLOR_BGR2RGB))
plt.subplot(234), plt.title("watermark ch-B"), plt.axis('off')
plt.imshow(bMark, cmap='gray')
plt.subplot(235), plt.title("watermark ch-G"), plt.axis('off')
plt.imshow(gMark, cmap='gray')
plt.subplot(236), plt.title("watermark ch-R"), plt.axis('off')
plt.imshow(mark2, cmap='gray')
plt.show()
【本节完】
版权声明:
[email protected] 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/125506913)
Copyright 2022 youcans, XUPT
Crated:2022-6-28
欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中
210. 绘制直线也会有这么多坑?
211. 绘制垂直矩形
212. 绘制倾斜的矩形
213. 绘制圆形
214. 绘制椭圆的参数详解
215. 基于多段线绘制近似椭圆
216. 绘制多段线和多边形
217. 鼠标交互获取多边形区域
218. 多行倾斜文字水印
219. 添加数字盲水印
边栏推荐
- 解决Navicat激活、注册时候出现No All Pattern Found的问题
- What should we pay attention to when developing B2C websites?
- What should we pay attention to when entering the community e-commerce business?
- Figure neural network + comparative learning, where to go next?
- 基于模板配置的数据可视化平台
- Officially launched! Tdengine plug-in enters the official website of grafana
- Vs code problem: the length of long lines can be configured through "editor.maxtokenizationlinelength"
- 如何正确的评测视频画质
- SQL learning - case when then else
- Lepton 无损压缩原理及性能分析
猜你喜欢
Unity SKFramework框架(二十二)、Runtime Console 运行时调试工具
写入速度提升数十倍,TDengine 在拓斯达智能工厂解决方案上的应用
LeetCode 31. Next spread
【组队 PK 赛】本周任务已开启 | 答题挑战,夯实商品详情知识
Deep understanding of C language pointer
Tdengine can read and write through dataX, a data synchronization tool
Dry goods sorting! How about the development trend of ERP in the manufacturing industry? It's enough to read this article
TDengine 已经支持工业英特尔 边缘洞见软件包
Understanding of smt32h7 series DMA and DMAMUX
Why does everyone want to do e-commerce? How much do you know about the advantages of online shopping malls?
随机推荐
Observation cloud and tdengine have reached in-depth cooperation to optimize the cloud experience of enterprises
Small program startup performance optimization practice
[JS sort according to the attributes in the object array]
A detailed explanation of the general process and the latest research trends of map comparative learning (gnn+cl)
uni-app---uni.navigateTo跳转传参使用
Resolve the horizontal (vertical) sliding conflict between viewpager and WebView
Lepton 无损压缩原理及性能分析
Unity skframework framework (XXIII), minimap small map tool
Talking about the difference between unittest and pytest
Design and exploration of Baidu comment Center
[technical live broadcast] how to rewrite tdengine code from 0 to 1 with vscode
阿里十年测试带你走进APP测试的世界
C language - input array two-dimensional array a from the keyboard, and put 3 in a × 5. The elements in the third column of the matrix are moved to the left to the 0 column, and the element rows in ea
一文读懂TDengine的窗口查询功能
Data visualization platform based on template configuration
High performance spark_ Transformation performance
Android privacy sandbox developer preview 3: privacy, security and personalized experience
Three-level distribution is becoming more and more popular. How should businesses choose the appropriate three-level distribution system?
Android 隐私沙盒开发者预览版 3: 隐私安全和个性化体验全都要
正式上架!TDengine 插件入驻 Grafana 官网