你想要一份“搞怪”型画风的照片么?看这里,风格迁移帮你搞定!

1,383 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第33天,点击查看活动详情


项目需求

  趁着双休,有属于自己的时间了,赶紧给自己做几张“搞怪”画风照片(本文后面会附上照片),现在需求如下:

  1. 输入自己的照片;
  2. 通过某种手段可以获得到比较搞怪画风的照片;
  3. 这种手段具备一定的泛化能力。

注意事项: 本文着重于实践操作,不过讲解源理,望见晾!

需求分析

  上述需求不禁让我想起了初学GAN时候的风格迁移网络,该类型的网络可以正好满足上述需求,于是自己在网上搜刮下来了一些训练好的权重给自己使用。(双休在家,无GPU训练)

  实践步骤逻辑:

  1. CV读取图像;
  2. 读取网络Net;
  3. 调整图像的尺寸和格式;
  4. 计算网络对原图像处理的结果;
  5. 输出结果的尺寸和通道数;
  6. 将输出结果存放到图像中去;
  7. 获取原图像的通道数及均值;
  8. 恢复图像剔除掉的均值;
  9. 对输出图像进行归一化;
  10. 显示结果搞怪图

实践调试

  在电脑里面找到了自己以前做人脸检测的样图,现在正好可以拿来使用以下: 在centos7中运行如下代码,创建CMakeLists.txt 进行cmake和make即可获取下面的图像。

#include <opencv2/opencv.hpp>
#include <iostream>
#include<vector>
#include<string>

using namespace cv;
using namespace cv::dnn;
using namespace std;

int main()
{
	Mat image = imread("/home/kiven/Demo/Imgs/lena.png");
	String models[5] = { "Net1.t7","Net2.t7","Net3.t7","Net4.t7","Net5.t7" };
	for (int i = 0; i < 5; i++)
	{
		Net net = readNet(models[i]);
		Scalar imgaeMean = mean(image);

		Mat blobImage = blobFromImage(image, 1.0, Size(256, 256), imgaeMean, false, false);

		net.setInput(blobImage);
		Mat output = net.forward();

		int outputChannels = output.size[1];
		int outputRows = output.size[2];
		int outputCols = output.size[3];

		Mat result = Mat::zeros(Size(outputCols, outputRows), CV_32FC3);
		float* data = output.ptr<float>();
		for (int channel = 0; channel < outputChannels; channel++)
		{
			for (int row = 0; row < outputRows; row++)
			{
				for (int col = 0; col < outputCols; col++)
				{
					result.at<Vec3f>(row, col)[channel] = *data++;
				}
			}
		}
		result = result + imgaeMean;
		result = result / 255.0;
		resize(result, result, image.size());
		//显示结果
		string OutImgName = format("/home/kiven/Demo/SaveImgs/%d.jpg", i); 
		imwrite(OutImgName, result);
	}

	return 0;
}
2022-07-23-141938.jpg sendpix0.jpg sendpix1.jpg sendpix2.jpg sendpix3.jpg sendpix4.jpg