风格迁移
图像风格迁移、色彩填充与色彩变换等,严格意义上来说都属于计算机视觉任务中图像处理的分支。它们输入的是图像,输出的也是图像,过程实现图像到图像的内容与风格的转换,深度学习在这类图像处理任务上也取得了良好的效果。OpenCV4在DNN模块中支持常见风格迁移的图像转换模型,该模型是李飞飞等人发表的感知损失实时分割迁移与超分辨率论文的torch版本实现,模型的下载地址为:
https://github.com/jcjohnson/fast-neural-style
模型介绍
模型支持任意尺寸的图像输入,输出NCHW的四维数据,其中N=1,C=3表示彩色图像,H跟W分别表示图像的高与宽。作者提供了很多种预训练的风格迁移模型以供读者使用,这里下载了下面九种风格转换的预训练模型:
composition_vii.t7 starry_night.t7 la_muse.t7 the_wave.t7 mosaic.t7 the_scream.t7 feathers.t7 candy.t7 udnie.t7
这些模型都是torch框架支持的二进制权重文件,加载模型之后,就可以调用forward得到结果,通过对输出结果反向加上均值,rescale到0~255的RGB色彩空间,即可得到转换后的风格图像,如图12-8所示,是九种变换风格的效果演示。
OpenCV4 C++ 风格迁移演示的相关代码如下:
int main(int argc, char** argv) { int index = 0; VideoCapture capture = VideoCapture(0); Net net = readNetFromTorch(format("%s%s", base_dir.c_str(), styles[index].c_str())); net.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE); net.setPreferableTarget(DNN_TARGET_CPU); Mat frame; while (true) { capture.read(frame); imshow("input", frame); Mat blobImage = blobFromImage(frame, 1.0, Size(width, height), Scalar(103.939, 116.779, 123.68), false, false); net.setInput(blobImage); Mat out = net.forward(); vector<double> layersTimings; double freq = getTickFrequency() / 1000; double time = net.getPerfProfile(layersTimings) / freq; printf("execute time : %.2f ms\n", time); int ch = out.size[1]; int h = out.size[2]; int w = out.size[3]; Mat result = Mat::zeros(Size(w, h), CV_32FC3); float* data = out.ptr<float>(); // decode 4-d Mat object for (int c = 0; c < ch; c++) { for (int row = 0; row < h; row++) { for (int col = 0; col < w; col++) { result.at<Vec3f>(row, col)[c] = *data++; } } } // 整合结果输出 printf("channels : %d, height: %d, width: %d \n", ch, h, w); add(result, Scalar(103.939, 116.779, 123.68), result); result /= 255.0; // 中值滤波 medianBlur(result, result, 5); Mat dst; resize(result, dst, frame.size()); imshow("styled-video", dst); // ESC means exit char c = waitKey(1); if (c == 27) { break; } } waitKey(0); return 0; }
以上演示来自《OpenCV应用开发:入门、进阶与工程化实践》一书第十二章 第五小节内容。学习OpenCV深度神经网络模型推理技能,相关代码解释与说明查看本书即可获取,