图像加密与解密
图像加密解密使用的是按位异或的运算,一真一假方为真,全真全假皆为假。
比方说,3和5进行按位异或,3的二进制为11,5的二进制为101,运算之后得到二进制110,换算成十进制也就是得到6,那么3、5、6这三个数字,任意两个进行按位异或运算都可以得出另一个。
import cv2 import numpy as np #读取图像 img = cv2.imread('./lena.jpg') #生成秘钥 key = np.random.randint(0,256,img.shape,dtype=np.uint8) #加密 secret = cv2.bitwise_xor(img,key) #解密 truth = cv2.bitwise_xor(secret,key) #显示图像 cv2.imshow('secret',secret) cv2.imshow('truth',truth) cv2.waitKey(0)
数字水印嵌入与提取
数字水印利用图像的位平面来实现,像素点最高为255,也就是8位二进制表示,每一位可以看成一个位面,高位代表的数字大,低位代表的数字小,整幅图像可以看成是由八个位平面堆叠而成,我们可以把水印图片嵌入到载体图片的最低层位平面。
import cv2 import numpy as np #读取原始载体图像 lena=cv2.imread("./lena.jpg") #读取水印图像 watermark=cv2.imread("./watermark.png",0) #将水印大于0的像素置为1 temp = watermark[:,:] > 0 watermark[temp] = 1 #读取G通道 打算将水印嵌入本通道(想把水印藏到哪个通道都随意) g_channel = lena[:,:,1] #保留前7位 末位置为0 g_channel_1 = np.left_shift(np.right_shift(g_channel,1),1) #嵌入载体图像 new_channel = cv2.bitwise_or(g_channel_1,watermark) lena[:,:,1] = new_channel #提取g通道 channel = lena[:,:,1] #生成全1数组 temp1 = np.ones(channel.shape,dtype=np.uint8) #按位与运算,提取水印 water = cv2.bitwise_and(temp1,channel) #将1处理为255 w= water[:,:] > 0 water[w] = 255 #显示嵌入水印的图像 cv2.imshow('img',lena) #显示从图像中提取的水印 cv2.imshow('water',water) cv2.waitKey()
脸部打码与解码
脸部打码与解码是使用像素点进行按位运算的综合应用
import cv2 import numpy as np #读取原始载体图像 lena = cv2.imread("./lena.jpg") shape = lena[:,:,0].shape #指定打码区域 mask = np.zeros(shape,dtype=np.uint8) mask[220:380,220:350] = 1 #获取一个key,打码、解码所使用的密钥 key = np.random.randint(0,256,size=shape,dtype=np.uint8) def encode(img): ''' 脸部打码 :param img: 图像 :return: 打码图 ''' key = globals()['key'] mask = globals()['mask'] # 使用密钥key加密原始图像lena 整幅图被加密 xor_img = cv2.bitwise_xor(img, key) # 打码区域的像素置为255 占满八位全1 按位与运算 使得打码区域保持原样 其他区域全黑 and_face = cv2.bitwise_and(xor_img, mask * 255) # 通过反色后按位与运算 使脸部区域置为全0 其他区域保持原样 no_face = cv2.bitwise_and(img, (1 - mask) * 255) # 两矩阵各像素相加 得到脸部打码图像 return and_face + no_face def decode(img): ''' 脸部解码 :param img: 图像 :return: 解码图 ''' key = globals()['key'] mask = globals()['mask'] # 与秘钥按位异或运算 解析出脸部打码区域 xor_img = cv2.bitwise_xor(img, key) # 脸部区域保留 其他区域置为全黑 and_face = cv2.bitwise_and(xor_img, mask * 255) # 打码图的脸部区域置为全黑 其他区域不变 no_face = cv2.bitwise_and(img, (1 - mask) * 255) # 两矩阵各像素相加 得到脸部解码图像 return and_face + no_face #脸部打码 b_channel = encode(lena[:,:,0]) g_channel = encode(lena[:,:,1]) r_channel = encode(lena[:,:,2]) secret_img = cv2.merge([b_channel,g_channel,r_channel]) cv2.imshow('secret_img',secret_img) #脸部解码 b_channel = decode(secret_img[:,:,0]) g_channel = decode(secret_img[:,:,1]) r_channel = decode(secret_img[:,:,2]) true_img = cv2.merge([b_channel,g_channel,r_channel]) cv2.imshow('true_img',true_img) cv2.waitKey() cv2.destroyAllWindows()