本文主要介紹OpenCV的DNN模塊的使用。OpenCV的DNN模塊自從contrib倉庫開始,就是隻支持推理,不支持訓練。可是僅僅只是推理方面,也夠強大了。如今OpenCV已經支持TensorFlow、Pytorch/Torch、Caffe、DarkNet等模型的讀取。本文們就以風格遷移爲例,來看一下OpenCV DNN模塊的用法。
python
相比於複雜而耗時的模型訓練過程,模型推理就顯得簡單多了。簡單來講,過程就是:git
- 加載模型
- 輸入圖像預處理(跟訓練過程同樣的方式,加強除外)
- 模型推理
1. 加載模型
由於OpenCV只支持推理,因此首先你須要有一個訓練好的模型。OpenCV支持全部主流框架的大部分模型。從OpenCV的readNet
系列函數就能夠看出來:github
readNetFromCaffe
readNetFromTensorflow
readNetFromTorch
readNetFromDarknet
readNetFromONNX
readNetFromModelOptimizer
本文所用風格遷移模型是李飛飛的文章<<Perceptual Losses for Real-Time Style Transfer and Super-Resolution>>
開源的Torch/Lua
的模型,地址在這裏:https://github.com/jcjohnson/fast-neural-style
。他們提供了十種風格遷移的模型,模型的下載腳本在:https://github.com/jcjohnson/fast-neural-style/blob/master/models/download_style_transfer_models.sh
。顯然這裏須要用OpenCV的readNetFromTorch
函數去加載模型,因爲模型較多,這裏提供的函數能夠選擇加載指定的模型:網絡
import cv2 model_base_dir = "/cvpy/style_transfer/models/" d_model_map = { 1: "udnie", 2: "la_muse", 3: "the_scream", 4: "candy", 5: "mosaic", 6: "feathers", 7: "starry_night" } def get_model_from_style(style: int): """ 加載指定風格的模型 :param style: 模型編碼 :return: model """ model_name = d_model_map.get(style, "mosaic") model_path = model_base_dir + model_name + ".t7" model = cv2.dnn.readNetFromTorch(model_path) return model
2. 圖像預處理
在OpenCV中,輸入給模型的圖像須要首先被構建成一個4維的Blob
,看到Blob
這個詞感受是收到了Caffe
的影響。在構建Blob
的時候會作一些諸如resize
、歸一化和縮放之類的簡單預處理。OpenCV
提供的函數爲:框架
blobFromImage(image, scalefactor=None, size=None, mean=None, swapRB=None, crop=None, ddepth=None)
函數
這個函數在構建Blob
的以前會先作以下計算:測試
(image - mean) * scalefactor
。網站
函數中的swapRB
參數的含義是swap Blue and Red channels
,乾的是cvtColor(image, cv2.COLOR_BGR2RGB)
的事情。編碼
本文的風格遷移所須要作的圖像預處理很簡單,只是三通道分別減去均值便可。代碼以下:url
(h, w) = img.shape[:2] blob = cv2.dnn.blobFromImage(img, 1.0, (w, h), (103.939, 116.779, 123.680), swapRB=False, crop=False)
3. 模型推理
模型推理過程就是神經網絡模型進行一次前向傳播,在OpenCV中,用如下可讀性很是強的兩行代碼便可完成:
net.setInput(blob) output = net.forward()
把第一節構建的blob
輸入給模型,而後執行一次前向傳播。
獲得輸出output
再作一些處理使得咱們能夠更好的可視化圖像:
# reshape輸出結果, 將減去的平均值加回來,並交換各顏色通道 output = output.reshape((3, output.shape[2], output.shape[3])) output[0] += 103.939 output[1] += 116.779 output[2] += 123.680 output = output.transpose(1, 2, 0)
效果展現
找一張測試圖片,選擇不一樣的風格,試一下效果。
想用本身的圖片風格遷移一下嗎?cvpy.net
網站剛部署成功,來試試吧。
嘗試地址:傳本身的圖片嘗試一下吧!