我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python实现在图像中隐藏二维码的方法详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python实现在图像中隐藏二维码的方法详解

一、前言

在某个App中有一个加密水印的功能,当帖子的主人开启了之后。如果有人截图,那么这张截图中就是添加截图用户、帖子ID、截图时间等信息,而且我们无法用肉眼看出这些水印。

这可以通过今天要介绍的隐写技术来实现,我们会通过这种技术,借助Python语言和OpenCV模块来实现在图像中隐藏二维码的操作。而且这个二维码无法通过肉眼看出。

二、隐写

隐写是一种类似于加密却又不同于加密的技术。通常情况下,加密是对数据本身进行一个转换,得到的结果是一堆人无法解读的数据,比如“你好”进行md5加密后的结果是“7eca689f0d3389d9dea66ae112e5cfd7”,如果光看“7eca689f0d3389d9dea66ae112e5cfd7”我们不知道内容,但是我们知道这应该是加密后的数据。隐写的目的同样是让只有接收方才能获取数据,但是隐写通常更加隐蔽,隐写更注重于不让第三方知道我发送的数据中有额外信息。

就像我们在电影中经常看到的一些剧情,一场看似普通的对话却隐含了许多外人不知道的信息,这实际上就是一种隐写。再比如“This is a pig”,看上去像一个普通的句子,如果通信双方规定“T、i、s”这些占三线格上两个的字母表示0,而“p、g”这种占三线格下两格的字母表示1,那么这句话就可以翻译成“0000000101”。而今天我们要介绍的是“最低有效位”隐写。

三、位平面分解

在介绍“最低有效位”隐写之前,需要了解一些图像相关的知识。这里包括数字图像、位平面、位平面分解。

3.1 图像

在计算机中,图像被表示为一个数字矩阵,每个数字被称为一个像素,它们的取值在[0, 255]区间,可以用8个二进制来表示。

这个矩阵大小由图像分辨率决定,如果是480×480分辨率的图像,那么这个矩阵大小就是480×480。如果是彩色图像,会用三个大小相同的矩阵合起来表示,它们分别表示图像R(红色)、G(绿色)、B(蓝色)的程度,也就是俗称的RGB图像。

我们可以用OpenCV来读取图像,OpenCV的安装如下:

pip install opencv-python

安装完成后就可以读取图像:

# 导入模块
import cv2
# 读取图像
img = cv2.imread('test.jpg')
# 输出图像
print(img)

其中test.jpg就是我们的图像名称或者图像路径。上面代码输出结果如下:

[[[ 72 220 234]
  [ 72 220 234]
  [ 73 221 235] 
  ...
  [ 87 147 176]
  [ 87 147 176]
  [ 87 147 176]]]

因为输出过长,这里省略了一部分内容。

3.2 位平面

在前面我们说了一个图像是一个数字矩阵,比如:

[[2, 2]
[3, 4]]

我们可以理解为一张简单的图像,现在我们把图像的像素值写成二进制形式:

[[0000 0010, 0000 0010],
[0000 0011, 0000 0100]]

我们把四个像素的最高位取出,得到新的图像:

[[0, 0]
[0, 0]]

这个过程的图示如下:

这里取出来的图像就叫位平面,因为是取出第7位(从左到右依次是7-0)组成的图像,所以叫第7位平面,也叫最高位平面。而第0位平面也叫“最低有效位”位平面。

如果取出第1位,得到的图像为:

[[1, 1],
[1, 0]]

这个图像叫第1位平面。这里需要注意一点,就是每个位平面的实际值应该乘一个权重,这个权重位i2,即第7位平面的权重位72。

3.3 位平面分解

下面我们看看如何分解位平面,分解位平面可以用cv2.bitwise_and函数来实现。我们需要传入一个图像以及一个分解因子,各个位平面的分解因子如下:

分解因子作用
0x80分解第7位平面
0x40分解第6位平面
0x20分解第5位平面
0x10分解第4位平面
0x08分解第3位平面
0x04分解第2位平面
0x02分解第1位平面
0x11分解第0位平面

比如分解第7位平面的操作为:

import cv2
# 读取图像
img = cv2.imread('test.jpg', 0)
# 分解第7位平面
layer = cv2.bitwise_and(img, 0x80)

其它位平面的分解只需要对照表进行修改即可。

3.4 位平面合成

假如我们以及分解出来8个位平面,分别是M0、M1、…、M7。我们只需要将各个位平面乘上对应的权重,然后相加就能恢复原图,即:

如果我们只对M1-M7进行合成,得到的A`与A的差距最多为1,因此我们可以让A`≈A。此时图像A`的第0个位平面可以用于隐藏数据。

四、图像隐写

这里我们使用一种叫“最低有效位”位平面隐写的技术来实现二维码的隐藏。其原理就是把图像“最低有效位”位平面设置为0,此时图像与原图像像素相差最大为0,人肉眼无法看出区别。然后我们可以在图像的最低有效位任意设置值,此时图像与原图像素相差最大仍是1。这样我们就可以用“最低有效位”位平面来隐写数据。

在前面我们合成原图时用M1-M7,而M0位平面则全为0,这时我们可以用最低有效位存储数据。假如我们的数据矩阵为M,该矩阵为一个0-1矩阵。而二维码就是一个黑白矩阵,我们可以把黑当作0,白当作1,这样我们让M为一个二维码的矩阵。现在我们通过下面的公式来合成:

这个A就是带有隐写信息的图像。代码实现如下:

import cv2
# ①读取图像
img = cv2.imread('test.jpg', 0)
# ②把最低有效位清空
img -= cv2.bitwise_and(img, 0x01)
# ③准备需要隐写的信息M
M = cv2.imread('qrcode.jpg', 0)
M = cv2.resize(M, img.shape)
# 把二维码转换成0-1矩阵
_, M = cv2.threshold(M, 30, 1, cv2.THRESH_BINARY)
# ④将要隐写的数据设置到图像最低有效位
img += M
# ⑥以无损的方式保存隐写后的
cv2.imwrite('dst.png', img, [int(cv2.IMWRITE_JPEG_QUALITY), 100])

最后保存的dst.png就是我们隐写后的图像。

二维码的生成可以参考详解Python如何生成优雅的二维码

到此这篇关于Python实现在图像中隐藏二维码的方法详解的文章就介绍到这了,更多相关Python图像隐藏二维码内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python实现在图像中隐藏二维码的方法详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

java实现识别二维码图片功能方法详解与实例源码

这篇文章主要介绍了java实现识别二维码图片,java无法识别二维码情况下对二维码图片调优功能方法与实例源码,需要的朋友可以参考下
2022-12-10

Python实现在Excel中绘制可视化大屏的方法详解

今天小编来给大家分享如何在Excel文档当中来绘制可视化图表,并且制作一个可视化大屏。文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
2023-01-29

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录