OpenCV图像加密和解密

发布于:2025-04-21 ⋅ 阅读:(14) ⋅ 点赞:(0)

OpenCV计算机视觉开发实践:基于Qt C++ - 商品搜索 - 京东

15.1  图像加密和解密原理

通过按位异或运算可以实现图像的加密和解密。将原始图像与密钥图像进行按位异或可以实现加密;将加密后的图像与密钥图像进行按位异或可以实现解密。

异或运算规则可以描述为:

(1)运算数相同,结果为0;运算数不同,结果为1。

(2)任何数(0或1)与数值0异或,结果仍为自身。

(3)任何数(0或1)与数值1异或,结果变为另外一个数,即0变1,1变0。

(4)任何数(0或1)与自身异或,结果为0。

我们用表15-1来表示。

其中,XOR表示是异或运算符号。比如有两个数198和219,198的二进制形式是1100 0110,219的二进制形式是1101 1011,它们异或后得到的二进制形式是0001 1101,化为十进制数为29。

具体到图像,每个像素点在图像中都可以通过RGB(红绿蓝)三个颜色的组合来表示。若要对图像进行加密处理,通常需要先将其转化为灰度图像。在这一过程中,原本由RGB三个通道构成的像素值会被转换成一个单一的灰度值,其数值范围通常在0到255之间。

举例来说,假设我们有一个像素点的像素值为216(这可以被视作明文信息),我们选取一个数值178作为密钥(这个密钥由加密者自由设定)。通过将这两个数值的二进制形式进行按位异或运算,我们就能够完成加密过程,得到加密后的像素值(即密文)106。

当需要解密时,我们只需再次使用密钥178的二进制形式与密文106进行按位异或运算,即可还原出原始的像素值216(即明文)。

15.2  相关函数

通过图像加解密原理可知,涉及到的主要运算是异或运算,而OpenCV提供了库函数bitwise_xor来实现异或运算功能,其函数声明如下:

void bitwise_xor(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray());

其中,输入参数src1、src2可为灰度图或彩色图,src1和src2大小需一样;参数mask 表示可选操作掩码,可通俗理解为一个遮罩,只对 mask 设定的有效区域进行操作,它是8位单通道。输出参数dst的尺寸和类型与src1保持一致。

下面我们来看一个该函数的实例。

【例15.1】对图片按位异或运算

(1)打开Qt Creator,新建一个控制台项目,项目名称是test。

(2)在main.cpp中输入代码如下:

#include "opencv2/opencv.hpp"
using namespace cv;
int main()
{
      Mat dog,cat,img_and;
      resize(imread("cat.png"),cat, Size(400, 360)); //加载图片并调整尺寸
      resize(imread("dog.png"),dog, Size(400, 360)); //加载图片并调整尺寸
      bitwise_xor(cat,dog,img_and); //异或运算 
      imshow("result",img_and);
      waitKey(0);
      return 0;
 }

注意:加载图片并调整尺寸的目的是为了让两幅图像大小一样,然后再调用异或函数bitwise_xor。

(3)运行程序,运行结果如图15-1所示。

图15-1

15.3  代码实现图像加解密

前面我们讲解了图像加解密的原理和相关函数。下面我们就根据它们,通过代码来实现图像加解密。

【例15.2】实现图像加解密

(1)打开Qt Creator,新建一个控制台项目,项目名称是test。

(2)在main.cpp中输入代码如下:

#include "opencv2/opencv.hpp"
using namespace cv;
int main()
{
    Mat encryption,decryption;
    //读取图像并转为灰度图
    Mat lena = imread("lena.jpg", IMREAD_GRAYSCALE);
    //获取图像的尺寸
    int r=lena.rows;
    int c=lena.cols;
    int type = CV_8UC1;
    // 创建一个用于存储随机数的矩阵,大小和类型与目标矩阵相同
    Mat key(r, c, type);
    // 设置随机数的上下界
    Scalar lowerb = cv::Scalar::all(0); // 最小值
    Scalar upperb = cv::Scalar::all(255); // 最大值
    // 生成随机数填充到矩阵中
    randu(key, lowerb, upperb);
    // 使用异或运算进行加密
    bitwise_xor(lena, key,encryption);
    //使用相同的密钥和异或运算进行解密
    bitwise_xor(encryption, key,decryption);
    //显示原图像、密钥、加密后的图像和解密后的图像
    imshow("Original img", lena);
    imshow("Random Key", key);
    imshow("Encrypted img", encryption);
    imshow("Decrypted img", decryption);
    //等待任意按键按下后关闭所有窗口
    waitKey(0);
    destroyAllWindows();

    return 0;
 }

在上述示例中,首先使用`cv2.imread()`函数加载一个输入图像(假设为名为lena.jpg'的文件)并转为灰度图。然后检查图像是否成功读取,若成功则获取图像尺寸。

接着,生成随机密钥(也就是一个无意义的二维数据),大小与图像一致,数据类型为无符号8位整数。这个密钥不但用于加密,也用于解密,并且加密时候的密钥数据和解密时候都密钥数据要一致,而且平时要保存好,不能让第三方人知道,这种加解密方式成为对称加解密。

通过使用bitwise_xor()函数对图像进行异或操作来实现加密和解密。加密过程将每个像素的颜色值都与255进行按位异或,从而产生加密图像。解密过程与加密过程相同,因为两次按位取反操作可以恢复原始的颜色值。

最后,使用imshow()函数显示原始图像、密钥数据(图像)、加密后的图像和解密后的图像。waitKey(0)等待用户按下任意键关闭窗口,并使用destroyAllWindows()关闭所有窗口。

(3)运行程序,运行结果如图15-2所示。

图15-2

限于篇幅,这里只列出加密后的图像(Encrypted img)和解密后的图像(Decrypted img)。

 


网站公告

今日签到

点亮在社区的每一天
去签到