OpenCV4.0 运行快速风格迁移(Torch)

从《Python 图像风格迁移(模仿名画)》一文中看到 OpenCV 可以运行Torch 模型。也来试试,

先用vs2008编译一个cv3.3,

再下一个"fast-neural-style-master"包,按包中地址下载几个模型,下面是其中一个:

"http://cs.stanford.edu/people/jcjohns/fast-neural-style/models/instance_norm/candy.t7"

运行:

	// 加载模型
	dnn::Net net = cv::dnn::readNetFromTorch("candy.t7");

这里出错了,candy.t7中的部分Torch层在CV3.3不支持。

先来看一下模型的各层名称,和 fast-neural-style-tensorflow-master 比一比、有什么不同:

nn.Sequential
nn.SpatialReflectionPadding	补边
nn.SpatialConvolution		卷积		3-->16扩维
nn.InstanceNormalization	实例正则化
nn.SpatialBatchNormalization	批正则化
nn.ReLU				relu激励
nn.SpatialConvolution		卷积		16-->32扩维,并2倍下采样
nn.InstanceNormalization
nn.SpatialBatchNormalization
nn.ReLU
nn.SpatialConvolution		卷积		32-->64扩维,并2倍下采样
nn.InstanceNormalization
nn.SpatialBatchNormalization
nn.ReLU
--------------------------------残差块 1
nn.Sequential
nn.ConcatTable
nn.Sequential
nn.SpatialConvolution		卷积		64-->64维不变
nn.InstanceNormalization
nn.SpatialBatchNormalization
nn.ReLU
nn.SpatialConvolution		卷积		64-->64维不变
nn.InstanceNormalization
nn.SpatialBatchNormalization
nn.ShaveImage			去边(边宽=补边宽/残差块数)
nn.CAddTable			矩阵相加
--------------------------------残差块 2
nn.Sequential
nn.ConcatTable
nn.Sequential
nn.SpatialConvolution
nn.InstanceNormalization
nn.SpatialBatchNormalization
nn.ReLU
nn.SpatialConvolution
nn.InstanceNormalization
nn.SpatialBatchNormalization
nn.ShaveImage
nn.CAddTable
--------------------------------残差块 3
nn.Sequential
nn.ConcatTable
nn.Sequential
nn.SpatialConvolution
nn.InstanceNormalization
nn.SpatialBatchNormalization
nn.ReLU
nn.SpatialConvolution
nn.InstanceNormalization
nn.SpatialBatchNormalization
nn.ShaveImage
nn.CAddTable
--------------------------------残差块 4
nn.Sequential
nn.ConcatTable
nn.Sequential
nn.SpatialConvolution
nn.InstanceNormalization
nn.SpatialBatchNormalization
nn.ReLU
nn.SpatialConvolution
nn.InstanceNormalization
nn.SpatialBatchNormalization
nn.ShaveImage
nn.CAddTable
--------------------------------残差块 5
nn.Sequential
nn.ConcatTable
nn.Sequential
nn.SpatialConvolution
nn.InstanceNormalization
nn.SpatialBatchNormalization
nn.ReLU
nn.SpatialConvolution
nn.InstanceNormalization
nn.SpatialBatchNormalization
nn.ShaveImage
nn.CAddTable
nn.SpatialFullConvolution	全卷积		64-->32减维,并2倍上采样
nn.InstanceNormalization
nn.SpatialBatchNormalization
nn.ReLU
nn.SpatialFullConvolution	全卷积		32-->16减维,并2倍上采样
nn.InstanceNormalization
nn.SpatialBatchNormalization
nn.ReLU
nn.SpatialConvolution		卷积		16-->3减维
nn.Tanh
nn.MulConstant
nn.TotalVariation

相差不是很大,中间层维数是哪个tensorflow的一半,这个速度应该会快一点。

看来要编译CV4.0了,4.0对于vs2008已经没办法了,由于空间不足,就用mingw32编译吧

下了一个mingw32-4.92,费了一点波折,成功了

《Python OpenCV 图像风格迁移(模仿名画)》一文是、Python调用OpenCV, 这个暂时还不会,先搞一个C++的吧:

//核心代码: 加载模型 -> 读取图片 -> 前传计算 -> 输出图片
#include 
#include 
#include 

using namespace cv;
using namespace std;
 
//----------------cv中取出	-----------------开始
const int CV_MAX_DIM = 32;
Mat getPlane(const Mat &m, int n, int cn)
{
    CV_Assert(m.dims > 2);
    int sz[CV_MAX_DIM];
    for(int i = 2; i < m.dims; i++)
    {
        sz[i-2] = m.size.p[i];
    }
    return Mat(m.dims - 2, sz, m.type(), (void*)m.ptr(n, cn));
}

//用于单图,如果多图还要再修改
void imagesFromBlob(const cv::Mat& blob_, OutputArrayOfArrays images_)
{
    //blob 是浮点精度的4维矩阵
    //blob_[0] = 批量大小 = 图像数
    //blob_[1] = 通道数
    //blob_[2] = 高度
    //blob_[3] = 宽度    
	CV_Assert(blob_.depth() == CV_32F);
    CV_Assert(blob_.dims == 4);

    //images_.create(cv::Size(1, blob_.size[0]),blob_.depth() );//多图,不明白为什么?
    images_.create(blob_.size[2],blob_.size[3],blob_.depth() );//创建一个图像
	

    std::vector vectorOfChannels(blob_.size[1]);
    //for (int n = 0; n <  blob_.size[0]; ++n) //多个图
    {int n = 0;                                //只有一个图
        for (int c = 0; c < blob_.size[1]; ++c)
        {
            vectorOfChannels[c] = getPlane(blob_, n, c);
        }
        //cv::merge(vectorOfChannels, images_.getMatRef(n));//这里会出错,是前面的create的原因?
        cv::merge(vectorOfChannels, images_);//通道合并
    }
}
//----------------cv中取出	-----------------结束

int main(int argc, char *argv[])
{
	char jpgname[256];//图像名
	if( argc == 2 )
		strcpy_s(jpgname, argv[1]);
	else		
		strcpy_s(jpgname, "5c6.jpg");

	double time1 = static_cast(getTickCount());  //记录起始时间

	// 加载模型
	dnn::Net net = cv::dnn::readNetFromTorch("mosaic.t7");

	// 读取图片
	Mat image = cv::imread(jpgname);

	size_t h=image.rows;// 行数(高度)
	size_t w=image.cols;// 列数(宽度)
	cout<<	w <

 

效果图:

OpenCV4.0 运行快速风格迁移(Torch)_第1张图片

  这是mosaic风格的

和《fast-neural-style-master》一文比有点暗,应该是后处理有点不同吧,原文相当于做了一个归一化。

 

你可能感兴趣的:(风格转换)