当前位置:网站首页>【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. 添加数字盲水印
边栏推荐
- From "chemist" to developer, from Oracle to tdengine, two important choices in my life
- Unity skframework framework (XXII), runtime console runtime debugging tool
- Tdengine offline upgrade process
- 【对象数组a与对象数组b取出id不同元素赋值给新的数组】
- Three-level distribution is becoming more and more popular. How should businesses choose the appropriate three-level distribution system?
- 一篇文章带你走进cookie,session,Token的世界
- 【饿了么动态表格】
- Develop and implement movie recommendation applet based on wechat cloud
- Baidu app's continuous integration practice based on pipeline as code
- 使用el-upload封装得组件怎么清空已上传附件
猜你喜欢
Vs code problem: the length of long lines can be configured through "editor.maxtokenizationlinelength"
[sourcetree configure SSH and use]
百度APP 基于Pipeline as Code的持续集成实践
The writing speed is increased by dozens of times, and the application of tdengine in tostar intelligent factory solution
Oracle combines multiple rows of data into one row of data
Charm of code language
干货整理!ERP在制造业的发展趋势如何,看这一篇就够了
Analysis on the wallet system architecture of Baidu trading platform
解决idea调试过程中liquibase – Waiting for changelog lock….导致数据库死锁问题
卷起來,突破35歲焦慮,動畫演示CPU記錄函數調用過程
随机推荐
Baidu app's continuous integration practice based on pipeline as code
Are databases more popular as they get older?
Principle and performance analysis of lepton lossless compression
On July 2, I invite you to TD Hero online press conference
Tdengine can read and write through dataX, a data synchronization tool
[NTIRE 2022]Residual Local Feature Network for Efficient Super-Resolution
Node の MongoDB Driver
LeetCode 496. Next larger element I
[hungry dynamic table]
【对象数组的排序】
Small program startup performance optimization practice
代码语言的魅力
Unity SKFramework框架(二十四)、Avatar Controller 第三人称控制
Android privacy sandbox developer preview 3: privacy, security and personalized experience
卷起來,突破35歲焦慮,動畫演示CPU記錄函數調用過程
How to choose the right chain management software?
单片机原理与接口技术(ESP8266/ESP32)机器人类草稿
微信小程序获取住户地区信息
oracle 多行数据合并成一行数据
Analysis of eventbus source code