图像的加密与解密

图像加密与解密

图像加密解密使用的是按位异或的运算,一真一假方为真,全真全假皆为假。

比方说,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()

 

posted @ 2021-01-18 08:29  不该相遇在秋天  阅读(2790)  评论(1编辑  收藏  举报