C++ 实现 超分 Meta-SR

Meta-SR(任意放大倍数的超分辨率),大概意思是 :可以是非整数倍的,并且只要一个模型(就可以实现2,3,4 倍及它们之中间倍数,比如,2.3, 3.5 倍等)

在《Meta-SR--master》中提供了 一个训练好的模型 (百度盘),这里用C++实现下(便于没有安装Pytorch的电脑运行)。

分成 特征学习、元放大  两块。

 

先定义数据池,把训练模型数据载入:

struct 层数据
{
	int 权重长度;
	float *	权重_数据;
	int 偏移长度; 
	float *	偏移_数据;
	int 输入维度;
	int	输出维度;
	int 核宽;
};

struct Linear权重//这个全连接以前是直接用“层数据”,并且用卷积代替这里的torch.nn.Linear
{
	int 权重长度;
	float *	权重_数据;
	int 偏移长度; 
	float *	偏移_数据;
	int 输入维度;
	int	输出维度;
};



struct 密集残差块 // 8+1个卷积层
{
	//输入       0; -->64

	//0 连续存储 64
	层数据 * conv1;//64-->64

	//0,1 连续存储 128
	层数据 * conv2;//128-->64

	//0,1,2 连续存储 192
	层数据 * conv3;//192-->64

	//0,1,2,3 连续存储 256
	层数据 * conv4;//256-->64  
	
	//0,1,2,3 ,4连续存储 320
	层数据 * conv5;//320-->64  
	
	层数据 * conv6;//384-->64  
	层数据 * conv7;//448-->64  
	层数据 * conv8;//512-->64    

	层数据 * conv9;//576-->64    局部特征融合 1x1卷积
	
};


struct  Meta_SR模型
{
	层数据 * sub_mean;//减均值
	层数据 * add_mean;//加均值
    //浅层特征提取
	层数据 * conv1;//3->64
	层数据 * conv2;//64->64

	//密集残差块
	int 密集残差块数量;//16块
	密集残差块 * 块;

	//16个密集残差块连续存储 1024
	层数据 * conv3;	//1024-->64 特征融合 1x1卷积
	层数据 * conv4; //64-->64

	//全局残差相加

	//放大
	Linear权重 * Pos2Weight1; //in:3,  out:256
	Linear权重 * Pos2Weight2; //in:256,out:1728

	
	//构造函数
	 Meta_SR模型();

};

主函数:

void  Meta_SR(char * savefilename, Meta_SR模型 & sr)
{

		
	int wid=bmp.width;
	int hei=bmp.height;
		cout<<"输入图像宽度:"<<wid<<endl;
		cout<<"        高度:"<<hei<<endl;

	卷积层 rgb(wid,hei,3);
	rgb.data=new float[wid * hei * 3 ]; 

	//jpg转换为RGB卷积层
	bmp2RGB(rgb);



	//---------------特征学习模块----------------------->
	层数据 * 层;

	//两个卷积层 交替前传(源,目标)
			
	卷积层 * di=(卷积层 *)malloc(sizeof(卷积层));
		di->width=1;
		di->height=1;
		di->depth=1;
		di->data=new float[1 ]; 

	卷积层 *源,*目标;
	源 = &rgb;
	
	目标 = di;

	int pad;

		RGB2BGR(*源);


	卷积前传无RELU(sr.sub_mean);

	cout<<"输入层..."<<endl;
	卷积前传无RELU(sr.conv1);

	//备份
	卷积层 conv1备份(wid,hei,源->depth);//f__1
	conv1备份.data=new float[wid * hei * 源->depth ]; 
	卷积层复制(源,&conv1备份);


	卷积前传无RELU(sr.conv2);



	//第二部分 密集残差块
	密集残差块总成(sr,*源);
			cout<<"GFF_out:";
		
	卷积层相加(&conv1备份,源);del卷积层(conv1备份);
	

	cout<<"当前宽,高,深度:"<<源->width<<","<<源->height<<","<<源->depth<<endl;

	卷积层 x(1,1);
	Resize卷积层(x,源->width,源->height,源->depth);
	卷积层复制(源,&x);

	//---------------特征学习模块-----------------------<


	//--------------- 元放大模块 ----------------------->
	cout<<"矩阵宽,高:"<<源->width<<","<<源->height<<endl;

	float scale=2.0f;//可以是小数倍数
		cout<<"\n"<< scale<<" 倍\n\n";
	int scale_int=(int)ceil(scale);

		cout<<"倍数选择矩阵:\n";
	void  input_matrix_wpn(int inH,int inW,float scale,卷积层 &out);//
	input_matrix_wpn(源->height,源->width,scale,*源);


	cout<<"当前宽,高,深度:"<<源->width<<","<<源->height<<","<<源->depth<<endl;

	vl_nnLinear(源,目标,sr.Pos2Weight1);
	swap(源,目标);
	cout<<"当前宽,高,深度:"<<源->width<<","<<源->height<<","<<源->depth<<endl;

	vl_nnrelu(源);
	vl_nnLinear(源,目标,sr.Pos2Weight2);
	swap(源,目标);
	cout<<"当前宽,高,深度:"<<源->width<<","<<源->height<<","<<源->depth<<endl;

	删除模型数据(sr);

		cout<<"多维前传:\n";
	多维前传(x,*源,scale_int);

	//--------------- 元放大模块 -----------------------<

	wid = 源->width;hei = 源->height;

	//加均值
	后处理(*源);
	

	RGB2BGR(*源);

	cout<<"生成宽,高:"<<wid<<","<<hei<<endl;


	RGB2bmp(*源);
						
	cout<<"图像转换成jpg格式... "<<endl;

	char filename[255];
	sprintf_s(filename,"Meta %d 倍",scale_int);
	savejpg(filename);

	cout<<"转换文件已经保存为:    "<<filename<<endl;
	
	del卷积层(*源);
	del卷积层(*目标);
	
}

左面的特征学习模块还是按以前的方法运行,右面的元放大模块的原理也没有看懂,只能按《Meta-SR--master》中的pytorch 代码照样运行。由于其中要用到多维张量(3,5,6维),放到下一文章说明吧。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值