OpenCV DNN 模块-风格迁移

本文主要介绍OpenCV的DNN模块的使用。OpenCV的DNN模块自从contrib仓库开始,就是只支持推理,不支持训练。可是仅仅只是推理方面,也够强大了。如今OpenCV已经支持TensorFlow、Pytorch/Torch、Caffe、DarkNet等模型的读取。本文们就以风格迁移为例,来看一下OpenCV DNN模块的用法。
git

相比于复杂而耗时的模型训练过程,模型推理就显得简单多了。简单来讲,过程就是:github

  1. 加载模型
  2. 输入图像预处理(跟训练过程同样的方式,加强除外)
  3. 模型推理

1. 加载模型

由于OpenCV只支持推理,因此首先你须要有一个训练好的模型。OpenCV支持全部主流框架的大部分模型。从OpenCV的readNet系列函数就能够看出来:web

  • 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)app

这个函数在构建Blob的以前会先作以下计算:框架

(image - mean) * scalefactor编辑器

函数中的swapRB参数的含义是swap Blue and Red channels,干的是cvtColor(image, cv2.COLOR_BGR2RGB)的事情。函数

本文的风格迁移所须要作的图像预处理很简单,只是三通道分别减去均值便可。代码以下:测试

(h, w) = img.shape[:2]
blob = cv2.dnn.blobFromImage(img, 1.0, (w, h), (103.939116.779123.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(120)

效果展现

找一张测试图片,选择不一样的风格,试一下效果。

想用本身的图片风格迁移一下吗?

体验请到

www.cvpy.net

(微信内可直接右键搜一搜触达)

往期精彩

一键智能抠图-原理与实现 | 可在线体验









本文分享自微信公众号 - CVPy(x-cvpy)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索