數字水印處理的小小心得!!!

因爲最近幫老師做一些,有關數字水印的東西,在這裏我想記錄一下,自己在這次幫老師做數字水印過程中的一些小小心得。

在這個項目中,我們做的是基於DCT變換的數字水印,語言方面用的 java 來實現,當中還用到了,JAVACV來處理圖形。

下面我來說說,我們是如何準備這次數字水印的項目。

第一天,老師先叫我們,看看數字水印的相關論文,然後在網上找代碼,在下週二的時候集中討論,講講你找的數字水印算法,是如何實現的,它的基本原理是什麼?

那天我就開始找算法,發現網上很多都是,用 matlab 或者 C++ 來實現的,由於本人matlab 不會,再加上呢? 學 C++的時候學的都是一些皮毛,所以我不是特別想找用 c++ 來實現的代碼,然後我就一直找,終於在找了很久的情況下,我終於找到了,一個用 java 實現的數字水印代碼,然後直接將其copy下來,運行一下,可以成功,感覺不錯,然後我就開始了,漫長的 “考古”之旅,因爲本人java的相關知識在那個時候,還在努力學習當中,說以當時那個 java 算法中 有些東西是我第一次接觸,不是特別懂,比如 BufferedImage 等相關用法不是特別懂,還有對於 圖片 的一些性質也不是特別懂,經過幾天的查找資料,然後終於,把這個算法看懂了, 在這裏我來說說,我第一個找到的,用java寫的數字水印算法,的實現過程,第一步,我們在這裏設置一個常數 d = 10,然後我們在將一個圖片得到一個 8 * 8的小塊,在把這個圖片的RGB三個通道中的B通道提取出來,然後在進DCT變換,那個算法中,選擇了,5個點作爲改變DCT係數的點,在這裏我在補充一下,那個算法選的是 嵌入 32 32的二值圖片(二值圖片就是用0或1表示的像素點),如果我們嵌入的 是 0 ,那麼我們就將這 5個點的DCT係數 分別增加 常數d,如果我們嵌入的是 1,那麼我們就將這 5個點的DCT係數 分別減少 常數d,然後這8 * 8的小塊嵌入完0或1後,我們在做IDCT變換,改變88小塊的像素值, 那麼我在說說這個算法的提取水印的過程,這個算法是一個非盲水印,(雖然這個算法是一個非盲水印,但它卻給我帶來接下來幫老師做真正做數字水印的機會),提取過程大致是,用嵌入後的圖對應點的DCT係數與原圖對應點DCT係數的比較大小,統計這選中5個點中,大於的個數假設是m,小於的個數假設是n,如果 m > n那麼提取的數字水印信息是1,反之是0。
我找的第一個用java實現的非盲數字水印算法

然後,到了下週二,老師過來詢問我們找數字水印算法的三個人的進展,可能當時,我對我的這個算法理解的比較透徹吧,(就有了老師叫我跟我們專業另一個人合夥寫數字水印的機會),當老師得知是非盲水印時,我有開始了尋找盲水印的java實現代碼,然後找了一天,終於找到了,一個用java寫的非盲水印,當時我很激動,以爲自己成功找到了,老師想要的代碼,可是沒想到,那只是剛剛開始,在這個算法當中,我又接觸到了,我重來沒有見過和使用過的東西,openCV(在那個算法中用的是openCV中對java開放的接口,簡稱:javaCV)。然後我有開始了漫長的 “考古”之旅,而這次“考古”也是巨艱難,先是openCV是第一次使用,然後我就將第二個java代碼,逐句逐句的百度,用了幾個晚上的時間,纔看懂一些,openCV的常用用法,本來有些東西想進一步瞭解的,發現看不了源碼,而且馬上又要到和老師一起討論進展的時候了,所以那個時候我很慌,就在星期五的那天晚上,那個時候我記得我還在跟室友一起打盧克,然後老師一個電話說,有事找我一下,於是被逼無奈,我只好掛機了,老師找我們說有一個項目,需要做一個數字水印的系統,然後叫我跟另一個人一起合作,做一個出來,當時我還是滿激動的,畢竟是第一次遇見這種事,就答應了,第二天我就拿出來了,我找到的第二個用java實現的盲數字水印算法給那個人看,他覺得不錯,然後我也覺得不錯,然後我們將那個代碼稍稍的改了一下,發現容量擴大了,更不錯了,因爲我下午跟我同學,一起要去看復聯4於是我就提前走了,然後他就一個人,留在那裏等老師,過來檢查結果,但是老師不是特別滿意,勉強能夠接受,於是我們開始做,壓縮,亮度變換,對比度變換,飽和度變換,縮放攻擊,下提取水印信息的情況,一做攻擊測試,發現這算法不行,感覺那個時候驚了,於是把這個測試結果告訴了老師,發現老師叫我們繼續找代碼,或者看論文。然後我們開始找網上現成的代碼,發現找不到了,於是我們決定自己寫算法,然後我跟那個同學一起看起了論文,那個時候頭都大,然後第二天,老師跟我們討論,看的論文情況,然後我們找到了一篇論文,那個時候,我們看了下那個論文的在各種攻擊的情況下,魯棒性都很不錯,於是,我們開始了,自己寫數字水印的算法,那天晚上,將那個算法寫出來了,但我發現有bug,於是第二天開始調試代碼,調試成功後,我們在將代碼,給老師看,老師看來之後提了幾個問題,然後我們又將這個代碼進行了修改,使嵌入後的圖片效果更好,然後我們再在網上找了個可以個可以在線壓縮圖片的網站進行壓縮測試發現效果很好,但那個時候也遇到了一個問題我們寫的算法只能處理圖片格式是bmp或者png的無法處理jpg,當時也不是特別注意,但就是這個問題使我們花費了巨大的代價,然後給老師看,老師還是比較滿意的,於是叫我們開始寫界面和準備攻擊測試,然而就是剛剛提到的那個問題,使我們在找壓縮代碼的時候發現,找不到壓縮png格式的代碼,或者找到將bmp壓縮成jpg的,但就是提不出來。還是那個同學比較給力,那天他給我看來一篇,有關jpeg壓縮的原理,發現壓縮用的是YCbCr這種,提取Y的通道,而我們一直用的都是RGB中的B通道去提取信息,然後我們就明白了,於是我們就用Y通道去嵌入水印信息,然後當天晚上加上第二天早上,我們將代碼重新修改了一下, 發現可以提取壓縮後的圖片的水印信息,當時感覺很爽,那時沒有做其他攻擊測試,然而,那天網上,當我們做其他測試的時候驚了,發現抵抗不了其他攻擊,於是又開始修改代碼,然後我的那個同學,他提到了一個非常重要的一點,然後我們修改後,發現能夠抵抗,壓縮,亮度變換,對比度變換,飽和度變換,縮放攻擊,這些攻擊,然後第二天我又去找了一些非常好的點,和嵌入強度,進行攻擊測試,都不錯,與寫好UI,去給老師看,老師很滿意,唯一不好的是,老師希望我能把這個界面重新優化一下,我想行吧。於是開始了我的優化之旅。

下面我來說說,這次數字水印的一些心得(可能也不是特別好,但我想把我這次經歷的一些東西記錄下來,萬一將來,在工作中需要用到數字水印的一些東西,那我豈不是爽歪歪):

1,將圖片分成塊,從而形成 8* 8 的像素塊比較好。因爲JPEG壓縮也是用的是8 * 8的像素塊來進行的。

2,當我們提取一張圖片的某個通道的像素值形成的二維矩陣,然後將其進行DCT變換。在這裏我們假設 像數值 a 對應點的DCT係數是 b,如果我們將 b = b + 750;然後在將其進行IDCT變換,然後改變了的DCT係數對應點的 像素值 其實和原來相比 變化程度不大。

3,改變DCT係數時,我們需要提取通道,如果你想讓你的算法,抗壓縮的能力強的話,可以看看這篇文章,有關JPEG壓縮的祕密,通過這篇文章我們可以發現一個特點,JPEG壓縮的本質是同過,YCbCr中的Y通道來實現壓縮的,所以要想抗壓縮的能力更強一點,所以我建議大家使用YCbCr中的Y通道,通過改變DCT係數的方式來達到嵌入水印信息的目的。

4,最重要的一點是,如何表示嵌入信息,通過修改DCT係數,那麼又是如何修改DCT係數的呢?我們可選擇兩個點,那麼我們要怎麼去選擇兩個點,去修改它們的DCT係數,我們可以通過這樣的方式去尋找點在這裏插入圖片描述
和JPEG量化係數表:
在這裏插入圖片描述
然後我們選擇兩個合適點,比較接近,而且JPEG量化係數差距不大,作爲修改DCT係數的兩個點,接下來說說,這樣修改點,我們的做法是,我們在先假設兩個點 a點 和 b點,如果我們嵌入的數字是1,那麼我們 就將a點的DCT係數變爲p(p表示嵌入強度),b點的DCT係數變爲0,如果我們嵌入的數字是0,那麼我們 就將a點的DCT係數變爲0,b點的DCT係數變爲p。
那麼怎樣表示提取呢? 將嵌入後的圖片先分成8*8的像素塊,然後進行DCT變換,找到我們修改DCT係數的a ,b兩點,如果 a的DCT係數 > b的DCT係數,那麼嵌入的信息表示1,反之表示0。而且p越大,魯棒性越強,但是也越影響圖片的質量。所以我們選擇點的時候,要慎重考慮、。

5,爲什麼,我們可以抵抗,亮度變換,對比度變換,飽和度變換,這些攻擊都是通過,改變R,G,B通道的值從而,來進行變換的,而Y通道的值是可以通過R,G,B的值計算得到,而我們選擇相似的兩個點,他們的R,G,B的值不會相差太大,所以經過這些變換後,他們兩個點的大小關係,也不容易,發生變換。

6,縮放攻擊,會捨棄高頻位置上的點,所以我們選擇點時,應該選擇,比較靠前的兩個點。

總之:改變YCbCr中的Y通道的DCT係數來表示嵌入信息,選擇兩個比較相近的點,然後在改變這兩個點的DCT係數,而且這兩個點比較靠前(用於抵抗縮放),通過兩個點的大小關係來表示嵌入的信息。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章