Python實現(xiàn)在圖像中隱藏二維碼的方法詳解
一、前言
在某個App中有一個加密水印的功能,當(dāng)帖子的主人開啟了之后。如果有人截圖,那么這張截圖中就是添加截圖用戶、帖子ID、截圖時間等信息,而且我們無法用肉眼看出這些水印。
這可以通過今天要介紹的隱寫技術(shù)來實現(xiàn),我們會通過這種技術(shù),借助Python語言和OpenCV模塊來實現(xiàn)在圖像中隱藏二維碼的操作。而且這個二維碼無法通過肉眼看出。
二、隱寫
隱寫是一種類似于加密卻又不同于加密的技術(shù)。通常情況下,加密是對數(shù)據(jù)本身進行一個轉(zhuǎn)換,得到的結(jié)果是一堆人無法解讀的數(shù)據(jù),比如“你好”進行md5加密后的結(jié)果是“7eca689f0d3389d9dea66ae112e5cfd7”,如果光看“7eca689f0d3389d9dea66ae112e5cfd7”我們不知道內(nèi)容,但是我們知道這應(yīng)該是加密后的數(shù)據(jù)。隱寫的目的同樣是讓只有接收方才能獲取數(shù)據(jù),但是隱寫通常更加隱蔽,隱寫更注重于不讓第三方知道我發(fā)送的數(shù)據(jù)中有額外信息。
就像我們在電影中經(jīng)??吹降囊恍﹦∏?,一場看似普通的對話卻隱含了許多外人不知道的信息,這實際上就是一種隱寫。再比如“This is a pig”,看上去像一個普通的句子,如果通信雙方規(guī)定“T、i、s”這些占三線格上兩個的字母表示0,而“p、g”這種占三線格下兩格的字母表示1,那么這句話就可以翻譯成“0000000101”。而今天我們要介紹的是“最低有效位”隱寫。
三、位平面分解
在介紹“最低有效位”隱寫之前,需要了解一些圖像相關(guān)的知識。這里包括數(shù)字圖像、位平面、位平面分解。
3.1 圖像
在計算機中,圖像被表示為一個數(shù)字矩陣,每個數(shù)字被稱為一個像素,它們的取值在[0, 255]區(qū)間,可以用8個二進制來表示。
這個矩陣大小由圖像分辨率決定,如果是480×480分辨率的圖像,那么這個矩陣大小就是480×480。如果是彩色圖像,會用三個大小相同的矩陣合起來表示,它們分別表示圖像R(紅色)、G(綠色)、B(藍色)的程度,也就是俗稱的RGB圖像。
我們可以用OpenCV來讀取圖像,OpenCV的安裝如下:
pip install opencv-python
安裝完成后就可以讀取圖像:
# 導(dǎo)入模塊
import cv2
# 讀取圖像
img = cv2.imread('test.jpg')
# 輸出圖像
print(img)
其中test.jpg就是我們的圖像名稱或者圖像路徑。上面代碼輸出結(jié)果如下:
[[[ 72 220 234]
[ 72 220 234]
[ 73 221 235]
...
[ 87 147 176]
[ 87 147 176]
[ 87 147 176]]]
因為輸出過長,這里省略了一部分內(nèi)容。
3.2 位平面
在前面我們說了一個圖像是一個數(shù)字矩陣,比如:
[[2, 2]
[3, 4]]
我們可以理解為一張簡單的圖像,現(xiàn)在我們把圖像的像素值寫成二進制形式:
[[0000 0010, 0000 0010],
[0000 0011, 0000 0100]]
我們把四個像素的最高位取出,得到新的圖像:
[[0, 0]
[0, 0]]
這個過程的圖示如下:

這里取出來的圖像就叫位平面,因為是取出第7位(從左到右依次是7-0)組成的圖像,所以叫第7位平面,也叫最高位平面。而第0位平面也叫“最低有效位”位平面。
如果取出第1位,得到的圖像為:
[[1, 1],
[1, 0]]
這個圖像叫第1位平面。這里需要注意一點,就是每個位平面的實際值應(yīng)該乘一個權(quán)重,這個權(quán)重位i2,即第7位平面的權(quán)重位72。
3.3 位平面分解
下面我們看看如何分解位平面,分解位平面可以用cv2.bitwise_and函數(shù)來實現(xiàn)。我們需要傳入一個圖像以及一個分解因子,各個位平面的分解因子如下:
| 分解因子 | 作用 |
|---|---|
| 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。我們只需要將各個位平面乘上對應(yīng)的權(quán)重,然后相加就能恢復(fù)原圖,即:

如果我們只對M1-M7進行合成,得到的A`與A的差距最多為1,因此我們可以讓A`≈A。此時圖像A`的第0個位平面可以用于隱藏數(shù)據(jù)。
四、圖像隱寫
這里我們使用一種叫“最低有效位”位平面隱寫的技術(shù)來實現(xiàn)二維碼的隱藏。其原理就是把圖像“最低有效位”位平面設(shè)置為0,此時圖像與原圖像像素相差最大為0,人肉眼無法看出區(qū)別。然后我們可以在圖像的最低有效位任意設(shè)置值,此時圖像與原圖像素相差最大仍是1。這樣我們就可以用“最低有效位”位平面來隱寫數(shù)據(jù)。
在前面我們合成原圖時用M1-M7,而M0位平面則全為0,這時我們可以用最低有效位存儲數(shù)據(jù)。假如我們的數(shù)據(jù)矩陣為M,該矩陣為一個0-1矩陣。而二維碼就是一個黑白矩陣,我們可以把黑當(dāng)作0,白當(dāng)作1,這樣我們讓M為一個二維碼的矩陣?,F(xiàn)在我們通過下面的公式來合成:

這個A就是帶有隱寫信息的圖像。代碼實現(xiàn)如下:
import cv2
# ①讀取圖像
img = cv2.imread('test.jpg', 0)
# ②把最低有效位清空
img -= cv2.bitwise_and(img, 0x01)
# ③準(zhǔn)備需要隱寫的信息M
M = cv2.imread('qrcode.jpg', 0)
M = cv2.resize(M, img.shape)
# 把二維碼轉(zhuǎn)換成0-1矩陣
_, M = cv2.threshold(M, 30, 1, cv2.THRESH_BINARY)
# ④將要隱寫的數(shù)據(jù)設(shè)置到圖像最低有效位
img += M
# ⑥以無損的方式保存隱寫后的
cv2.imwrite('dst.png', img, [int(cv2.IMWRITE_JPEG_QUALITY), 100])
最后保存的dst.png就是我們隱寫后的圖像。
二維碼的生成可以參考詳解Python如何生成優(yōu)雅的二維碼
到此這篇關(guān)于Python實現(xiàn)在圖像中隱藏二維碼的方法詳解的文章就介紹到這了,更多相關(guān)Python圖像隱藏二維碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決Python中回文數(shù)和質(zhì)數(shù)的問題
今天小編就為大家分享一篇解決Python中回文數(shù)和質(zhì)數(shù)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11
Python中*args和**kwargs的區(qū)別詳解
這篇文章主要介紹了Python中*args和**kwargs的區(qū)別詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-09-09
Python項目打包成apk或者其他端的應(yīng)用程序
本文主要介紹了使用Kivy和Buildozer將Python項目打包成Android APK文件的步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-11-11
Python實現(xiàn)的數(shù)據(jù)結(jié)構(gòu)與算法之基本搜索詳解
這篇文章主要介紹了Python實現(xiàn)的數(shù)據(jù)結(jié)構(gòu)與算法之基本搜索,詳細分析了Python順序搜索、二分搜索的使用技巧,非常具有實用價值,需要的朋友可以參考下2015-04-04
pytorch實現(xiàn)seq2seq時對loss進行mask的方式
今天小編就為大家分享一篇pytorch實現(xiàn)seq2seq時對loss進行mask的方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02
Python數(shù)據(jù)分析之?Matplotlib?散點圖繪制
這篇文章主要介紹了Python數(shù)據(jù)分析之?Matplotlib?散點圖繪制,散點圖又稱散點圖,是使用多個坐標(biāo)點的分布反映數(shù)據(jù)點分布規(guī)律、數(shù)據(jù)關(guān)聯(lián)關(guān)系的圖表,下文對散點圖的詳細介紹及繪制,需要的小伙伴可以參考以一下2022-05-05
Python 經(jīng)典貪心算法之Prim算法案例詳解
這篇文章主要介紹了Python 經(jīng)典貪心算法之Prim算法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-09-09
Python學(xué)習(xí)之a(chǎn)syncore模塊用法實例教程
這篇文章主要介紹了Python學(xué)習(xí)之a(chǎn)syncore模塊用法,主要講述了asyncore模塊的組成、原理及相關(guān)函數(shù)的用法,對于使用Python進行網(wǎng)絡(luò)編程來說非常實用,需要的朋友可以參考下2014-09-09

