OpenCV4.0 摄像头风格迁移

再按照 https://github.com/opencv/opencv/blob/3.4.0/samples/dnn/fast_neural_style.py 改为 C++ 版的摄像头风格迁移

//摄像头或视频风格转换
//按空格存一图
//OpenCV:使用VideoCapture类进行视频读取和显示

#include <opencv2\opencv.hpp>
#include <opencv2\dnn.hpp>
#include <iostream>

using namespace std;
using namespace cv;

//数字转字符串:用C++的streanstream:
#include <sstream>
#include <string>

string num2str(double i)
{
	stringstream ss;
	ss << i;
	return ss.str();
}

//----------------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<float>(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<Mat> 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);
        //}
    vectorOfChannels[0] = getPlane(blob_, n, 0)+103.939;
    vectorOfChannels[1] = getPlane(blob_, n, 1)+116.779;
    vectorOfChannels[2] = getPlane(blob_, n, 2)+123.68;

        //cv::merge(vectorOfChannels, images_.getMatRef(n));//这里会出错,是前面的create的原因?
        cv::merge(vectorOfChannels, images_);//通道合并
    }
}
//----------------cv中取出	-----------------结束

int main(int argc, char *argv[])
{

	String model[]={"mosaic.t7","candy.t7","la_muse.t7","the_scream.t7","feathers.t7","udnie.t7",//instance_norm 6个
		"the_wave.t7","starry_night.t7","la_muse_eccv16.t7","composition_vii.t7"};//eccv16 4个

	//随机取一个模型
	 cv::RNG rng((unsigned)time(NULL));
	 int num=rng.uniform(0, 1000 )% 10;
	 cout<<num<<endl;
	 cout<<model[num]<<endl;

	// 加载模型
	dnn::Net net = cv::dnn::readNetFromTorch(model[num]);

	//打开视频文件:其实就是建立一个VideoCapture结构
	VideoCapture capture(0);

	//检测是否正常打开:成功打开时,isOpened返回ture
	if(!capture.isOpened()){
		cout<<"出错了!"<<endl;			return -1;}


	//定义一个用来控制读取视频循环结束的变量
	bool stop = false;
	//承载每一帧的图像
	Mat frame;


	long currentFrame = 0;//记录用

	while(!stop)
	{
		//读取下一帧
		if(!capture.read(frame))
		{
			cout<<"读取视频失败"<<endl;
			return -1;
		}

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

	Mat inputBlob;//转换为 (1,3,h,w) 的矩阵 即:(图像数,通道,高,宽)
	inputBlob = cv::dnn::blobFromImage(frame, 1.0, Size(200, 200*h/w), Scalar(103.939, 116.779, 123.680), false, false);//
		
	// 前传
	net.setInput(inputBlob);
	Mat out = net.forward();

	Mat Styled;//4维转回3维
	//cv::dnn::imagesFromBlob(out, Styled);//由于这个函数会出错,已把它从dnn取出稍稍修改一下用
	imagesFromBlob(out, Styled);
	// 输出图片
	Styled /=255;

	Mat uStyled;
	Styled.convertTo(uStyled,CV_8U,255);//转换格式
	cv::imshow("风格图像", uStyled);
	
		

		int c = waitKey(1);
		//按下ESC或者到达指定的结束帧后退出读取视频
		if((char) c == 27 )
		{
			stop = true;
			break;
		}
		//按下空格键存图
		if(c==32){//保存一张图,接片用
			string jpg_file=""+num2str(currentFrame)+".jpg";//按位置设置文件名
			currentFrame++;

			for(unsigned int i=0,p=8-jpg_file.length();i<p;i++) //不足8个字符用0补
				jpg_file="0"+jpg_file;

			imwrite(jpg_file,uStyled);
		}
}
	//关闭视频文件
	capture.release();

	cout<<"已结束"<<endl;
	return 0;
}

感觉速度有点慢

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值