一、opencv的示例模型文件
使用Torch模型,下载地址:fast_neural_style_eccv16_starry_night.t7和fast_neural_style_instance_norm_feathers.t7。
二、示例代码
c++和py代码流程均较简单:图像转Blob,forward,处理输出结果,显示。
c++代码如下:
// This script is used to run style transfer models from '
// https://github.com/jcjohnson/fast-neural-style using OpenCV
#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace cv::dnn;
using namespace std;
int main(int argc, char **argv)
{
string modelBin = "../../data/testdata/dnn/fast_neural_style_instance_norm_feathers.t7";
string imageFile = "../../data/image/chicago.jpg";
float scale = 1.0;
cv::Scalar mean { 103.939, 116.779, 123.68 };
bool swapRB = false;
bool crop = false;
bool useOpenCL = false;
Mat img = imread(imageFile);
if (img.empty()) {
cout << "Can't read image from file: " << imageFile << endl;
return 2;
}
// Load model
Net net = dnn::readNetFromTorch(modelBin);
if (useOpenCL)
net.setPreferableTarget(DNN_TARGET_OPENCL);
// Create a 4D blob from a frame.
Mat inputBlob = blobFromImage(img,scale, img.size(),mean,swapRB,crop);
// forward netword
net.setInput(inputBlob);
Mat output = net.forward();
// process output
Mat(output.size[2], output.size[3], CV_32F, output.ptr<float>(0, 0)) += 103.939;
Mat(output.size[2], output.size[3], CV_32F, output.ptr<float>(0, 1)) += 116.779;
Mat(output.size[2], output.size[3], CV_32F, output.ptr<float>(0, 2)) += 123.68;
std::vector<cv::Mat> ress;
imagesFromBlob(output, ress);
// show res
Mat res;
ress[0].convertTo(res, CV_8UC3);
imshow("reslut", res);
imshow("origin", img);
waitKey();
return 0;
}
python代码如下:
from __future__ import print_function
import cv2 as cv
import numpy as np
import argparse
parser = argparse.ArgumentParser(
description='This script is used to run style transfer models from '
'https://github.com/jcjohnson/fast-neural-style using OpenCV')
parser.add_argument('--input', help='Path to image or video. Skip to capture frames from camera')
parser.add_argument('--model', help='Path to .t7 model')
parser.add_argument('--width', default=-1, type=int, help='Resize input to specific width.')
parser.add_argument('--height', default=-1, type=int, help='Resize input to specific height.')
parser.add_argument('--median_filter', default=0, type=int, help='Kernel size of postprocessing blurring.')
args = parser.parse_args()
args.model = "../data/testdata/dnn/fast_neural_style_instance_norm_feathers.t7"
args.input = "../data/image/chicago.jpg"
net = cv.dnn.readNetFromTorch(cv.samples.findFile(args.model))
net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV);
if args.input:
cap = cv.VideoCapture(args.input)
else:
cap = cv.VideoCapture(0)
cv.namedWindow('Styled image', cv.WINDOW_NORMAL)
while cv.waitKey(1) < 0:
hasFrame, frame = cap.read()
if not hasFrame:
cv.waitKey()
break
inWidth = args.width if args.width != -1 else frame.shape[1]
inHeight = args.height if args.height != -1 else frame.shape[0]
inp = cv.dnn.blobFromImage(frame, 1.0, (inWidth, inHeight),
(103.939, 116.779, 123.68), swapRB=False, crop=False)
net.setInput(inp)
out = net.forward()
out = out.reshape(3, out.shape[2], out.shape[3])
out[0] += 103.939
out[1] += 116.779
out[2] += 123.68
out /= 255
out = out.transpose(1, 2, 0)
t, _ = net.getPerfProfile()
freq = cv.getTickFrequency() / 1000
print(t / freq, 'ms')
if args.median_filter:
out = cv.medianBlur(out, args.median_filter)
cv.imshow('Styled image', out)
三、演示
fast_neural_style_instance_norm_feathers.t7的演示效果
fast_neural_style_eccv16_starry_night.t7的演示效果: