C++实现超分辨率重建 SRFeat

有个博文介绍了这个 SRFeat ,并且《SRFeat-master》中有模型: SRFeat_full.npz 。

这里也用C++来实现下。

模型流程图:

 定义批正则层和残差块:

struct tf_BatchNorm层数据
{
	int 数据长度;
	float *	偏移;//beta
	float *	权重;//gamma
	float *	均值;//moving_mean
	float *	方差;//moving_variance
};

struct 残差块//
{
	层数据 *conv1; 
	tf_BatchNorm层数据 *BNorm1;
	层数据 *conv2; 
	tf_BatchNorm层数据 *BNorm2;
	层数据 *conv3; 
};

定义模型:

struct SRFeat模型
{
    //头
	层数据 * 输入层;//3->128

	//主体
	int 残差块数量;//16块
	残差块 * 块;

	//放大层
	层数据 * 放大1前层;//128->512
	//像素混组层 放大2倍 512->128
	层数据 * 放大2前层;//128->512
	//像素混组层 放大2倍 512->128


    //尾
	层数据 * 输出层;//128->3

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

};

 主函数:

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

//		
	int wid=bmp.width;
	int hei=bmp.height;
		cout<<"输入图像宽度:"<<wid<<endl;
		cout<<"        高度:"<<hei<<endl;
//
	卷积层 rgb(wid,hei,3);//即rgb通道
	rgb.data=new float[wid * hei *3]; 

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

	wid=rgb.width;
	hei=rgb.height;

	//---------------------------------------------->
	层数据 * 层;
	tf_BatchNorm层数据 *BN层;


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

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

	int pad;

		

	#define 卷积前传(ConvX)\
	\
	层=ConvX;/* Conv2 层 */ \
	if(层->输出维度 != 目标->depth || 目标->width != wid || 目标->height != hei)\
		Resize卷积层(*目标,wid,hei,层->输出维度);\
	pad=层->核宽/2;\
	vl_nnconv(源,目标,层 ,1,1,pad,pad,pad,pad);\
\
	std::swap (源,目标);\


	cout<<"输入层..."<<endl;
	卷积前传(sr.输入层);
			//load_mat2卷积层("me/c-add.txt",源);

	//----------------------------------------------<

	    
	卷积层 总和(wid,hei,源->depth);
	总和.data=new float[wid * hei * 源->depth ];
	    

	//第二部分  16残差层
	卷积层 convfea5(wid,hei,源->depth);
	convfea5.data=new float[wid * hei * 源->depth ]; 

	卷积层 *源备份=&convfea5;


	if(源->depth != 目标->depth || 目标->width != wid || 目标->height != hei)
		Resize卷积层(*目标,wid,hei,源->depth);

	残差块 * 块0=sr.块;
	cout<<sr.残差块数量<<"个残差块... 包括 2 组卷积"<<endl;

	for (int k = 0;k<sr.残差块数量;k++)
	{
		cout<<"\r"<<k;


		//备份
		卷积层复制(源,源备份);


		卷积前传(块0->conv1);

		BN层 = 块0->BNorm1;
		torch_BatchNorm(源,BN层->权重,BN层->偏移,BN层->均值,BN层->方差);
		vl_nnrelu(源,0.2f);

		卷积前传(块0->conv2);
		BN层 = 块0->BNorm2;
		torch_BatchNorm(源,BN层->权重,BN层->偏移,BN层->均值,BN层->方差);

		卷积层相加(源备份,源);
		if(k==15) //最后一个用不到
		{
			卷积层相加(源,&总和);
			break;
		}
		else
			vl_nnconv(源,目标,块0->conv3 ,1,1);// 不用 swap
			
		卷积层相加(目标,&总和);


		块0++;//到下残差块
	}
	cout<<endl;
	del卷积层(*源备份);

	   
	卷积层复制(&总和,源);
		del卷积层(总和);
			//load_mat2卷积层("me/add3_14.txt",源);
		//save_卷积层2txt(源,"add-14.txt");

		cout<<"放大2倍"<<endl;
	卷积前传(sr.放大1前层);

	wid=wid*2;hei=hei*2;
		Resize卷积层(*目标,wid,hei,128);
	depth_to_space(*源,*目标);
		vl_nnrelu(目标,0.2f);
		std::swap (源,目标);

			//load_mat2卷积层("me/pixelshufflerx2-1-lrelu.txt",源);

		cout<<"再放大2倍"<<endl;
	卷积前传(sr.放大2前层);

	wid=wid*2;hei=hei*2;
		Resize卷积层(*目标,wid,hei,128);
	depth_to_space(*源,*目标);
		vl_nnrelu(目标,0.2f);
		std::swap (源,目标);


	cout<<"输出层..."<<endl;
	卷积前传(sr.输出层);
						
	
	cout<<"生成图 宽,高:"<<源->width<<","<<源->height<<endl;


	cout<<"图像转换成jpg格式... "<<endl;


//load_mat2卷积层("me/out.txt",源);


	RGB2bmp(*源);

	del卷积层(*源);

	savejpg(savefilename);

	cout<<"转换文件已经保存为:    "<<savefilename<<endl;

}

效果图:

小图

SRFeat生成图(4倍,20秒)

ESRGAN生成图(4倍,72秒)

比ESRGAN差一点,速度也快一点,毕竟体量小一点。

超分辨率已经差不多了,暂时就不会有这个内容了。

下载:

win超分辨重建SRFeat

超分辨重建SRFeat(4倍),由《SRFeat-master》中的模型 SRFeat_full.npz 改编而成

https://download.csdn.net/download/juebai123/11189298

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值