0


【OpenCV 例程200篇】219. 添加数字水印(盲水印)

OpenCV 例程200篇 总目录

【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,"Copyright@youcans, 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()

在这里插入图片描述

【本节完】

版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/125506913)
Copyright 2022 youcans, XUPT
Crated:2022-7-5
欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中

  1. 多行倾斜文字水印
  2. 添加数字盲水印

本文转载自: https://blog.csdn.net/youcans/article/details/125506913
版权归原作者 小白YouCans 所有, 如有侵权,请联系我们删除。

“【OpenCV 例程200篇】219. 添加数字水印(盲水印)”的评论:

还没有评论