图像矩阵中的每个值是一个八位二进制数,它可以表示为:
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=a0⋅20+a1⋅21+a2⋅22+a3⋅23+a4⋅24+a5⋅25+a6⋅26+a7⋅27ai=0/1
将整个矩阵的值的 a i ⋅ 2 i a_i·2^{i} ai⋅2i 提取出来,得到新的8个矩阵,称这8个矩阵为图像的位平面。
可以通过按位与实现。
获取图像的形状
# 图像预处理
image = cv2.imread("./monalisa.png")
shape=image.shape
与 2 i 2^i 2i作按位与运算,可以得到第i位的值
故需构造8个值全为 2 i 2^i 2i 的矩阵
# 构造提取矩阵
for i in range(8):
bit_mat=np.ones(shape)*(2**i)
与提取矩阵分别进行按位与运算
# 位平面提取
result=cv2.bitwise_and(image,bit_mat)
为了让位平面更加清晰可见,将 2 i 2^i 2i 全都处理为255
# 阈值处理
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)
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位。它影响整个图像的程度更低。我们可以把一些信息隐藏到最低有效位平面中。
可称之为数字水印。
将数字与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)
将正值全部设置为1,方便嵌入载体图像的第0位
info=cv2.imread("./info.png")
for j in range(3):
info_mask = info[:, :, j] > 0
info[info_mask] = 1
将处理完后的载体图像与水印图像作按位或运算,可以将水印图像嵌入载体图像的第0位
result1=cv2.bitwise_or(image,info)
cv2.namedWindow("in", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.imshow("in",result1)
用全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()