本文主要介紹OpenCV的DNN模塊的使用。OpenCV的DNN模塊自從contrib倉庫開始塌西,就是只支持推理他挎,不支持訓(xùn)練。但是僅僅只是推理方面捡需,也夠強(qiáng)大了“旖埃現(xiàn)在OpenCV已經(jīng)支持TensorFlow、Pytorch/Torch站辉、Caffe呢撞、DarkNet等模型的讀取。本文們就以風(fēng)格遷移為例饰剥,來看一下OpenCV DNN模塊的用法殊霞。
相比于復(fù)雜而耗時的模型訓(xùn)練過程,模型推理就顯得簡單多了汰蓉。簡單來說绷蹲,過程就是:
- 加載模型
- 輸入圖像預(yù)處理(跟訓(xùn)練過程一樣的方式,增強(qiáng)除外)
- 模型推理
1. 加載模型
因為OpenCV只支持推理,所以首先你需要有一個訓(xùn)練好的模型祝钢。OpenCV支持所有主流框架的大部分模型比规。從OpenCV的readNet
系列函數(shù)就可以看出來:
readNetFromCaffe
readNetFromTensorflow
readNetFromTorch
readNetFromDarknet
readNetFromONNX
readNetFromModelOptimizer
本文所用風(fēng)格遷移模型是李飛飛的文章<<Perceptual Losses for Real-Time Style Transfer and Super-Resolution>>
開源的Torch/Lua
的模型,地址在這里:https://github.com/jcjohnson/fast-neural-style
拦英。他們提供了十種風(fēng)格遷移的模型苞俘,模型的下載腳本在:https://github.com/jcjohnson/fast-neural-style/blob/master/models/download_style_transfer_models.sh
。顯然這里需要用OpenCV的readNetFromTorch
函數(shù)去加載模型龄章,由于模型較多,這里提供的函數(shù)可以選擇加載指定的模型:
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):
"""
加載指定風(fēng)格的模型
: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. 圖像預(yù)處理
在OpenCV中乞封,輸入給模型的圖像需要首先被構(gòu)建成一個4維的Blob
做裙,看到Blob
這個詞感覺是收到了Caffe
的影響。在構(gòu)建Blob
的時候會做一些諸如resize
肃晚、歸一化和縮放之類的簡單預(yù)處理锚贱。OpenCV
提供的函數(shù)為:
blobFromImage(image, scalefactor=None, size=None, mean=None, swapRB=None, crop=None, ddepth=None)
這個函數(shù)在構(gòu)建Blob
的之前會先做如下計算:
(image - mean) * scalefactor
。
函數(shù)中的swapRB
參數(shù)的含義是swap Blue and Red channels
关串,干的是cvtColor(image, cv2.COLOR_BGR2RGB)
的事情拧廊。
本文的風(fēng)格遷移所需要做的圖像預(yù)處理很簡單,只是三通道分別減去均值即可晋修。代碼如下:
(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. 模型推理
模型推理過程就是神經(jīng)網(wǎng)絡(luò)模型進(jìn)行一次前向傳播吧碾,在OpenCV中,用以下可讀性非常強(qiáng)的兩行代碼即可完成:
net.setInput(blob)
output = net.forward()
把第一節(jié)構(gòu)建的blob
輸入給模型墓卦,然后執(zhí)行一次前向傳播倦春。
得到輸出output
再做一些處理使得我們可以更好的可視化圖像:
# reshape輸出結(jié)果, 將減去的平均值加回來,并交換各顏色通道
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)
效果展示
找一張測試圖片落剪,選擇不同的風(fēng)格睁本,試一下效果。
想用自己的圖片風(fēng)格遷移一下嗎忠怖?cvpy.net
網(wǎng)站剛部署成功呢堰,來試試吧。
嘗試地址:傳自己的圖片嘗試一下吧凡泣!