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

位平面分解与数字水印

  • 位平面分解与数字水印
    • 位平面分解
      • 1.图像预处理
      • 2.构造提取矩阵
      • 3.位平面提取
      • 4.阈值处理
      • 5.显示图像
    • 简单的数字水印
      • 1.载体图像预处理
      • 2.水印图像处理
      • 3.水印添加
      • 4.水印提取

位平面分解与数字水印

两张素材:
opencv-python之位平面分解与数字水印_第1张图片
opencv-python之位平面分解与数字水印_第2张图片

位平面分解

图像矩阵中的每个值是一个八位二进制数,它可以表示为:
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()

opencv-python之位平面分解与数字水印_第3张图片

简单的数字水印

最低有效位指的是第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()

opencv-python之位平面分解与数字水印_第4张图片

你可能感兴趣的:(opencv-python,python,opencv,平面)