摘要:其實(shí)隱藏文件和盲水印都屬于圖片隱寫(xiě)術(shù)。圖片隱寫(xiě)術(shù)隱寫(xiě)術(shù)也是數(shù)字水印的一種應(yīng)用,雙方可利用隱藏在數(shù)字信號(hào)中的信息進(jìn)行溝通。圖片隱寫(xiě)術(shù)只是其中一種,有興趣的同學(xué)可以看下面這本書(shū)。
首先看 這是一張女朋友
接下來(lái)我們輸入一行神奇的命令:
python bwm.py --action decode --origin Demo.jpg --im ../Gakki.jpg --result res.jpg
可以得到這樣的一張圖:
以后誰(shuí)再跟你搶女朋友就可以這樣聲明版權(quán)了嘿嘿.
(腳本和原圖都在最后的附錄里 有興趣的朋友只需要將上面的圖片保存為Demo.jpg
附錄里的原圖保存為Gakki.jpg
就可以解碼出上面的信息)
通過(guò)今天的方法你可以將信息放入任意圖片來(lái)達(dá)到加密信息的目的.
附錄里的腳本 加密用法:
python bwm.py --action encode --origin Gakki.jpg --im wm1.png --result Demo.jpg --alpha 2
上面 的水印就叫做盲水印,隱藏式的水印是以數(shù)字?jǐn)?shù)據(jù)的方式加入音頻、圖片或影片中,但在一般的狀況下無(wú)法被看見(jiàn)。隱藏式水印的重要應(yīng)用之一是保護(hù)版權(quán),期望能借此避免或阻止數(shù)字媒體未經(jīng)授權(quán)的復(fù)制和拷貝。
聲明版權(quán)
應(yīng)用案例:
13年左右有位自稱(chēng)是“超寫(xiě)實(shí)主義”的畫(huà)家,聲稱(chēng)自己純手工畫(huà)的畫(huà)寫(xiě)實(shí)程度可以超過(guò)攝影機(jī),并開(kāi)辦培訓(xùn)班斂財(cái)。
后被一位加了盲水印的攝影師戳穿,原來(lái)其“畫(huà)作”都是直接將照片用ps處理成手繪質(zhì)感的圖。
淘寶賣(mài)家圖會(huì)被淘寶自動(dòng)打上水印,如果有別的賣(mài)家存圖作為自己的圖上傳會(huì)被檢測(cè)出。
將某份保密數(shù)字資料發(fā)送給不同人時(shí),可加上不同標(biāo)識(shí),如果資料被復(fù)制、傳播可根據(jù)解碼出的唯一標(biāo)識(shí)來(lái)追究責(zé)任人。
應(yīng)用案例:
比如著名的“阿里月餅門(mén)”。
傅里葉變換簡(jiǎn)單地說(shuō)就是將信號(hào)在時(shí)域或空域的函數(shù)轉(zhuǎn)變到頻域表示,在和工程學(xué)中有許多應(yīng)用。因其基本思想首先由法國(guó)學(xué)者約瑟夫·傅里葉系統(tǒng)地提出。
那么,傅里葉變換有什么用呢,
現(xiàn)在把sin(3x)+sin(5x)的曲線(xiàn)給你,只看圖是看不出這整個(gè)曲線(xiàn)的方程式是怎樣的,現(xiàn)在需要將把sin(5x)從圖里拿出去,看看剩下的是什么。這基本是不可能做到的。
但是在頻域呢?則簡(jiǎn)單的很,無(wú)非就是幾條豎線(xiàn)而已。
這是最簡(jiǎn)單的一種用法,其他復(fù)雜用法不在此贅述。
一維信號(hào)的變換理解之后,那么圖像的頻譜圖長(zhǎng)什么樣呢。
圖片中明亮的部分就是低頻(平緩)部分,暗點(diǎn)的是高頻(突變交界)部分。一般為了展示會(huì)把頻譜圖低頻的部分移到中心。頻譜圖上的點(diǎn)跟原圖不存在一一對(duì)應(yīng)關(guān)系,頻譜圖的每一點(diǎn)都來(lái)自于全部的圖像(類(lèi)似于時(shí)域曲線(xiàn)的點(diǎn),和頻域圖的點(diǎn))。
這樣可能還不夠直觀(guān),接下來(lái)看這張圖。
這是一張400x400的圖,共有16 萬(wàn)個(gè)像素點(diǎn)。
我們平時(shí)怎么來(lái)表示一張圖片呢,首先是在笛卡爾坐標(biāo)系中用xy來(lái)定位某一確定的點(diǎn)。那么,我們?cè)趺磥?lái)描述這個(gè)點(diǎn)呢?
我們知道,所有的色彩都是由三原色組成。生活中經(jīng)常說(shuō)的紅、黃、藍(lán)(青),其實(shí)是一種消減型的三原色,光學(xué)中的三原色是紅、綠、藍(lán),也就是R、G、B。
通常我們用來(lái)描述圖像點(diǎn)的方法就是RGB的值,其實(shí)圖像處理中用的是灰度(Gray scale)來(lái)表示圖片,但是為了便于理解,下面用的是RGB演示 。
上圖是截取了某一行RGB的值做成的曲線(xiàn)圖,可以看到,每條曲線(xiàn)都在不停的上下波動(dòng),且波動(dòng)的頻率是相同的。有些區(qū)域的波動(dòng)比較小,有些區(qū)域突然出現(xiàn)了大幅波動(dòng)。
對(duì)比一下圖像就能發(fā)現(xiàn),曲線(xiàn)波動(dòng)較大的地方,也是圖像出現(xiàn)突變的地方。
圖像的頻譜可以理解為將一維的頻譜繞著縱軸旋轉(zhuǎn)一圈,形成一個(gè)3維的數(shù)學(xué)函數(shù)圖(原圖中心對(duì)稱(chēng)、鏡像對(duì)稱(chēng)才可以這樣干,其他類(lèi)似),x、y軸代表兩個(gè)方向的頻率,z軸代表該頻率的幅值,只不過(guò)頻譜圖像是一個(gè)2維圖,所以用亮度來(lái)表示幅值了。
二維傅里葉變換的物理意義是將圖像的灰度分布函數(shù)變換為圖像的頻率分布函數(shù)。
魯棒性一般要能抗(壓縮 、裁剪、涂畫(huà),旋轉(zhuǎn))。
由于不希望被察覺(jué)、不希望干擾用戶(hù)體驗(yàn)、不希望被模仿等等原因,我們的水印不可見(jiàn),也就是隱匿性。
不易移除性跟魯棒性有些相似, 不同的是:
魯棒性更加強(qiáng)調(diào)的是數(shù)字資源在傳播過(guò)程中不要被不自覺(jué)地干擾和破壞。
不易移除性是在別有用心者察覺(jué)了盲水印的存在后,不被他們自覺(jué)地移除或者破壞。
強(qiáng)健性通常也被稱(chēng)作魯棒性,來(lái)自于其英文名稱(chēng)(Robustness)的音譯。
簡(jiǎn)單地說(shuō)就是耐操性。
需要說(shuō)明的一點(diǎn)是,魯棒性和隱蔽性通常不可兼得。
沒(méi)什么可說(shuō)的,就是盲水印需要表示出明確的信息。
例如這是一張相貌平平的圖片 你可以保存下來(lái)將后綴改為"rar"或者直接用解壓工具打開(kāi)就可以看到神秘福利.
|??ω?` )
制作方法也很簡(jiǎn)單在win下 入以下命令就可以做一張"圖種"了.
copy /b A.jpg + B.zip C.jpg
大約十年以前,圖種被廣泛上傳到論壇等地用來(lái)傳播資源。后來(lái)由于許多網(wǎng)站在上傳圖片時(shí)會(huì)判斷圖片結(jié)尾標(biāo)識(shí),其之后的全部丟棄,慢慢不再有人使用。(https://sm.ms/這個(gè)圖床還是很給力的 經(jīng)測(cè)試還是可以解析種子)
圖片可以跟種子文件結(jié)合,當(dāng)然也可以和其他文件結(jié)合。
其實(shí)隱藏文件和盲水印都屬于圖片隱寫(xiě)術(shù)。
隱寫(xiě)術(shù)(Steganography)也是數(shù)字水印的一種應(yīng)用,雙方可利用隱藏在數(shù)字信號(hào)中的信息進(jìn)行溝通。
數(shù)字照片中的注釋數(shù)據(jù)能記錄照片拍攝的時(shí)間、使用的光圈和快門(mén),甚至是相機(jī)的廠(chǎng)牌等信息,這也是數(shù)字水印的應(yīng)用之一。
某些文件格式可以包含這些稱(chēng)為“me
? 所謂的“敏感詞過(guò)濾”,常翻墻的同學(xué),應(yīng)該都很熟悉了。用圖片來(lái)隱藏信息,可以規(guī)避GFW的敏感詞過(guò)濾。
? 國(guó)內(nèi)的很多網(wǎng)站,對(duì)于上傳的圖片,都會(huì)進(jìn)行人工審查。如果能通過(guò)技術(shù)手段把信息隱藏在圖片中,而圖片本身又看不出什么異樣,人工審核就看不出來(lái)。
? 不希望被別人看到的資料、信息等。
通常來(lái)說(shuō),圖片文件都有包含2部分:文件頭和數(shù)據(jù)區(qū)。
而“內(nèi)容覆蓋法”,就是把要隱藏的文件,直接【覆蓋】到圖片文件的【數(shù)據(jù)區(qū)】的【尾部】。
比方說(shuō),某圖片有 100KB,其中文件頭占 1KB,那么,數(shù)據(jù)區(qū)就是 99KB。也就是說(shuō),最多只能隱藏 99KB 的文件。
切記:覆蓋的時(shí)候,千萬(wàn)不可破壞文件頭。文件頭一旦破壞,這個(gè)圖片文件就不再是一個(gè)合法的圖片文件了。
使用這種方法,對(duì)圖片文件的格式,是有講究的——最好用【24位色的 BMP 格式】。
import sys
def embed(container_file data_file output_file) :
"""代碼沒(méi)有嚴(yán)格計(jì)算 BMP 的文件頭尺寸,只是大致預(yù)留了 1024 字節(jié)"""
container = open(container_file "rb").read()
data = open(data_file "rb").read()
if len(data)+1024 >= len(container) :
print("Not enough space to save " + data_file)
else :
f = open(output_file "wb")
f.write(container[ : len(container)-len(data)])
f.write(data)
f.close()
if "__main__" == __name__ :
try :
if len(sys.argv) == 4 :
embed(sys.argv[1] sys.argv[2] sys.argv[3])
else :
print("Usage:n%s container data output" % sys.argv[0])
except Exception as err :
print(err)
很多商業(yè)軟件使用的原理都是這個(gè)方法。
例如在PNG圖片的儲(chǔ)存中,每個(gè)顏色會(huì)有8bit,LSB(Least Significant Bit)隱寫(xiě)就是修改了像數(shù)中的最低的1bit,在人眼看來(lái)是看不出來(lái)區(qū)別的,也把信息隱藏起來(lái)了。(每個(gè)像數(shù)可以攜帶3bit的信息。)
譬如我們想把’A’隱藏進(jìn)來(lái)的話(huà),如下圖,就可以把A轉(zhuǎn)成16進(jìn)制的0x61再轉(zhuǎn)成二進(jìn)制的01100001,再修改為紅色通道的最低位為這些二進(jìn)制串。
(參考了幾個(gè)git hub上的項(xiàng)目不過(guò)魯棒性都不太好)
ALPHA = 5
class BlindWaterMark(): """盲水印加解密,無(wú)頻移簡(jiǎn)單版""" def **init**(self): self.parser = ArgumentParser() self.parser.add_argument(--action dest=action required=True) self.parser.add_argument(--origin dest=ori required=True) self.parser.add_argument(--img dest=img required=True) self.parser.add_argument(--result dest=res required=True) self.parser.add_argument(--alpha dest=alpha default=ALPHA)
def encode(self ori_path wm_path res_path alpha):
img = cv2.imread(ori_path)
img_f = np.fft.fft2(img) # 2維離散傅里葉變換
height width channel = np.shape(img)
watermark = cv2.imread(wm_path)
wm_height wm_width = watermark.shape[0] watermark.shape[1]
# 水印隨機(jī)編碼
x y = range(height / 2) range(width)
random.seed(height + width) # 隨機(jī)數(shù)解碼時(shí)可控
random.shuffle(x)
random.shuffle(y)
# 按目標(biāo)圖片大小 對(duì)水印圖進(jìn)行對(duì)稱(chēng)
tmp = np.zeros(img.shape) # 根據(jù)圖片形狀,生成0填充的矩陣
for i in range(height / 2):
for j in range(width):
if x[i] < wm_height and y[j] < wm_width:
tmp[i][j] = watermark[x[i]][y[j]]
tmp[height - 1 - i][width - 1 - j] = tmp[i][j]
res_f = img_f + alpha * tmp # 原圖頻域值 + 水印頻域值
res = np.fft.ifft2(res_f) # 傅里葉逆變換
res = np.real(res) # 轉(zhuǎn)換為實(shí)數(shù)
cv2.imwrite(res_path res [int(cv2.IMWRITE_JPEG_QUALITY) 100])
def decode(self ori_path img_path res_path alpha):
ori = cv2.imread(ori_path)
img = cv2.imread(img_path)
ori_f = np.fft.fft2(ori)
img_f = np.fft.fft2(img)
height width = ori.shape[0] ori.shape[1]
watermark = (ori_f - img_f) / alpha
watermark = np.real(watermark)
res = np.zeros(watermark.shape)
random.seed(height + width)
x = range(height / 2)
y = range(width)
random.shuffle(x)
random.shuffle(y)
for i in range(height / 2):
for j in range(width):
res[x[i]][y[j]] = watermark[i][j]
res[height - i - 1][width - j - 1] = res[i][j]
cv2.imwrite(res_path res [int(cv2.IMWRITE_JPEG_QUALITY) 100])
def run(self):
options = self.parser.parse_args()
action = options.action
ori = options.ori
img = options.img
res = options.res
alpha = float(options.alpha)
if not os.path.isfile(ori):
parser.error("image %s does not exist." % ori)
if not os.path.isfile(img):
parser.error("watermark %s does not exist." % img)
if action == "encode":
self.encode(ori img res alpha)
elif action == "decode":
self.decode(ori img res alpha)
if **name** == **main**: bwm = BlindWaterMark() bwm.run()
2.隱寫(xiě)術(shù)是一門(mén)很深、應(yīng)用很廣泛的學(xué)問(wèn),這里講的很泛,權(quán)當(dāng)做拋磚引玉。圖片隱寫(xiě)術(shù)只是其中一種,有興趣的同學(xué)可以看下面這本書(shū)。
本文作者:UCloud后臺(tái)研發(fā)工程師 Hughes Chen
博客地址:https://ulyc.github.io/
您也可以關(guān)注知乎官方技術(shù)課堂https://www.zhihu.com/column/ucloud 查看更多技術(shù)干貨!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/126014.html
摘要:作者微信公眾號(hào)的皮卡丘歡迎大家搜索關(guān)注知乎圖像類(lèi)畫(huà)畫(huà)實(shí)現(xiàn)手寫(xiě)筆記的壓縮與增強(qiáng)實(shí)現(xiàn)簡(jiǎn)單的車(chē)牌檢測(cè)算法類(lèi)實(shí)現(xiàn)版貪吃蛇實(shí)現(xiàn)五子棋初版信息安全類(lèi)簡(jiǎn)單實(shí)現(xiàn)隱寫(xiě)術(shù)使用破解滑塊驗(yàn)證碼其他制作簡(jiǎn)易瀏覽器實(shí)現(xiàn)浪漫表白實(shí)現(xiàn)地理信息可視化簡(jiǎn)單分析高考數(shù)據(jù)制作簡(jiǎn)易 作者:Charles微信公眾號(hào):Charles的皮卡丘(歡迎大家搜索關(guān)注)知乎:https://zhuanlan.zhihu.com/p/... ...
閱讀 3546·2023-04-25 20:09
閱讀 3745·2022-06-28 19:00
閱讀 3066·2022-06-28 19:00
閱讀 3092·2022-06-28 19:00
閱讀 3185·2022-06-28 19:00
閱讀 2886·2022-06-28 19:00
閱讀 3057·2022-06-28 19:00
閱讀 2643·2022-06-28 19:00