? 傳知代碼 ? 基于擴散模型的無載體圖像隱寫術

💛前情提要💛

本文是傳知代碼平臺中的相關前沿知識與技術的分享~

接下來我們即將進入一個全新的空間,對技術有一個全新的視角~

本文所涉及所有資源均在傳知代碼平臺可獲取

以下的內容一定會讓你對AI 賦能時代有一個顛覆性的認識哦!!!

以下內容干貨滿滿,跟上步伐吧~


📌導航小助手📌

  • 💡本章重點
  • 🍞一. 概述
  • 🍞二. 論文思路
  • 🍞三. 方法原理
  • 🍞四. 實驗過程
  • 🍞五. 使用方式
  • 🫓總結


💡本章重點

  • 基于擴散模型的無載體圖像隱寫術

🍞一. 概述

當前的圖像隱寫技術主要集中在基于載體圖(cover image)的方法上,這些方法通常存在泄露隱藏圖(secret image)的風險和對退化容器圖(container image)不魯棒的風險。受到最近擴散模型(diffusion models)發展的啟發,作者發現了擴散模型的兩個特性,即無需訓練即可實現兩張圖像之間的轉換以及對噪聲數據有天然的魯棒性。這些特性可以用來增強圖像隱寫任務中的安全性和魯棒性。這是首次將擴散模型引入圖像隱寫領域的嘗試。與基于載體圖的圖像隱寫方法相比,作者提出的CRoSS框架在可控性、魯棒性和安全性方面具有明顯優勢。


🍞二. 論文思路

💡技術要點:

本文將無載體圖圖像隱寫任務表示為三個圖像和兩個過程組成:這三個圖像指的是秘密圖像xsec、容器圖像xcont和揭示圖像xrev,而這兩個過程是隱藏過程和揭示過程。秘密圖像xsec是我們想要隱藏的圖像,并通過隱藏過程隱藏在容器圖像xcont中。通過互聯網傳輸后,容器圖像xcont可能會退化,得到容器圖像的退化圖像x’cont,我們通過揭示過程從中提取顯示的圖像xrev。根據上述定義,我們可以將隱藏過程視為秘密圖像xsec和容器圖像xcont之間的翻譯,將揭示過程視為隱藏過程的反向過程。

在這里插入圖片描述
本文使用條件擴散模型來將秘密圖像進行加密使之轉換為容器圖像,并使用DDIM反轉來實現圖像分布和噪聲分布之間的雙向轉換,允許可逆圖像轉換,這樣的方法使得容器圖像能夠成功被還原為秘密圖像。

在這里插入圖片描述


🍞三. 方法原理

1、CRoSS的隱藏過程
(1)原理:使用 DDIM 的前后向過程對秘密圖像進行處理,得到容器圖像。首先,使用一個私鑰作為條件,對秘密圖像進行加噪(前向過程),接著使用一個公鑰作為條件,進行去噪(后向過程),這樣就可以生成一個可以在互聯網上傳播的容器圖像了。私鑰用于描述秘密圖像中的內容,而公鑰用于控制容器圖像中的內容。

在這里插入圖片描述
如上圖所示,prompt1是私鑰,prompt2是公鑰。并列的三幅圖中,第一幅是秘密圖像,第二幅是容器圖像,第三幅是揭示圖像。

(2)算法思路
輸入:將被隱藏的秘密圖像xsec,帶有噪聲估計器εθ的預訓練條件擴散模型,采樣時間步數T,以及作為私鑰和公鑰的兩個不同條件kpri和kpub。
輸出:用于隱藏秘密圖像xsec的容器圖像xcont。

在這里插入圖片描述
2、CRoss的揭示過程
(1)原理:在揭示階段,假設容器圖像已通過互聯網傳輸,并可能已損壞為x’cont,接收器需要使用相同的條件擴散模型和相應提示詞,通過相同的正向和后向過程的逆過程將其顯示回秘密圖像。在整個無載體圖像隱寫過程中,我們不專門為圖像隱寫任務訓練或微調擴散模型,而是依靠DDIM反轉保證的固有可逆圖像翻譯。

(2)算法思路
輸入:通過互聯網傳輸的容器圖像x’cont(可能從xcont退化),帶有噪聲估計器εθ的預訓練條件擴散模型,采樣時間步數T,私鑰kpri和公鑰kpub。
輸出:從容器圖像中揭示出的圖像xrev。


🍞四. 實驗過程

1、實驗設置
實驗選擇了穩定Stable Diffusion v1.5作為條件擴散模型,并使用了確定性DDIM采樣算法。由秘密圖像生成噪聲圖和由噪聲圖生成容器圖各自都由50步組成。為了實現可逆圖像轉換,我們將穩定擴散的引導刻度設置為1。對于作為私鑰和公鑰的給定條件,我們有三個選項:prompts(提示詞)、ControlNets條件(depth maps, scribbles, segmentation maps)和LoRAs。

2、數據準備
實驗收集了總共260張圖像,并生成專門為無載體圖像隱寫術量身定制的提示詞,稱為Stego260。實驗將數據集分為三類,即人類、動物和一般物體(如建筑、植物、食物、家具等)。數據集中的圖像來自公開的數據集和谷歌搜索引擎。為了生成提示密鑰,我們使用BLIP生成私鑰,并使用ChatGPT或人工調整來執行語義修改并批量生成公鑰。
下圖為使用ChatGPT生成公鑰的過程。

在這里插入圖片描述
3、核心代碼

class ODESolve:def __init__(self, model, NUM_DDIM_STEPS=50):scheduler = DDIMScheduler(beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", clip_sample=False,set_alpha_to_one=False)self.model = modelself.num_ddim_steps = NUM_DDIM_STEPSself.tokenizer = self.model.tokenizerself.model.scheduler.set_timesteps(self.num_ddim_steps)self.prompt = Noneself.context = Nonedef prev_step(self, model_output: Union[torch.FloatTensor, np.ndarray], timestep: int, sample: Union[torch.FloatTensor, np.ndarray]):prev_timestep = timestep - self.scheduler.config.num_train_timesteps // self.scheduler.num_inference_stepsalpha_prod_t = self.scheduler.alphas_cumprod[timestep]alpha_prod_t_prev = self.scheduler.alphas_cumprod[prev_timestep] if prev_timestep >= 0 else self.scheduler.final_alpha_cumprodbeta_prod_t = 1 - alpha_prod_tpred_original_sample = (sample - beta_prod_t ** 0.5 * model_output) / alpha_prod_t ** 0.5pred_sample_direction = (1 - alpha_prod_t_prev) ** 0.5 * model_outputprev_sample = alpha_prod_t_prev ** 0.5 * pred_original_sample + pred_sample_directionreturn prev_sampledef next_step(self, model_output: Union[torch.FloatTensor, np.ndarray], timestep: int, sample: Union[torch.FloatTensor, np.ndarray]):timestep, next_timestep = min(timestep - self.scheduler.config.num_train_timesteps // self.scheduler.num_inference_steps, 999), timestepalpha_prod_t = self.scheduler.alphas_cumprod[timestep] if timestep >= 0 else self.scheduler.final_alpha_cumprodalpha_prod_t_next = self.scheduler.alphas_cumprod[next_timestep]beta_prod_t = 1 - alpha_prod_tnext_original_sample = (sample - beta_prod_t ** 0.5 * model_output) / alpha_prod_t ** 0.5next_sample_direction = (1 - alpha_prod_t_next) ** 0.5 * model_outputnext_sample = alpha_prod_t_next ** 0.5 * next_original_sample + next_sample_directionreturn next_sampledef get_noise_pred_single(self, latents, t, context):noise_pred = self.model.unet(latents, t, context)["sample"]return noise_preddef get_noise_pred(self, latents, t, is_forward=True, context=None):if context is None:context = self.contextguidance_scale = GUIDANCE_SCALEuncond_embeddings, cond_embeddings = context.chunk(2)noise_pred_uncond = self.model.unet(latents, t, uncond_embeddings)["sample"]noise_prediction_text = self.model.unet(latents, t, cond_embeddings)["sample"]noise_pred = noise_pred_uncond + guidance_scale * (noise_prediction_text - noise_pred_uncond)if is_forward:latents = self.next_step(noise_pred, t, latents)else:latents = self.prev_step(noise_pred, t, latents)return latents@torch.no_grad()def latent2image(self, latents, return_type='np'):latents = 1 / 0.18215 * latents.detach()image = self.model.vae.decode(latents)['sample']if return_type == 'np':image = (image / 2 + 0.5).clamp(0, 1)image = image.cpu().permute(0, 2, 3, 1).numpy()[0]image = (image * 255).astype(np.uint8)return image@torch.no_grad()def image2latent(self, image):with torch.no_grad():if type(image) is Image:image = np.array(image)if type(image) is torch.Tensor and image.dim() == 4:latents = imageelse:image = torch.from_numpy(image).float() / 127.5 - 1image = image.permute(2, 0, 1).unsqueeze(0).to(device)latents = self.model.vae.encode(image)['latent_dist'].meanlatents = latents * 0.18215return latents@torch.no_grad()def init_prompt(self, prompt: str):uncond_input = self.model.tokenizer([""], padding="max_length", max_length=self.model.tokenizer.model_max_length,return_tensors="pt")uncond_embeddings = self.model.text_encoder(uncond_input.input_ids.to(self.model.device))[0]text_input = self.model.tokenizer([prompt],padding="max_length",max_length=self.model.tokenizer.model_max_length,truncation=True,return_tensors="pt",)text_embeddings = self.model.text_encoder(text_input.input_ids.to(self.model.device))[0]self.context = torch.cat([uncond_embeddings, text_embeddings])self.prompt = prompt@torch.no_grad()def get_text_embeddings(self, prompt: str):text_input = self.model.tokenizer([prompt],padding="max_length",max_length=self.model.tokenizer.model_max_length,truncation=True,return_tensors="pt",)text_embeddings = self.model.text_encoder(text_input.input_ids.to(self.model.device))[0]return text_embeddings

4、實驗結果

運行ReadMe文件中的以下代碼,快速運行代碼進行圖片加密解密。

python demo.py --image_path ./asserts/1.png --private_key "Effiel tower" --public_key "a tree" --save_path ./output --num_steps 50

成功運行界面如下:

在這里插入圖片描述
打開output文件夾,查看實驗過程中的三幅圖像

在這里插入圖片描述
待加密圖像:

在這里插入圖片描述
容器圖像:

在這里插入圖片描述
揭示圖像:

在這里插入圖片描述
可以發現,隱寫后的圖片自然且清晰度高,不易被察覺到隱藏了秘密圖像,揭示圖像還原度高,經過網絡傳輸后仍然能夠很好地被還原。


🍞五. 使用方式

編譯器采用Pycharm,下載好項目代碼后,閱讀ReadMe文件以及“requirements.txt”。

首先運行ReadMe文件中的以下代碼,下載好實驗所需的所有庫并配置好環境。

pip install -r requirements.txt

然后運行ReadMe文件中的以下代碼,快速運行代碼進行圖片加密解密。

python demo.py --image_path ./asserts/1.png --private_key "Effiel tower" --public_key "a tree" --save_path ./output --num_steps 50

上述image_path后面的參數是要加密圖像在設備上的路徑,可以根據自己的圖片路徑進行調整;private_key后面的參數是私鑰,根據不同待加密圖片的內容自行調整;public_key后面的參數是公鑰,根據想要生成的容器圖像內容進行調整;save_path后面的參數是加密后的容器圖像的保存地址,如果不修改的話每次運行程序都會覆蓋前一次的運行結果;num_steps后面的參數是迭代次數,可以根據自己的需要進行調整,一般迭代次數越多效果越好,花費的時間越長。


🫓總結

綜上,我們基本了解了“一項全新的技術啦” 🍭 ~~

恭喜你的內功又雙叒叕得到了提高!!!

感謝你們的閱讀😆

后續還會繼續更新💓,歡迎持續關注📌喲~

💫如果有錯誤?,歡迎指正呀💫

?如果覺得收獲滿滿,可以點點贊👍支持一下喲~?

【傳知科技 – 了解更多新知識】

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/15628.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/15628.shtml
英文地址,請注明出處:http://en.pswp.cn/web/15628.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

前端---閉包【防抖以及節流】----面試高頻!

1.什么閉包 釋放閉包 從以上看出:一般函數調用一次會把內部的數據進行清除--但是這種操作卻可以一起保留局部作用域的數據 // 優點:1、可以讀取函數內部的變量 2、讓這些變量始中存在局部作用域當中 2.閉包產生的兩種業務場景:防抖、節流 2.1防抖 舉…

QGraphicsView實現簡易地圖16『爆炸效果』

前文鏈接:QGraphicsView實現簡易地圖15『測量面積』 一種簡單的爆炸波擴散效果 動態演示效果: 靜態展示圖片: 核心代碼: #pragma once #include "../AbstractGeoItem.h" #include "DataStruct/GeoData.h"…

sysbench壓測mysql性能測試命令和報告

sysbench壓測mysql性能測試命令和報告 一、安裝sysbench工具二、創建測試數據庫三、基于sysbench構造測試表和測試數據四、數據庫性能測試1、數據庫讀寫性能測試2、數據庫讀性能測試3、數據庫刪除性能測試4、數據庫更新索引字段性能測5、數據庫更新非索引字段性能測試6、數據庫…

windows ip助手函數了解

根據手冊,winsock編程中提供的有一類函數叫ip助手函數;比如Ipconfig函數,從名字看應該是可自己編程實現類似ipconfig命令的功能; 剛看到一個示例,是MS提供的,也屬于這一類,代碼如下, #include <winsock2.h> #include <ws2tcpip.h> #include <iphlpapi…

C++ vector類

目錄 0.前言 1.vector介紹 2.vector使用 2.1 構造函數(Constructor) 2.1.1. 默認構造函數 (Default Constructor) 2.1.2 填充構造函數 (Fill Constructor) 2.1.3 范圍構造函數 (Range Constructor) 2.1.4 拷貝構造函數 (Copy Constructor) 2.2 迭代器(Iterator) 2.2.…

十、通配符和正則表達式

10.1 通配符 通配符是由shell處理的, 它只會出現在 命令的“參數”里。當shell在“參數”中遇到了通配符 時&#xff0c;shell會將其當作路徑或文件名去在磁盤上搜尋可能的匹配&#xff1a;若符合要求的匹配存在&#xff0c;則進 行代換(路徑擴展)&#xff1b;否則就將該通配…

python安裝依賴

創建 requirement.txt 文件并填充內容 flask2.0.0 pandas1.3.3 numpy1.21.2 安裝模塊 pip install -r requirement.txt

Spring boot使用集群方式、支持ssl連接redis的方法

1、需求背景 項目需要提供一個管理界面給內部人員操作用戶信息&#xff0c;需要在修改用戶信息后刪除用戶的redis緩存。用戶所在的區域不同&#xff0c;其redis服務地址也不相同&#xff0c;因此需要管理多個redis連接&#xff0c;且redis要求以集群方式并支持ssl進行連接。 2…

Qt for android 獲取USB設備列表(一)Java方式 獲取

簡介 QtActivity 作為 Qt 應用程序的入口點&#xff0c;負責啟動和配置 Qt 應用程序的信息&#xff0c; 后面我們繼承 QtActivity 做自定義控制&#xff0c;了解一下 Activity 生命周期概念&#xff0c; 因為 QtActivity 繼承自Android的activity&#xff0c;使用周期函數完成我…

java8新特性——函數式編程詳解

目錄 一 概述1.1 背景1.2 函數式編程的意義1.3 函數式編程的發展 Lambda表達式1.1 介紹1.2 使用Lambda的好處1.3 Lambda方法1.3.1 Lambda表達式結構1.3.2 Lambda表達式的特征 1.4 Lambda的使用1.4.1 定義函數式接口1.4.2 Lambda表達式實現函數式接口1.4.3 簡化Lambda表達式1.4.…

C++學習/復習4--與類相關的概念/默認成員函數/運算符重載/Date類實現案例

一、類和對象 1.本章概要 2.C中的結構體(struct與class) 升級為類 &#xff08;1&#xff09;類及成員函數的兩種定義方式 聲明與定義分離 &#xff08;2&#xff09;權限 注意1&#xff1a;struct/class在權限上的區別 &#xff08;3&#xff09;封裝 &#xff08;4&#x…

AI學習指南數學工具篇-凸優化之對偶性與拉格朗日對偶

AI學習指南數學工具篇-凸優化之對偶性與拉格朗日對偶 在凸優化中&#xff0c;對偶性是一個非常重要的概念。通過對偶性&#xff0c;我們可以將原始問題轉化為對偶問題&#xff0c;從而更容易求解。其中&#xff0c;拉格朗日對偶問題是對偶性的一個重要應用&#xff0c;通過拉格…

《Ai學習筆記》自然語言處理 (Natural Language Processing):機器閱讀理解-基礎概念解析01

自然語言處理 (Natural Language Processing)&#xff1a; NLP四大基本任務 序列標注&#xff1a; 分詞、詞性標注 分類任務&#xff1a; 文本分類、情感分析 句子關系&#xff1a;問答系統、對話系統 生成任務&#xff1a;機器翻譯、文章摘要 機器閱讀理解的定義 Machi…

LangChain - 建立代理

本文翻譯整理自&#xff1a;Build an Agent https://python.langchain.com/v0.2/docs/tutorials/agents/ 文章目錄 一、說明概念 二、定義工具1、TavilyAPI參考&#xff1a; 2、RetrieverAPI參考&#xff1a;API參考&#xff1a; 3、工具 三、使用語言模型四、創建代理五、運行…

《安富萊嵌入式周報》第337期:超高性能信號量測量,協議分析的開源工具且核心算法開源,工業安全應用的雙通道數字I/O模組,低成本腦機接口,開源音頻合成器

周報匯總地址&#xff1a;http://www.armbbs.cn/forum.php?modforumdisplay&fid12&filtertypeid&typeid104 視頻版&#xff1a; https://link.zhihu.com/?targethttps%3A//www.bilibili.com/video/BV1PT421S7TR/ 《安富萊嵌入式周報》第337期&#xff1a;超高性…

【Spring Boot】分層開發 Web 應用程序(含實例)

分層開發 Web 應用程序 1.應用程序分層開發模式&#xff1a;MVC1.1 了解 MVC 模式1.2 MVC 和三層架構的關系 2.視圖技術 Thymeleaf3.使用控制器3.1 常用注解3.1.1 Controller3.1.2 RestController3.1.3 RequestMapping3.1.4 PathVariable 3.2 將 URL 映射到方法3.3 在方法中使用…

用戶數據報協議UDP實現可靠傳輸的思路

一、UDP協議的特點 按照報文來分割發送。不需要建立連接和維護連接。不需要接收確認。速度較快。不確保接收的順序和發送順序一樣。 二、用UDP實現可靠通信的思路 (一)接收時發送一個確認報文 實現接收確認的機制。 (二)每個報文騰出空間放置序號 發送時設置序號&#xff0c…

如何安裝虛擬機Wmware,并且在虛擬機中使用centos系統

1. 前言 大家好&#xff0c;我是jiaoxingk 本篇文章主要講解如何安裝虛擬機&#xff0c;并且在虛擬機中安裝centos系統&#xff0c;讓windows電腦也能夠使用Linux系統 2. 虛擬機的介紹 在安裝Vmware之前&#xff0c;我們先做虛擬機的介紹 虛擬機&#xff1a;通過軟件虛擬出來的…

Docker拉取鏡像報錯:x509: certificate has expired or is not yet v..

太久沒有使用docker進行鏡像拉取&#xff0c;今天使用docker-compose拉取mongo發現報錯&#xff08;如下圖&#xff09;&#xff1a; 報錯信息翻譯&#xff1a;證書已過期或尚未有效。 解決辦法&#xff1a; 1.一般都是證書問題或者系統時間問題導致&#xff0c;可以先執行 da…