OpenCV 風格遷移、DNN模塊 案例解析及實現

圖像風格遷移是計算機視覺領域極具趣味性的技術之一 —— 它能將普通照片(內容圖像)與藝術畫作(風格圖像)的特征融合,生成兼具 “內容輪廓” 與 “藝術風格” 的新圖像。OpenCV 的 DNN(深度神經網絡)模塊為風格遷移提供了輕量、便捷的實現方案,無需搭建復雜的深度學習框架,僅通過加載預訓練模型即可快速完成風格遷移。本文將從基礎概念入手,詳解 DNN 模塊特性,最終通過完整案例實現 “照片轉梵高星空風”“照片轉糖果風” 等效果。

一、核心概念:風格遷移與 OpenCV DNN 模塊

在動手寫代碼前,我們需要先理清兩個關鍵概念:風格遷移的原理OpenCV DNN 模塊的定位,這是理解后續實戰的基礎。

1. 什么是圖像風格遷移?

圖像風格遷移的核心目標是 “內容與風格的分離與重組”:

  • 內容圖像:提供圖像的 “結構信息”,比如照片中的建筑、人物、風景輪廓(例:黃鶴樓照片)。
  • 風格圖像:提供圖像的 “藝術風格信息”,比如梵高《星空》的漩渦筆觸、莫奈《睡蓮》的色彩暈染(例:梵高《星空》)。
  • 生成圖像:保留內容圖像的結構,同時賦予風格圖像的藝術特征(例:“梵高星空風” 的黃鶴樓)。

在 OpenCV 中,風格遷移的實現依賴預訓練的神經網絡模型—— 這些模型已通過大量 “內容 - 風格” 圖像對訓練完成,能自動學習 “如何提取內容特征”“如何遷移風格特征”,我們只需加載模型并傳入內容圖像即可生成結果。

2. OpenCV DNN 模塊:輕量的深度學習推理工具

DNN(Deep Neural Networks)是 OpenCV 中專門用于深度學習模型推理的模塊,它不負責模型訓練,僅專注于 “加載已訓練模型并完成預測”,這使其具備以下核心優勢:

DNN 模塊實現風格遷移的核心流程可概括為:
加載預訓練風格模型 → 內容圖像預處理 → 模型推理(風格遷移) → 輸出結果后處理 → 顯示/保存生成圖像

二、關鍵技術:圖像預處理與模型加載


風格遷移的效果好壞,除了依賴預訓練模型,還與 “圖像預處理” 和 “模型加載方式” 密切相關。下面詳解這兩個關鍵步驟的技術細節。


1. 圖像預處理:讓圖像符合模型輸入要求


深度學習模型對輸入圖像的格式有嚴格要求(如尺寸、通道順序、數據范圍),而 OpenCV 讀取的原始圖像(BGR 格式、像素值 0-255)通常無法直接傳入模型,需要通過 **cv2.dnn.blobFromImage()** 函數進行預處理,將其轉換為模型可識別的 “四維 Blob 數據”(格式:N×C×H×W,其中 N = 批量大小、C = 通道數、H = 高度、W = 寬度)。
cv2.dnn.blobFromImage()參數詳解
該函數是 DNN 模塊的 “預處理核心”,支持縮放、裁剪、通道轉換、均值減法等操作,參數如下:

輔助工具:自動縮放圖像函數
若原始圖像尺寸過大(如 4K 照片),會導致模型推理速度慢且占用內存高。可自定義一個 “自動縮放函數”,按指定寬度 / 高度縮放圖像,同時保持縱橫比不變:

import cv2def auto_resize(image, width=None, height=None, inter=cv2.INTER_AREA):"""自動縮放圖像(保持縱橫比):param image: 輸入原始圖像:param width: 目標寬度(若為None,則按height縮放):param height: 目標高度(若為None,則按width縮放):param inter: 插值方式(cv2.INTER_AREA適合縮小,cv2.INTER_CUBIC適合放大):return: 縮放后的圖像"""# 獲取原始圖像尺寸(h, w) = image.shape[:2]# 若未指定寬度和高度,返回原圖if width is None and height is None:return image# 若僅指定高度,按高度比例計算寬度if width is None:ratio = height / float(h)dim = (int(w * ratio), height)# 若僅指定寬度,按寬度比例計算高度else:ratio = width / float(w)dim = (width, int(h * ratio))# 執行縮放并返回結果resized = cv2.resize(image, dim, interpolation=inter)return resized

2. 模型加載:兩種常用函數對比

OpenCV DNN 模塊提供兩種加載風格模型的函數,需根據模型格式選擇:cv2.dnn.readNet()(通用)和 **cv2.dnn.readNetFromTorch()**(專門用于 Torch 格式模型)。

(1)cv2.dnn.readNetFromTorch():Torch 模型專用

風格遷移的預訓練模型多為 Torch7 格式(文件后綴.t7),該格式模型將 “架構” 和 “權重” 存儲在同一個文件中,加載時只需傳入文件路徑:

# 加載梵高星空風格模型(.t7格式)
net = cv2.dnn.readNetFromTorch("models/starry_night.t7")
(2)cv2.dnn.readNet():多格式通用

若模型為 Caffe(需.prototxt架構文件 +?.caffemodel權重文件)、TensorFlow(.pb文件)等格式,需用該函數,根據格式傳入不同參數:

# 加載Caffe格式模型(需架構文件+權重文件)
net = cv2.dnn.readNet(model="models/style.caffemodel", config="models/style.prototxt")# 加載Torch格式模型(與readNetFromTorch效果一致)
net = cv2.dnn.readNet(model="models/starry_night.t7")  # 僅需傳入模型文件

三、完整實戰:實現多風格遷移

下面通過完整代碼,實現 “加載不同風格模型 → 預處理圖像 → 推理生成 → 顯示結果” 的全流程。我們以 “黃鶴樓照片” 為內容圖像,分別遷移 “梵高星空風” 和 “糖果風”。

1. 前期準備

  • 環境搭建:安裝 OpenCV(pip install opencv-python)。
  • 模型下載:下載上述推薦的.t7格式風格模型,放在models文件夾中(與代碼同級目錄)。
  • 內容圖像:準備一張內容圖像(如huanghelou.jpg),放在代碼同級目錄。

2. 完整代碼(支持切換風格模型)

import cv2def auto_resize(image, width=None, height=None, inter=cv2.INTER_AREA):"""自動縮放圖像(保持縱橫比)"""(h, w) = image.shape[:2]if width is None and height is None:return imageif width is None:ratio = height / float(h)dim = (int(w * ratio), height)else:ratio = width / float(w)dim = (width, int(h * ratio))resized = cv2.resize(image, dim, interpolation=inter)return resizeddef style_transfer(content_img_path, model_path, target_width=600):"""圖像風格遷移核心函數:param content_img_path: 內容圖像路徑:param model_path: 風格模型路徑(.t7格式):param target_width: 內容圖像目標寬度(默認600px,平衡速度與效果):return: 風格遷移后的圖像"""# 1. 讀取并預處理內容圖像content_img = cv2.imread(content_img_path)if content_img is None:raise ValueError(f"無法讀取內容圖像,請檢查路徑:{content_img_path}")# 自動縮放圖像(避免尺寸過大導致推理緩慢)content_img_resized = auto_resize(content_img, width=target_width)(h, w) = content_img_resized.shape[:2]  # 獲取縮放后圖像尺寸# 2. 圖像預處理:轉換為DNN模型可識別的Blob格式# 參數說明:縮放因子1.0,尺寸(w,h),均值(0,0,0),交換BGR→RGB,不裁剪blob = cv2.dnn.blobFromImage(image=content_img_resized,scalefactor=1.0,size=(w, h),mean=(0, 0, 0),swapRB=True,crop=False)# 3. 加載風格模型并執行推理print(f"正在加載風格模型:{model_path}")net = cv2.dnn.readNetFromTorch(model_path)net.setInput(blob)  # 將預處理后的Blob傳入模型output = net.forward()  # 執行前向傳播,得到風格遷移結果(四維Blob:1×3×h×w)# 4. 輸出結果后處理(將四維Blob轉換為OpenCV可顯示的圖像格式)# 步驟1:重塑維度(去掉批量維度,變為3×h×w)output_reshaped = output.reshape((3, h, w))# 步驟2:歸一化(將像素值映射到0-1范圍,避免數值溢出)cv2.normalize(output_reshaped, output_reshaped, norm_type=cv2.NORM_MINMAX)# 步驟3:轉置維度(從C×H×W轉為H×W×C,符合OpenCV圖像格式)output_img = output_reshaped.transpose((1, 2, 0))# 步驟4:將像素值從0-1映射到0-255(OpenCV顯示需8位整數)output_img = (output_img * 255).astype("uint8")# 5. 顯示結果cv2.imshow("原始內容圖像", content_img_resized)cv2.imshow("風格遷移結果", output_img)print("按下ESC鍵關閉窗口")# 等待ESC鍵(27為ESC的ASCII碼),關閉窗口后釋放資源while cv2.waitKey(1) != 27:continuecv2.destroyAllWindows()return output_img# ------------------- 主程序:切換不同風格模型 -------------------
if __name__ == "__main__":# 內容圖像路徑(請根據實際情況修改)content_image_path = "huanghelou.jpg"# 風格模型路徑(可切換不同模型實現不同風格)style_models = {"梵高星空風": "models/starry_night.t7","糖果風": "models/candy.t7","文藝復興風": "models/la_muse.t7","吶喊風": "models/the_scream.t7"}# 選擇一種風格執行遷移(例如:梵高星空風)selected_style = "梵高星空風"style_model_path = style_models[selected_style]# 執行風格遷移print(f"開始執行{selected_style}遷移...")result_img = style_transfer(content_image_path, style_model_path)# (可選)保存結果圖像save_path = f"huanghelou_{selected_style}.jpg"cv2.imwrite(save_path, result_img)print(f"結果圖像已保存至:{save_path}")

3. 代碼說明與效果驗證

(1)核心流程拆解
  1. 圖像縮放:通過auto_resize()將內容圖像縮放到寬度 600px,平衡推理速度與視覺效果。
  2. Blob 轉換cv2.dnn.blobFromImage()將 BGR 圖像轉為 RGB 格式的四維 Blob,符合模型輸入要求。
  3. 模型推理:加載.t7模型后,通過net.setInput(blob)net.forward()完成風格遷移。
  4. 結果后處理:通過重塑維度、歸一化、轉置,將模型輸出的四維 Blob 轉為 OpenCV 可顯示的 8 位圖像。
(2)效果驗證
  • 運行代碼后,會彈出兩個窗口:“原始內容圖像” 和 “風格遷移結果”。
  • 按下 ESC 鍵關閉窗口后,結果圖像會自動保存為huanghelou_梵高星空風.jpg(或對應風格名稱)。
  • 切換風格時,只需修改selected_style變量(如改為 “糖果風”),即可生成不同藝術風格的圖像。

4. 常見問題與解決方案

四、總結與擴展

本文通過 “概念→技術→實戰” 的流程,詳解了 OpenCV DNN 模塊實現風格遷移的完整方案:

  • 核心優勢:無需依賴重型深度學習框架,僅用 OpenCV 即可快速實現風格遷移,適合輕量級部署。
  • 關鍵技術cv2.dnn.blobFromImage()預處理、cv2.dnn.readNetFromTorch()加載模型、結果維度轉換與歸一化。
  • 實戰價值:支持切換多種風格模型,可應用于圖像美化、文創設計、短視頻特效等場景。

擴展方向

  1. 批量風格遷移:遍歷文件夾中的所有圖像,批量生成指定風格的結果(需添加文件遍歷邏輯)。
  2. 實時攝像頭風格遷移:調用電腦攝像頭,實時捕捉畫面并應用風格遷移(類似案例 2 的攝像頭檢測邏輯,將每一幀傳入模型)。
  3. 模型優化:對于嵌入式設備()

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

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

相關文章

MySQL 日志:undo log、redo log、binlog以及MVCC的介紹

一、MySQL 日志:undo log、redo log、binlogundo log(回滾日志):是 Innodb 存儲引擎層生成的日志,實現了事務中的原子性,主要用于事務回滾和 MVCC(隔離性)。 redo log(重…

【面板數據】省及地級市農業新質生產力數據集(2002-2025年)

農業新質生產力是以科技創新為核心驅動力,以科技化、數字化、網絡化和智能化為主線,通過技術革命性突破、生產要素創新性配置、產業深度轉型升級,實現農業全要素生產率顯著躍升的先進生產力形態 本數據基于2002-2025年各省政府工作報告中關于…

20250917在榮品RD-RK3588-MID開發板的Android13系統下使用tinyplay播放wav格式的音頻

input keyevent 24 1|console:/sdcard # cat /proc/asound/cards console:/sdcard # ls -l /dev/snd/【需要打開Android13內置的音樂應用才會有聲音出來,原因未知!】 1|console:/sdcard # tinyplay /sdcard/Music/kiss8.wav -D 1 -d 020250917在榮品RD-R…

總共分為幾種IP

IP(Internet Protocol)地址根據不同的分類標準可分為多種類型,以下是常見的分類方式:按版本分類IPv4:32位地址,格式為四組十進制數字(如192.168.1.1),約43億個地址&#…

【Linux】常用命令(六)

【Linux】常用命令(六)1. yum命令1.1 基本語法1.2 常用命令2. 從服務器把數據cp到本地3. uname命令3.1 常用命令1. yum命令 全稱:Yellowdog Updater, Modified作用:是 RPM 包管理器的前端工具,用于基于 RPM 的 Linux …

go grpc開發使用

1、安裝proto 下載 Windows 版本 打開官方發布頁面 訪問 Protocol Buffers 的 GitHub Releases 頁面: 👉 https://github.com/protocolbuffers/protobuf/releases 解壓 ZIP 文件 將下載的 ZIP 文件解壓到一個你容易找到的目錄,例如&#xff1…

MyBatis分頁:PageHelper

MyBatis分頁:PageHelper 📖 前言:為什么需要分頁? 在處理大量數據時,一次性從數據庫查詢并返回所有結果是不可行的,這會帶來巨大的性能和內存開銷。分頁是解決這一問題的標準方案。而PageHelper是一個極其流…

Gin框架:構建高性能Go Web應用

Gin框架:構建高性能Go Web應用 Gin是Go語言中最受歡迎的Web框架之一,以其高性能、簡潔API和豐富的中間件支持而聞名。本文將帶你從零開始,逐步掌握Gin框架的核心概念和高級特性,并通過實際代碼示例演示如何構建高效的Web應用程序。…

IO進程——線程、IO模型

一、線程Thread1、引入1.1 概念相當于是一個輕量級的進程,為了提高系統的性能引入線程,在同一進程中可以創建多個線程,共享進程資源1.2 進程和線程比較相同點:都為操作系統提供了并發執行的能力不同點:調度和資源&…

人工智能概念:NLP任務的評估指標(BLEU、ROUGE、PPL、BERTScore、RAGAS)

文章目錄一、評估指標基礎1. 準確率(Accuracy)2. 精確率(Precision)3. 召回率(Recall)4. F1-Score5. 示例二、文本生成專用指標1. BLEU:機器翻譯與標準化文案的“質量標尺”1.1 計算流程&#x…

團隊對 DevOps 理解不統一會帶來哪些問題

團隊對DevOps理念與實踐的理解不統一、片面甚至扭曲,是導致眾多企業DevOps轉型失敗的根本原因,它將直接引發一系列深層次的、相互關聯的嚴重問題。核心體現在:轉型極易淪為“為了工具而工具”的盲目自動化,導致最核心的文化變革被…

企業級實戰:構建基于Qt、C++與YOLOv8的模塊化工業視覺檢測系統(基于QWidget)

目錄一、概述二、項目目標與技術架構2.1 核心目標2.2 技術選型2.3 軟件架構三、AI推理DLL的開發 (Visual Studio 2019)3.1 定義DLL接口 (DetectorAPI.h)3.2 實現核心功能 (DetectorAPI.cpp)四、Qt Widget GUI應用程序的開發4.1 項目配置 (.pro 文件)4.2 UI設計 (mainwindow.ui)…

SVN自動化部署工具 腳本

SVN自動化部署工具 功能概述 這是一個自動化部署SVN倉庫的bash腳本,主要功能包括: 自動安裝SVN服務(如未安裝) 創建SVN項目倉庫 配置多用戶權限 設置自動同步到網站目錄 提供初始檢出功能 下載地址 https://url07.ctfile…

Facebook主頁變現功能被封?跨境玩家該如何申訴和預防

不少跨境玩家在運營Facebook公共主頁時,最期待的就是通過變現工具獲得穩定收入。但現實中,經常會遇到一個扎心的問題:主頁好不容易做起來,卻突然收到提示——“你的變現功能已被停用”。這意味著收入中斷,甚至可能導致…

安裝es、kibana、logstash

下載 elk 下載地址 elasticsearch地址: https://www.elastic.co/cn/downloads/elasticsearch kibana地址: https://www.elastic.co/cn/downloads/kibana logstash地址: https://www.elastic.co/cn/downloads/logstash 解壓elk 創建es全家桶文件夾 cd /usr/local mkdir elk …

Django admin 后臺開發案例【字段/圖片】

這是一個簡單的django admin 管理后臺,這個應用案例主要是給運營人員進行填寫數據 主要功能包括: 上傳圖片功能【選擇上傳時可以預覽】【替換已有數據中的圖片時可以預覽新舊圖片】 每條數據都將會記錄操作歷史。記錄操作人是誰?修改內容是什么?并且定位責任到某一員。 …

【C++】const和static的用法

目錄🚀前言💻const:“只讀”的守護者💯修飾普通變量💯修飾指針💯修飾函數💯修飾類成員💯修飾對象🌟static:“靜態存儲”與“作用域控制”💯修飾全…

F019 vue+flask海外購商品推薦可視化分析系統一帶一路【三種推薦算法】

文章結尾部分有CSDN官方提供的學長 聯系方式名片 B站up: 麥麥大數據 關注B站,有好處! 編號: F019 關鍵詞:海外購 推薦系統 一帶一路 python 視頻 VueFlask 海外購電商大數據推薦系統源碼 (三種推薦算法 全新界面布局…

【大數據專欄】流式處理框架-Apache Fink

Apache Fink 1 前言 1.1 功能 1.2 用戶 國際 國內 1.3 特點 ◆ 結合Java、Scala兩種語言 ◆ 從基礎到實戰 ◆ 系統學習Flink的核心知識 ◆ 快速完成從入門到上手企業開發的能力提升 1.4 安排 ◆ 初識Flink ◆ 編程模型及核心概念 ◆ DataSet API編程 ◆ Data…

向內核社區提交補丁

一、背景 內核的版本一直以來一直在持續迭代,離不開眾多開發者的貢獻。有時候我們會根據項目要求基于現有的內核版本開發一些新的功能或者修復掉一些特定場下的問題,我們是可以將其提交給社區的。 一般提交社區有兩個基本原則,一是提交的補…