国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

如何給圖片加盲水???盲水印和圖片隱寫(xiě)術(shù)實(shí)現

發(fā)布時(shí)間:2022-05-26 12:49 來(lái)源:老劉博客 閱讀:152 作者:網(wǎng)絡(luò ) 欄目: 經(jīng)驗分享 歡迎投稿:712375056

本文目錄 顯示

前文老劉博客有介紹過(guò)騰訊云的盲水印產(chǎn)品,我們這里不想用他家的這個(gè)產(chǎn)品了,我們如果要自己給圖片加盲水印,要怎么做呢?今天老劉博客就為大家分享盲水印實(shí)現技術(shù):盲水印和圖片隱寫(xiě)術(shù),并帶大家了解這背后的原理。

盲水印

一、演示

首先看,這是一張女朋友:

解碼水印

接下來(lái)我們輸入一行神奇的命令:

python bwm.py --action decode --origin Demo.jpg --im ../Gakki.jpg --result res.jpg

可以得到這樣的一張圖:

以后誰(shuí)再跟你搶女朋友就可以這樣聲明版權了嘿嘿。(腳本和原圖都在最后的附錄里,有興趣的朋友只需要將上面的圖片保存為Demo.jpg,附錄里的原圖保存為Gakki.jpg,就可以解碼出上面的信息)

加密水印

通過(guò)今天的方法你可以將信息放入任意圖片,來(lái)達到加密信息的目的。

附錄里的腳本,加密用法:

python bwm.py --action encode --origin Gakki.jpg --im wm1.png --result Demo.jpg --alpha 2

二、用途

上面 的水印就叫做盲水印,隱藏式的水印是以數字數據的方式加入音頻、圖片或影片中,但在一般的狀況下無(wú)法被看見(jiàn)。隱藏式水印的重要應用之一是保護版權,期望能借此避免或阻止數字媒體未經(jīng)授權的復制和拷貝。

1.不同人加相同水印

聲明版權

應用案例

  • 某些畫(huà)師、攝影師、設計師會(huì )在其作品中加入水印。

13年左右有位自稱(chēng)是“超寫(xiě)實(shí)主義”的畫(huà)家,聲稱(chēng)自己純手工畫(huà)的畫(huà)寫(xiě)實(shí)程度可以超過(guò)攝影機,并開(kāi)辦培訓班斂財。 后被一位加了盲水印的攝影師戳穿,原來(lái)其“畫(huà)作”都是直接將照片用ps處理成手繪質(zhì)感的圖。

  • 淘寶防盜圖功能

淘寶賣(mài)家圖會(huì )被淘寶自動(dòng)打上水印,如果有別的賣(mài)家存圖作為自己的圖上傳會(huì )被檢測出。

2.不同人加不同水印

將某份保密數字資料發(fā)送給不同人時(shí),可加上不同標識,如果資料被復制、傳播可根據解碼出的唯一標識來(lái)追究責任人。

應用案例

  • 電影剛剛公映時(shí),每個(gè)影院,影廳的 電影底片里都會(huì )加入不同的不可見(jiàn)水印, 如果電影流出,就可追究相關(guān)影院責任。
  • 阿里,華為等公司內部論壇、平臺會(huì )在HTML頁(yè)面中加入足夠數量 及不被發(fā)現的唯一標識。當有內部敏感信息通過(guò)截圖等方式流出,也可追蹤到個(gè)人。

比如著(zhù)名的“阿里月餅門(mén)”。

三、原理

原理圖

傅里葉變換

  • 簡(jiǎn)單復習下傅里葉變換

傅里葉變換簡(jiǎn)單地說(shuō)就是將信號在時(shí)域空域的函數轉變到頻域表示,在和工程學(xué)中有許多應用。因其基本思想首先由法國學(xué)者約瑟夫·傅里葉系統地提出。

  • 再理解下時(shí)域和頻域

那么,傅里葉變換有什么用呢,

  • 先在紙上畫(huà)一個(gè)sin(x),不一定標準,意思差不多就行。不是很難吧。
  • 好,接下去畫(huà)一個(gè)sin(3x) sin(5x)的圖形。這個(gè)就很難能畫(huà)得出來(lái)。

現在把sin(3x) sin(5x)的曲線(xiàn)給你,只看圖是看不出這整個(gè)曲線(xiàn)的方程式是怎樣的,現在需要將把sin(5x)從圖里拿出去,看看剩下的是什么。這基本是不可能做到的。

但是在頻域呢?則簡(jiǎn)單的很,無(wú)非就是幾條豎線(xiàn)而已。

這是最簡(jiǎn)單的一種用法,其他復雜用法不在此贅述。

頻譜圖

一維信號的變換理解之后,那么圖像的頻譜圖長(cháng)什么樣呢。

圖片中明亮的部分就是低頻(平緩)部分,暗點(diǎn)的是高頻(突變交界)部分。一般為了展示會(huì )把頻譜圖低頻的部分移到中心。頻譜圖上的點(diǎn)跟原圖不存在一一對應關(guān)系,頻譜圖的每一點(diǎn)都來(lái)自于全部的圖像(類(lèi)似于時(shí)域曲線(xiàn)的點(diǎn),和頻域圖的點(diǎn))。

這樣可能還不夠直觀(guān),接下來(lái)看這張圖。

這是一張400×400的圖,共有16 萬(wàn)個(gè)像素點(diǎn)。

我們平時(shí)怎么來(lái)表示一張圖片呢,首先是在笛卡爾坐標系中用x,y來(lái)定位某一確定的點(diǎn)。那么,我們怎么來(lái)描述這個(gè)點(diǎn)呢?

我們知道,所有的色彩都是由三原色組成。生活中經(jīng)常說(shuō)的紅、黃、藍(青),其實(shí)是一種消減型的三原色,光學(xué)中的三原色是紅、綠、藍,也就是R、G、B。

通常我們用來(lái)描述圖像點(diǎn)的方法就是RGB的值,其實(shí)圖像處理中用的是灰度(Gray scale)來(lái)表示圖片,但是為了便于理解,下面用的是RGB演示 。

上圖是截取了某一行RGB的值做成的曲線(xiàn)圖,可以看到,每條曲線(xiàn)都在不停的上下波動(dòng),且波動(dòng)的頻率是相同的。有些區域的波動(dòng)比較小,有些區域突然出現了大幅波動(dòng)。

對比一下圖像就能發(fā)現,曲線(xiàn)波動(dòng)較大的地方,也是圖像出現突變的地方。

圖像的頻譜可以理解為將一維的頻譜繞著(zhù)縱軸旋轉一圈,形成一個(gè)3維的數學(xué)函數圖(原圖中心對稱(chēng)、鏡像對稱(chēng)才可以這樣干,其他類(lèi)似),x、y軸代表兩個(gè)方向的頻率,z軸代表該頻率的幅值,只不過(guò)頻譜圖像是一個(gè)2維圖,所以用亮度來(lái)表示幅值了。

二維傅里葉變換的物理意義是將圖像的灰度分布函數變換為圖像的頻率分布函數。

盲水印的特性

魯棒性一般要能抗(壓縮 、裁剪、涂畫(huà),旋轉)。

  1. 隱蔽性由于不希望被察覺(jué)、不希望干擾用戶(hù)體驗、不希望被模仿等等原因,我們的水印不可見(jiàn),也就是隱匿性。
  2. 不易移除性不易移除性跟魯棒性有些相似, 不同的是:魯棒性更加強調的是數字資源在傳播過(guò)程中不要被不自覺(jué)地干擾和破壞。不易移除性是在別有用心者察覺(jué)了盲水印的存在后,不被他們自覺(jué)地移除或者破壞。
  3. 強健性強健性通常也被稱(chēng)作魯棒性,來(lái)自于其英文名稱(chēng)(Robustness)的音譯。簡(jiǎn)單地說(shuō)就是耐操性。需要說(shuō)明的一點(diǎn)是,魯棒性和隱蔽性通常不可兼得。
  4. 明確性沒(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ì )判斷圖片結尾標識,其之后的全部丟棄,慢慢不再有人使用。(https://sm.ms/這個(gè)圖床還是很給力的,經(jīng)測試還是可以解析種子)

隱藏文件

圖片可以跟種子文件結合,當然也可以和其他文件結合。

其實(shí)隱藏文件和盲水印都屬于圖片隱寫(xiě)術(shù)。

圖片隱寫(xiě)術(shù)

隱寫(xiě)術(shù)(Steganography)也是數字水印的一種應用,雙方可利用隱藏在數字信號中的信息進(jìn)行溝通。

數字照片中的注釋數據能記錄照片拍攝的時(shí)間、使用的光圈和快門(mén),甚至是相機的廠(chǎng)牌等信息,這也是數字水印的應用之一。

某些文件格式可以包含這些稱(chēng)為“metadata”的額外信息。

用途

規避敏感詞過(guò)濾

? 所謂的“敏感詞過(guò)濾”,常翻墻的同學(xué),應該都很熟悉了。用圖片來(lái)隱藏信息,可以規避GFW的敏感詞過(guò)濾。

規避肉眼審查

? 國內的很多網(wǎng)站,對于上傳的圖片,都會(huì )進(jìn)行人工審查。如果能通過(guò)技術(shù)手段把信息隱藏在圖片中,而圖片本身又看不出什么異樣,人工審核就看不出來(lái)。

傳遞加密信息

? 不希望被別人看到的資料、信息等。

常見(jiàn)方法

原理

內容覆蓋法

通常來(lái)說(shuō),圖片文件都有包含2部分:文件頭和數據區。

而“內容覆蓋法”,就是把要隱藏的文件,直接【覆蓋】到圖片文件的【數據區】的【尾部】。

比方說(shuō),某圖片有 100KB,其中文件頭占 1KB,那么,數據區就是 99KB。也就是說(shuō),最多只能隱藏 99KB 的文件。

切記:覆蓋的時(shí)候,千萬(wàn)不可破壞文件頭。文件頭一旦破壞,這個(gè)圖片文件就不再是一個(gè)合法的圖片文件了。   

使用這種方法,對圖片文件的格式,是有講究的——最好用【24位色的 BMP 格式】。

  • BMP 格式本身比較簡(jiǎn)單,數據區隨便覆蓋,問(wèn)題不大;
  • 24位色的 BMP 相對其它的格式 BMP,文件尺寸更大,可以隱藏更多內容。
import sys

def embed(container_file, data_file, output_file) :
    """代碼沒(méi)有嚴格計算 BMP 的文件頭尺寸,只是大致預留了 1024 字節"""
    
    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)

LSB最低有效位

很多商業(yè)軟件使用的原理都是這個(gè)方法。

例如在PNG圖片的儲存中,每個(gè)顏色會(huì )有8bit,LSB(Least Significant Bit)隱寫(xiě)就是修改了像數中的最低的1bit,在人眼看來(lái)是看不出來(lái)區別的,也把信息隱藏起來(lái)了。(每個(gè)像數可以攜帶3bit的信息。)

譬如我們想把’A’隱藏進(jìn)來(lái)的話(huà),如下圖,就可以把A轉成16進(jìn)制的0x61再轉成二進(jìn)制的01100001,再修改為紅色通道的最低位為這些二進(jìn)制串。

最后

1.附上前面演示代碼的實(shí)現:(參考了幾個(gè)git hub上的項目,不過(guò)魯棒性都不太好)

# coding=utf-8
import cv2
import numpy as np
import random
import os
from argparse import ArgumentParser
   
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]
   
        # 水印隨機編碼
        x, y = range(height / 2), range(width)
        random.seed(height   width)   # 隨機數解碼時(shí)可控
        random.shuffle(x)
        random.shuffle(y)
           
        # 按目標圖片大小 對水印圖進(jìn)行對稱(chēng)
        tmp = np.zeros(img.shape)  # 根據圖片形狀,生成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)  # 轉換為實(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)很深、應用很廣泛的學(xué)問(wèn),這里講的很泛,權當做拋磚引玉。圖片隱寫(xiě)術(shù)只是其中一種,有興趣的同學(xué)可以看下面這本書(shū)。

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

男人又粗又硬桶女人免费视频| 熟睡中被义子侵犯中字| 欧美寡妇XXXX黑人猛交| 国产第19页精品| 四韩色情无码一区二区三区| 北条麻妃人妻AV在线专区|