opencv-python之位平面分解与数字水印

位平面分解与数字水印

两张素材:
在这里插入图片描述
在这里插入图片描述

位平面分解

图像矩阵中的每个值是一个八位二进制数,它可以表示为:
v a l u e = a 0 ⋅ 2 0 + a 1 ⋅ 2 1 + a 2 ⋅ 2 2 + a 3 ⋅ 2 3 + a 4 ⋅ 2 4 + a 5 ⋅ 2 5 + a 6 ⋅ 2 6 + a 7 ⋅ 2 7 a i = 0 / 1 value=a_0·2^0+a_1·2^1+a_2·2^2+a_3·2^3+a_4·2^4+a_5·2^5+a_6·2^6+a_7·2^7 \\ a_i=0/1 value=a020+a121+a222+a323+a424+a525+a626+a727ai=0/1
将整个矩阵的值的 a i ⋅ 2 i a_i·2^{i} ai2i 提取出来,得到新的8个矩阵,称这8个矩阵为图像的位平面。

可以通过按位与实现。

1.图像预处理

获取图像的形状

# 图像预处理
image = cv2.imread("./monalisa.png")
shape=image.shape

2.构造提取矩阵

2 i 2^i 2i作按位与运算,可以得到第i位的值

故需构造8个值全为 2 i 2^i 2i 的矩阵

# 构造提取矩阵
for i in range(8):
    bit_mat=np.ones(shape)*(2**i)

3.位平面提取

与提取矩阵分别进行按位与运算

	# 位平面提取
    result=cv2.bitwise_and(image,bit_mat)

4.阈值处理

为了让位平面更加清晰可见,将 2 i 2^i 2i 全都处理为255

	# 阈值处理
    for j in range(3):
        mask=result[:,:,j]>0
        result[mask]=255

5.显示图像

	# 显示图像
    cv2.namedWindow(f"bit {i}", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
    cv2.imshow(f"bit {i}",result)
import cv2
import numpy as np

# 图像预处理
image = cv2.imread("./monalisa.png")
shape = image.shape

# 构造提取矩阵
for i in range(8):
    bit_mat = np.ones(shape, dtype=np.uint8) * (2**i)

    # 位平面提取
    result = cv2.bitwise_and(image, bit_mat)

    # 阈值处理
    for j in range(3):
        mask = result[:, :, j] > 0
        result[mask] = 255

    # 显示图像
    cv2.namedWindow(f"bit {i}", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
    cv2.imshow(f"bit {i}", result)

# 关闭窗口
key = chr(cv2.waitKey())
if key == "1":
    print("图像显示结束")
    cv2.destroyAllWindows()

在这里插入图片描述

简单的数字水印

最低有效位指的是第0位。它影响整个图像的程度更低。我们可以把一些信息隐藏到最低有效位平面中。

可称之为数字水印。

1.载体图像预处理

将数字与11111110(十进制为254)作按位与,可以保留前7位,将第0位设置为0

image = cv2.imread("./monalisa.png")
bit_mat=np.ones(image.shape, dtype=np.uint8) * (254)
image=cv2.bitwise_and(image,bit_mat)

2.水印图像处理

将正值全部设置为1,方便嵌入载体图像的第0位

info=cv2.imread("./info.png")
for j in range(3):
        info_mask = info[:, :, j] > 0
        info[info_mask] = 1

3.水印添加

将处理完后的载体图像与水印图像作按位或运算,可以将水印图像嵌入载体图像的第0位

result1=cv2.bitwise_or(image,info)
cv2.namedWindow("in", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.imshow("in",result1)

4.水印提取

用全1矩阵与添加完水印的图像作按位与运算,提取第0位,并扩大到255倍,方便显示水印图像

# 水印提取
bit_mat=np.ones(image.shape, dtype=np.uint8)
result2=cv2.bitwise_and(result1,bit_mat)*255
cv2.namedWindow("out", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.imshow("out",result2)

import cv2
import numpy as np

# 载体图像预处理
image = cv2.imread("./monalisa.png")
bit_mat=np.ones(image.shape, dtype=np.uint8) * (254)
image=cv2.bitwise_and(image,bit_mat)

# 水印图像处理
info=cv2.imread("./info.png")
for j in range(3):
        info_mask = info[:, :, j] > 0
        info[info_mask] = 1

# 水印添加
result1=cv2.bitwise_or(image,info)
cv2.namedWindow("in", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.imshow("in",result1)

# 水印提取
bit_mat=np.ones(image.shape, dtype=np.uint8)
result2=cv2.bitwise_and(result1,bit_mat)*255
cv2.namedWindow("out", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.imshow("out",result2)

key = chr(cv2.waitKey())
if key == "1":
    print("图像显示结束")
    cv2.destroyAllWindows()

在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子希卡利

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值