OpenCV图像加密和解密

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)。

相关推荐
Mintopia30 分钟前
OpenClaw 对软件行业产生的影响
人工智能
陈广亮1 小时前
构建具有长期记忆的 AI Agent:从设计模式到生产实践
人工智能
会写代码的柯基犬1 小时前
DeepSeek vs Kimi vs Qwen —— AI 生成俄罗斯方块代码效果横评
人工智能·llm
Mintopia2 小时前
OpenClaw 是什么?为什么节后热度如此之高?
人工智能
爱可生开源社区2 小时前
DBA 的未来?八位行业先锋的年度圆桌讨论
人工智能·dba
叁两5 小时前
用opencode打造全自动公众号写作流水线,AI 代笔太香了!
前端·人工智能·agent
前端付豪5 小时前
LangChain记忆:通过Memory记住上次的对话细节
人工智能·python·langchain
strayCat232555 小时前
Clawdbot 源码解读 7: 扩展机制
人工智能·开源
王鑫星5 小时前
SWE-bench 首次突破 80%:Claude Opus 4.5 发布,Anthropic 的野心不止于写代码
人工智能