C++实现超分辨 WDSR

WDSR  (有更宽的特征的EDSR)

终于用 tf.save_model.loader.load 打开了wdsr 的 saved_model.pb 模型。
再导出模型参数数据,有 23M,还是比较小的。

再到《tf_estimator_barebone-master》找出流程,这时才发现 里面是有一个演示程序可以打开pb 模型。

然后,在下面的显示内容中找到图节点名称。

g = tf.get_default_graph()
print(g.as_graph_def().node)

按节点名称,用get_tensor_by_name 就可以导出各个中间操作数据。这个倒是比其它框架更方便的一面。
准备工作完成 。

EDSR WDSR 比较流程图:

 残差块比较:

我下的这个pb 应该是哪个wdsr-a 型的2倍模型(16残差块)。

下面用我们的C++来实现:

定义残差块:

struct 残差块//
{
	层数据 *conv0; //32->128
	层数据 *conv1; //128->32
};

 模型:

struct WDSR模型
{
    //头
	层数据 * 备份层;//skip 3->12
	//像素混组 12->3

	层数据 * 输入层;//3->32

	//主体
	int 残差块数量;//16块
	残差块 * 块;//32->128->32

	//放大层
	层数据 * 放大前层;//32->12
	//像素混组 12->3

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

};

层数据:

struct 层数据
{
	int 权重长度;
	float *	权重_数据;
	int 偏移长度; 
	float *	偏移_数据;
	int 输入维度;
	int	输出维度;
	int 核宽;
	float *	核乘数;//(权重通道缩放比)(权重 = 权重 * 权重正则化 * 该值)
	//float *	激活_数据;

};

其中的<核乘数> 叫权重通道缩放比 可能比较合理。依照RCAN 可命名为 “权重通道注意力”。

按理这个权重正则化应该只在训练时使用。

初始化模型:

WDSR模型::WDSR模型()
{

	int size;
	层数据 * 层;

	/*输入维度,输出维度,核宽*/
	#define 初始化ONE层(IN,OUT,KW) \
	\
	层->输入维度=IN;\
	层->输出维度=OUT;\
	层->核宽=KW;\
	层->权重长度=层->输出维度*层->输入维度*层->核宽*层->核宽;\
	层->权重_数据=(float*)malloc(sizeof(float) * 层->权重长度);\
	层->偏移长度=层->输出维度;\
	层->偏移_数据=(float*)malloc(sizeof(float) * 层->偏移长度);\
	层->核乘数=(float*)malloc(sizeof(float) * 层->偏移长度);

	#define 初始化层(ConvX,IN,OUT,KW) \
	size = sizeof(层数据);\
\
	层=ConvX =(层数据 *)malloc(size);\
	初始化ONE层(IN,OUT,KW)\


	/*名称,输入维度,输出维度,核宽*/
		初始化层(备份层,3,12,5);
		初始化层(输入层,3,32,3);

		残差块数量=16;
		size = sizeof(残差块)*残差块数量;
		块=(残差块*)malloc(size);
		残差块 * 残差块0=块;
		for (int k = 0;k<残差块数量;k++)
		{
			初始化层(残差块0->conv0,32,128,3);
			初始化层(残差块0->conv1,128,32,3);

			残差块0++;
		}

		初始化层(放大前层,32,12,3);

}

主函数:

void WDSR(char * savefilename,WDSR模型 & sr)
{
	int 放大倍数=2;
//		
	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);
		//load_mat2卷积层("me/sub-6a.txt",&rgb);

	预处理(rgb);//减平均值
	
			

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

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

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

	卷积层 *源,*目标;

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

	源 = &si;
	
	目标 = di;

	int pad;

		


	cout<<"备份层..."<<endl;
	层=sr.备份层;
	weight_norm(层);
		//load_mat2层数据("skip-conv2d_weight_norm-mul_1-6a.txt",层);

	if(层->输出维度 != 目标->depth || 目标->width != wid || 目标->height != hei)
		Resize卷积层(*目标,wid,hei,层->输出维度);
	pad=层->核宽/2;
	vl_nnconv(源,目标,层 ,1,1,pad,pad,pad,pad);


		//load_mat2卷积层("me/skip-conv2d_weight_norm-Conv2D-6a.txt",目标);

	Resize卷积层(rgb,wid*放大倍数,hei*放大倍数,3);
	//像数混组(目标,&rgb);//亚像数放大层
	像数混组12_3(*目标,rgb);// 模拟 tf.depth_to_space

		//load_mat2卷积层("me/skip-DepthToSpace-6a.txt",&rgb);
		//save_卷积层2txt(&rgb,"skip-DepthToSpace-6a-0.txt");

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


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

	    
	//第二部分  16残差层
	残差块总成(sr,源,目标);

		//load_mat2卷积层("me/layer15-add.txt",源);


	cout<<endl;

	         //load_mat2层数据("me/output-conv2d_weight_norm-mul_1-0-6a.txt",sr.放大前层);
			 //weight_norm(sr.放大前层);
	         //save_mat2层数据("output-conv2d_weight_norm-mul_1.txt",sr.放大前层);


	卷积前传无RELU(sr.放大前层);
		//load_mat2卷积层("me/up2-BiasAdd-6a.txt",源);



		
					
	wid=wid*放大倍数;hei=hei*放大倍数;
		cout<<"生成宽,高:"<<wid<<","<<hei<<endl;

	Resize卷积层(*目标,wid,hei,3);
	//像数混组(源,目标);//亚像数放大层
	像数混组12_3(*源,*目标);
		//load_mat2卷积层("me/out-DepthToSpace-6a.txt",目标);


	//输入加上残差
	卷积层相加(&rgb,目标);
		//load_mat2卷积层("me/add-6a.txt",目标);

	del卷积层(rgb);
						
	
	


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

	后处理(*目标);//加平均值 

		//load_mat2卷积层("me/out-6a.txt",目标);


	RGB2bmp(*目标);

	del卷积层(*目标);

	savejpg(savefilename);

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

}

效果图:

小图

WDSR 2倍

再来一张:

小图

WDSR 2倍

看上去非常不错。

下载:

win32超分辩重建WDSR实用程序

超分辨率重建WDSR(2倍)的win32程序,使用tf_estimator_barebone-master 中的模型wdsr_saved_model.pb

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

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值