变换域信息隐藏--DCT
思想提出背景–空間域隱藏
空間域隱藏是基于位圖分解的思想產生的,其主要方法是將秘密信息存儲到載體不那么重要的部分中,這樣即使改變了載體的部分信息后,載體從肉眼來看也不會有太大區別。這種隱藏方法的優點是容量大,肉眼很難識別;但是缺點是直接隱藏了秘密信息,而且存儲信息區域過于連續,容易造成載體統計特性的改變,而且因為信息存儲在載體的最低有效位,在傳輸過程中很容易被一些壓縮算法破壞。針對上述問題,研究者嘗試將信息放在相對重要的的部位中,在不影響載體完整性的前提下盡可能將信息隱藏到低頻系數中去。
變換域學習中的一些小想法
變換域替換是將秘密信息存儲至載體相對重要的區域來規避壓縮算法和一些破壞行為,變換域替換包括DCT,傅里葉算法和小波變換,本文將主要介紹DCT算法。
其算法比較復雜,涉及的數學知識也比較多,就也不做詳細介紹。有一點值得分享一下。傅里葉算法是高數中的一個知識點,其思想是將一個波分解為多個正余弦波的合,聽起來好像沒什么意思,但是這種算法我們在生活中每時每刻都在使用。比如我們到菜市場,有人的喧鬧聲,車聲,叫賣聲,我們接收的是雜亂無序的的音波,我們是如何分辨出他們的呢?
這就是傅里葉變換的應用,接收這些聲波后,我們的大腦作快速傅里葉變換,將雜亂無序的波分解為多個波之和,大腦直接過濾掉不需要的波后,我們就能接收到想要的信息了,很神奇的方法不是嗎。
學計算機越久,越懷疑世界的真實性,萬物皆可編程的時代,我們看似一些神奇和自然的現象都可以用數學和計算知識來解釋。程序世界的運轉依賴與程序員設定的各項常量變量,三十萬千米每秒,6.2607015×10-34 J·s的普朗克常數,G=6.67259×10-11N·m2/kg2的引力常量,這些又是誰設置的常量呢。我們的一切感知都是大腦告訴我們的,現在的科學已經能通過電信號來模擬大腦的一些活動,那我們又如何確定自己所處的是真實的世界呢,或許真實的世界中我們只是一個個培養瓶中的大腦,不斷接受外部信號刺激來給我們造成各種經歷的感受 黑客帝國既視感:),感覺科學的盡頭是神學還是有一點道理。
DCT變換域隱藏
言歸正傳,目前的主流隱藏方法,且兼顧效率與隱蔽性的算法是基于離散余弦變換的信息隱藏算法(DCT),該算法涉及比較復雜的數學知識,只能簡要說下其原理:離散余弦變換是將圖像由空間域轉化到頻率域上,將圖像計算為二維余弦波,從效果來說是將圖像計算為一個DCT系數矩陣,該矩陣代表圖像的頻率分布,頻率低的為圖像中相對重要的主體信息,高頻則是圖像的一些細節,但該矩陣中的像素與圖像像素不存在一一對應關系。 然后將秘密信息根據自己的算法隱藏到DCT系數中即可,隱藏位置多選擇中頻區域,是在透明性和魯棒性之間做了折中的選擇。
本文設計的算法是利用dct系數的相對變化存儲10信息(可用該10信息代表黑白,即可嵌入圖片)。
引用一張覺得很不錯關于域的分解圖
變換域隱藏借助python的實現很簡單,只需一句代碼
img_dct=cv2.dct('打開的文件‘)
使用需要注意兩點,打開的文件需要以灰度圖像打開,而且需要將其轉為float類型。示例如下:
img=cv2.imread(’文件路徑',cv2.IMREAD_GRAYSCALE)
img1=img.astype('float')
基于變換域的壓縮方法
變換域的思想在壓縮領域應用相當廣泛,下載的專輯可能一首歌要幾十M,但是同樣的mp3格式就可能只要3-4M,而且大部分人可能很難聽出其中區別,這就是利用了變換域的方法,壓縮掉細節和不那么重要的高頻部分。
壓縮代碼示例如下:
效果對比如下:
保留像素0-300
保留像素100-400
可以看到保留相同數量的像素,僅僅是范圍后移了100就有如此大的差別,同時也驗證了圖像主要部分存儲在低頻系數內,而300像素點就能基本保存一張1920*1080圖片的主題,也說明了基于變換域的壓縮算法效率是相當高的。
信息嵌入
DCT信息隱藏的手段主要是將秘密信息以一定方式隱藏到DCT系數中,方法不限于直接嵌入到float的最后幾位,還有通過系數的奇偶存儲,比較特定位置上兩個系數的大小等,變換域信息隱藏是我最喜歡的信息隱藏方法,沒有之一,因為這中隱寫方法的高明之處在于不把信息直接隱藏到載體中,而是通過自行約定的一種算法,并且秘密信息在載體中沒有絲毫體現。這個特性使得檢測者即使拿到載體圖片,甚至分析出了其中含有秘密信息也很難破解其中的具體信息。DCT信息隱藏中,信息隱寫,隱寫算法,明文加密,三者同時保證了秘密信息的安全性。
問題
但是在信息嵌入的時候有幾個點需要注意:
1.嵌入位置: DCT信息隱藏的思想是將秘密信息存儲到相對重要的區域,防止被一些針對高頻的圖像壓縮算法破壞,所以信息具體的隱藏位置出于不同目的會有不同選擇。
2.嵌入算法: 由于DCT信息隱藏是將秘密信息存儲到圖像的DCT系數中,那么系數的變化規則應當本著對載體修改盡可能小,秘密信息盡可能隱蔽的原則來實現。
3.抗分析: 雖然信息隱寫學科發展時間較短,但是針對目前隱寫算法也有了很多行之有效的分析方法。其中對于DCT隱寫分析威脅最大的應該就是卡方檢測了,基于統計分析實現簡單,導致其門檻較低而應用廣泛,準確率又相對較高。所以如何有效對抗統計分析是DCT信息隱寫面臨比較嚴峻的問題。
分析及解決
1.信息嵌入位置:
如果修改低頻部分,容易看出變化,隱蔽性較差;如果修改高頻部分,雖然邊緣輪廓替換不容易被識別,但是容易被處理高頻的壓縮算法破壞,魯棒性比較差。所以最好采用折中方案—修改中頻系數。而針對不同的用途,修改系數位置的細節還可以有一定不同,例如數字水印主要目的是保證嵌入信息的健壯性,所以可以在較中頻系數略低的位置隱寫,而信息隱藏更注重保證信息的隱蔽性,修改頻率過低的可能會導致視覺效果變化,所以可以在較中頻系數較高的位置隱寫。
2.信息隱藏算法:
信息如何隱藏到dct系數中有很多選擇,首次實驗中采取比較兩個特定位置的dct系數大小來隱藏信息,左邊較大表示1,右邊較大表示0,雖然看似只能存儲1和0,但是應用可以更加廣泛,比如存儲灰度圖像。提取過程就只需將載體圖片dct變換后讀取特定位置的dct系數即可。但是dct系數可以一直讀取下去,所以按照讀取原則讀的話可以一直讀取到信息,這樣傳輸時需要提前商定秘密信息長度,這在實際傳輸中是比較不科學的。針對此問題,在后續實驗中實現了一種方法—將秘密信息長度也隱藏在載體中。在第一個提取位置存儲秘密信息長度,再根據長度提取之后的秘密信息。而在隱寫過程中對DCT系數修改時也發現,修改值的大小雖然在隱藏信息提取時沒什么影響,但是對于載體圖像可能會造成一定破壞。如果添加的值過大可能會造成載體圖像出現白點等現象,所以在對系數的更改時簡便起見可以統一修改0.01,以保證載體圖像視覺上的完整性。
3.隱寫分析抵抗:
我認為DCT信息隱藏方法在抗分析上有先天優勢,主流有效的分析方法大部分都是基于統計分析的,而DCT隱藏雖然修改了系數,但是根據算法和修改程度的不同可以有效規避統計分析檢測。目前基于卡方統計的破解隱寫方法對于隱寫內容多,修改大的隱藏方式效果較好,但若是僅修改了少數DCT系數,就很難識別。上面實現的算法修改也相對較大,如果左右系數的值相差較大可能會造成某個值修改明顯的情況。對于這一點可以優化算法進行解決,實現中DCT系數是以float類型存儲,我們可以判斷系數最后一個小數位的奇偶來存儲1或0,相對于前一種算法修改值就大大下降了。
而且隱寫分析使用的統計分析方法在隱寫時同樣可以使用,我們可以在保證不被分析出的情況下存儲秘密信息。上面實現的算法算是比較浪費的一種,如果要存儲n個字符需要2n個像素點,但是存儲五個字符也只占用了十個像素點,這在一張1920*1080的圖片中想探測出來,我認為是相當困難的。卡方檢測最終要算出可能存在隱寫的概率P,如果P等于1或者0就很容易確定是否有信息隱寫,但是當p等于0.5時是否還容易判斷呢,我把這種情況的系數叫做混淆系數,我們在隱寫過程中如果要嵌入大量信息,如果能將卡方計算出的P控制在混淆系數左右或者以下,對于檢測者來說辨別的難度更是增加了不少。
代碼–包含壓縮和嵌入
import cv2 import numpy as np import matplotlib.pyplot as plt def zip(num1,num2):recor_temp = img_dct[num1:num2, num1:num2]recor_temp2 = np.zeros(img.shape)print(img.shape)recor_temp2[num1:num2, num1:num2] = recor_tempimg_recor1 = cv2.idct(recor_temp2)plt.figure('zip')plt.subplot(121),plt.title('origin')plt.imshow(img)plt.subplot(122),plt.title('zip')plt.imshow(img_recor1)plt.show() img=cv2.imread('D:\earth.jpg',cv2.IMREAD_GRAYSCALE) img1=img.astype('float') img_dct=cv2.dct(img1) mes="10010" for i in range(0,len(mes)):#嵌入if mes[i]=='1':if img_dct[i][1917-i]>img_dct[i][1918-i]:passelse:img_dct[i][1917-i]=img_dct[i][1918-i]+0.1elif mes[i]=='0':if img_dct[i][1917-i]<img_dct[i][1918-i]:passelse:img_dct[i][1918-i]=img_dct[i][1917-i]+0.1 img_recover=cv2.idct(img_dct) img_decode=cv2.dct(img_recover) getmsg="" for i in range(0,len(mes)):#提取if img_dct[i][1917 - i] > img_dct[i][1918 - i]:getmsg=getmsg+"1"else:getmsg=getmsg+"0" print("Deliverd message is: ",mes) print("Ranger message is: ",getmsg) plt.imshow(img_recover) plt.savefig('D:/earth_insert.jpg') plt.figure('DCT') plt.subplot(121),plt.title('origin') plt.imshow(img) plt.subplot(312),plt.title('DCT') plt.imshow(img_dct) plt.subplot(122) plt.imshow(img_recover),plt.title('recover') plt.show()總結
以上是生活随笔為你收集整理的变换域信息隐藏--DCT的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: deepin安装MySQL5.7
- 下一篇: 学会了这个调试方法,再难的Bug都不怕!