圖像加密解密使用的是按位異或的運算,一真一假方為真,全真全假皆為假。
比方說,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 #指定打碼區(qū)域 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) # 打碼區(qū)域的像素置為255 占滿八位全1 按位與運算 使得打碼區(qū)域保持原樣 其他區(qū)域全黑 and_face = cv2.bitwise_and(xor_img, mask * 255) # 通過反色后按位與運算 使臉部區(qū)域置為全0 其他區(qū)域保持原樣 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'] # 與秘鑰按位異或運算 解析出臉部打碼區(qū)域 xor_img = cv2.bitwise_xor(img, key) # 臉部區(qū)域保留 其他區(qū)域置為全黑 and_face = cv2.bitwise_and(xor_img, mask * 255) # 打碼圖的臉部區(qū)域置為全黑 其他區(qū)域不變 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()
聯系客服