![OpenCV轻松入门:面向Python](https://wfqqreader-1252317822.image.myqcloud.com/cover/910/26297910/b_26297910.jpg)
3.7 图像加密和解密
通过按位异或运算可以实现图像的加密和解密。
通过对原始图像与密钥图像进行按位异或,可以实现加密;将加密后的图像与密钥图像再次进行按位异或,可以实现解密。
按位异或运算的基本规则如表3-15所示。
表3-15 按位异或运算的基本规则
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0077-0077.jpg?sign=1739505235-NN7Gs4X0Yi3hPPZT3N89jKn4aQVjyEU1-0-de4024f130c70265cb0f027abd31714d)
根据上述按位异或运算的规则,假设:
xor(a, b)=c
则可以得到:
xor(c, b)=a xor(c, a)=b
上述运算的过程如表3-16所示。
表3-16 按位异或运算的过程示例
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0077-0078.jpg?sign=1739505235-FXltUT8ktQ9CiyTqB8JkkuCLkCFTeP5O-0-1a88d5a107b5fbe8563ea26e606a3489)
从上述结果可以看出,如果上述a、b、c具有如下关系:
● a:明文,原始数据。
● b:密钥。
● c:密文,通过xor(a, b)实现。
则可以对上述数据进行如下操作和理解。
● 加密过程:将明文a与密钥b进行按位异或,完成加密,得到密文c。
● 解密过程:将密文c与密钥b进行按位异或,完成解密,得到明文a。
位运算是指针对二进制位进行的运算,利用位运算即可实现对像素点的加密。在图像处理中,需要处理的像素点的值通常为灰度值,其范围通常为[0,255]。例如,某个像素点的值为216(明文),则可以使用178(该数值由加密者自由选定)作为密钥对其进行加密,让这两个数的二进制值进行按位异或运算,即完成加密,得到一个密文106。当需要解密时,将密文106与密钥178进行按位异或运算,即可得到原始像素点值216(明文)。具体过程为:
bit_xor(216,178)=106 bit_xor(106,178)=216
以二进制形式表示的具体细节如下。
● 加密过程
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0078-0079.jpg?sign=1739505235-UwKyDar3b7rOvlkDdQvpgndw87LAx23e-0-68ce2b8c5116dc49e595940f92e34ead)
● 解密过程
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0078-0080.jpg?sign=1739505235-OelVL2ZdbFEmmgLLZ3dOTu7PjkrkLJwS-0-d1955ca06b3ebb5f633417c15e0a66ad)
对图像内的每一个像素点重复上述操作,即可完成对图像的加密、解密操作。这里以一个原始图像O为例,具体说明图像的加密、解密过程。
1.加密过程
假设有需要加密的原始图像O,其中的像素值为:
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0078-0081.jpg?sign=1739505235-qkDmV2RxgZ2rVJWUfqDmY2aWF6IQSKR6-0-11b4513d562462faf73fd4b8eb5c2edc)
选定的加密密钥图像为K,其中的像素值为:
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0078-0082.jpg?sign=1739505235-jxOxY2yS4KwIAVrFtFGxpgTRh6dY8PAF-0-af64aa770e400420bc14f7410fd9deaa)
图像O所对应的二进制表示OB为:
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0078-0083.jpg?sign=1739505235-1n0VCTWTjn3uT0kxs9O3yU52fswEf3sS-0-b9f3d1ad3366699e4e7e6303a03f26bf)
密钥图像K所对应的二进制表示KB为:
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0078-0084.jpg?sign=1739505235-Y3WJ4D67tXvlerncKZLIcKpcqbiXIRFq-0-abde1ff0352f1a7b3b1d112f38b25bea)
将OB与KB进行按位异或运算,即得到图像O的加密图像OSB:
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0078-0085.jpg?sign=1739505235-VmGcOAm3VAY0n8QifG3o3cfaNgZqzoVO-0-7842db208b1f4568342e1c5294830081)
将OSB转换为十进制形式OS,如下:
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0079-0086.jpg?sign=1739505235-kpYhI8Vxx8tXYEbAVRp2Zy3ctvSjBLzN-0-a1942aea6e93e3df26221649bcdd9950)
至此,图像O的加密过程完成,得到原始图像O的加密图像OS。
2.解密过程
解密过程需要将加密图像OS与密钥图像K进行按位异或运算,得到原图像OR。
将加密图像OS的二进制形式OSB与密钥图像K的二进制形式KB进行按位异或运算,即得到原始图像OR的二进制形式ORB。按照上述运算,得到的ORB为:
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0079-0087.jpg?sign=1739505235-LN7J0HSQXTSRGmgL4clcw3rykPfXVTNL-0-add6178fb06917d5215531e50f3e3494)
将ORB转换为十进制形式,得到解密图像OR,如下:
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0079-0088.jpg?sign=1739505235-GnkaxGkLGH7fO31WhWMxgBw593CCXxFG-0-efaf4cb11016e56e872b6146e2c3878e)
至此,图像的解密过程结束,得到加密图像OS的解密图像OR。
从上述过程可以看到,解密过程所得到的解密图像OR与原始图像O是一致的。这说明上述加密、解密过程是正确的。
上述说明过程中,为了方便理解和观察数据的运算,在进行按位运算时,我们都是将十进制数转换为二进制数后,再进行位运算处理的。实际上,在使用OpenCV编写程序时,不需要这样转换,OpenCV中位运算函数的参数是十进制数,位运算函数会直接对十进制参数进行按位异或运算。
【例3.14】编写程序,通到图像按位异或实现加密和解密过程。
在具体实现中,甲乙双方可以通过协商预先确定一幅密钥图像,并且双方各保存一份备用。在此基础上,甲乙双方就可以利用该密钥图像进行图像的加密和解密处理了。例如,甲通过密钥对原始图像加密后,原始图像变得杂乱无章,其他人无法解读图像内容。而乙可以通过预先保存的密钥图像,将加密图像解密,获取原始图像内容。
在加密过程中,可以选择一幅有意义的图像作为密钥,也可以选择一幅没有意义的图像作为密钥。在本例中,将随机生成一幅图像作为密钥。
根据题目要求,编写代码如下:
import cv2 import numpy as np lena=cv2.imread("lena.bmp",0) r, c=lena.shape key=np.random.randint(0,256, size=[r, c], dtype=np.uint8) encryption=cv2.bitwise_xor(lena, key) decryption=cv2.bitwise_xor(encryption, key) cv2.imshow("lena", lena) cv2.imshow("key", key) cv2.imshow("encryption", encryption) cv2.imshow("decryption", decryption) cv2.waitKey() cv2.destroyAllWindows()
本例的各个图像关系如下。
● 图像lena是明文(原始)图像,是需要加密的图像,从当前目录下读入。
● 图像key是密钥图像,是加密和解密过程中所使用的密钥,该图像是由随机数生成的。
● 图像encryption是加密图像,是明文图像lena和密钥图像key通过按位异或运算得到的。
● 图像decryption是解密图像,是加密图像encryption和密钥图像key通过按位异或运算得到的。
运行上述程序,结果如图3-11所示,其中:
![](https://epubservercos.yuewen.com/53BA2F/14737439604468406/epubprivate/OEBPS/Images/Figure-0080-0089.jpg?sign=1739505235-hSw0BF6YTuWaO94lbmrhBoadLJ1MI8dM-0-f1800c6c672ebc74ac4d8fb7ce5d45d8)
图3-11 【例3.14】程序的运行结果
● 图(a)是原始图像lena。
● 图(b)是密钥图像key。
● 图(c)是原始图像lena(图(a))借助密钥key(图(b))加密得到的加密图像encryption。
● 图(d)是对加密图像encryption(图(c))使用密钥图像key(图(b))解密得到的解密图像decryption。