C++ 实现 超分 SFTGAN

SFTGAN(通过语义分割先验恢复图像中的真实纹理的超分辨率),大意是有些场合效果可能更好。

https://github.com/xinntao/SFTGAN

生成部分分两块:

1。8种类语义分割

 

2 。超分部分

主函数:

void  SFTGAN(char * savefilename, SFTGAN模型 & 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;
	
		show卷积层size(*源);
		cout<<"conv0...\n";

	//x[0]: img; x[1]: seg
	卷积前传无RELU(sr.conv0);

	卷积层 fea(1,1);
	Resize卷积层(fea,源->width,源->height,源->depth);
	卷积层复制(源,&fea);
	卷积层 fea0(1,1);
	Resize卷积层(fea0,源->width,源->height,源->depth);
	卷积层复制(源,&fea0);
	cout<<"fea:"<<endl;
		show卷积层size(*源);

	卷积层 scale(1,1);//和 fea 同大小
	Resize卷积层(scale,源->width,源->height,源->depth);
	卷积层 shift(1,1);
	Resize卷积层(shift,源->width,源->height,源->depth);

	//x[1]: seg
	cout<<"载入语义分割图:seg-w.txt..."<<endl<<endl;
	 load_mat2卷积层("seg-w.txt",源);
	 wid=源->width;hei=源->height;
	
		show卷积层size(*源);
		cout<<sr.condnet.conv0->输入维度<<","<<sr.condnet.conv0->输出维度<<","<<sr.condnet.conv0->核宽<<endl;
	卷积多步长LeakyReLU前传(sr.condnet.conv0,0.1f,4); 
		show卷积层size(*源);
	卷积LeakyReLU前传(sr.condnet.conv2,0.1f);  
		show卷积层size(*源);
	卷积LeakyReLU前传(sr.condnet.conv4,0.1f);  
	卷积LeakyReLU前传(sr.condnet.conv6,0.1f);  
	卷积前传无RELU(sr.condnet.conv8); 

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

	输入 fea, cond
	//ResBlock_SFT_torch
		
	卷积层 fea_x0(1,1);
	Resize卷积层(fea_x0,fea.width,fea.height,fea.depth);

	ResBlock_SFT_torch * is=sr.sft_b.res;
	for(int i=0;i<16;i++)
	{
		cout<<i<<"\r";
		//SFTLayer_torch sft0
		//x[0]: fea; x[1]: cond
		卷积层复制(&fea,&fea_x0);
		//输入cond
				
		Resize卷积层(*源,cond.width,cond.height,cond.depth);		

		卷积层复制(&cond,源);
		卷积LeakyReLU前传(is->sft0.SFT_scale_conv0,0.01f); //(32, 32, 1)
		卷积前传无RELU(is->sft0.SFT_scale_conv1); //(32, 64, 1)为scale
		卷积层复制(源,&scale);

		//输入cond
		Resize卷积层(*源,cond.width,cond.height,cond.depth);
		卷积层复制(&cond,源);
		卷积LeakyReLU前传(is->sft0.SFT_shift_conv0,0.01f); //(32, 32, 1)
		卷积前传无RELU(is->sft0.SFT_shift_conv1); //(32, 64, 1)为shift
		卷积层复制(源,&shift);

		卷积层复制(&fea,源);
		//fea=fea * scale + shift
		卷积层点乘(&scale,源);
		卷积层相加(&shift,源);
		vl_nnrelu(源);

		卷积前传无RELU(is->conv0); 
		卷积层复制(源,&fea);

				
		//sft1
		Resize卷积层(*源,cond.width,cond.height,cond.depth);		
		卷积层复制(&cond,源);
		卷积LeakyReLU前传(is->sft1.SFT_scale_conv0,0.01f);
		卷积前传无RELU(is->sft1.SFT_scale_conv1); 
		卷积层复制(源,&scale);


		Resize卷积层(*源,cond.width,cond.height,cond.depth);		
		卷积层复制(&cond,源);
		卷积LeakyReLU前传(is->sft1.SFT_shift_conv0,0.01f);
		卷积前传无RELU(is->sft1.SFT_shift_conv1); 
		卷积层复制(源,&shift);

		卷积层复制(&fea,源);
		//fea=fea * scale + shift
		卷积层点乘(&scale,源);
		卷积层相加(&shift,源);
		vl_nnrelu(源);
		卷积前传无RELU(is->conv1); 
		卷积层复制(源,&fea);
		//fea=x[0] + fea
		卷积层相加(&fea_x0,&fea);

		is++;
	}cout<<"\n";

		Resize卷积层(*源,cond.width,cond.height,cond.depth);
		wid=cond.width;hei=cond.height;
	卷积层复制(&cond,源);
	卷积LeakyReLU前传(sr.sft_b.sft.SFT_scale_conv0,0.01f);
	卷积前传无RELU(sr.sft_b.sft.SFT_scale_conv1); 
	卷积层复制(源,&scale);

		Resize卷积层(*源,cond.width,cond.height,cond.depth);
		wid=cond.width;hei=cond.height;
	卷积层复制(&cond,源);
	卷积LeakyReLU前传(sr.sft_b.sft.SFT_shift_conv0,0.01f);
	卷积前传无RELU(sr.sft_b.sft.SFT_shift_conv1); 
	卷积层复制(源,&shift);

		卷积层复制(&fea,源);
		//fea=fea * scale  + shift
		卷积层点乘(&scale,源);
		卷积层相加(&shift,源);

	卷积前传无RELU(sr.sft_b.conv); 

	//fea = fea + res
	卷积层相加(&fea0,源);

	//nn.Upsample(scale_factor=2, mode='nearest')
	wid*=2;hei*=2;
	Resize卷积层(*目标,wid,hei,源->depth);
	最近邻插值(*源,*目标);
	swap(源,目标);

	卷积前传(sr.hr_b.conv1); 
	//nn.Upsample(scale_factor=2, mode='nearest')
	wid*=2;hei*=2;
	Resize卷积层(*目标,wid,hei,源->depth);
	最近邻插值(*源,*目标);
	swap(源,目标);

	卷积前传(sr.hr_b.conv4); 
	卷积前传(sr.hr_b.conv6); 
	卷积前传无RELU(sr.hr_b.conv8); 



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

	savejpg(savefilename);

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

}

效 果图:

输入小图

彩色语义分割图

对照色表,分割不完全正确

4倍重建图

与ESRGAN比一比:

输入小图

SFTGAN

ESRGANx4

下载:

win超分辩重建SFTGAN程序

超分辨率重建SFTGAN(4倍)的win32程序,也可以作为语义分割程序使用,由《SFTGAN-master》中的模型权重改编而来

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



 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,根据提供的引用内容,没有找到关于C++实现Transformer的具体信息。但是,我可以为您提供一些关于Transformer的基本概念和C++实现的一般步骤。 Transformer是一种用于序列到序列(Sequence-to-Sequence)任务的模型架构,最初用于机器翻译任务。它由编码器(Encoder)和解码器(Decoder)组成,其中编码器将输入序列转换为一系列隐藏表示,解码器则使用这些隐藏表示生成输出序列。 要在C++实现Transformer,您可以按照以下步骤进行操作: 1. 定义模型架构:在C++中,您需要定义Transformer的编码器和解码器的结构。编码器通常由多个自注意力层(Self-Attention Layer)和前馈神经网络层(Feed-Forward Neural Network Layer)组成,而解码器还包括一个注意力层(Attention Layer)。 2. 实现自注意力层:自注意力层是Transformer的核心组件之一。它通过计算输入序列中每个位置与其他位置的相关性来捕捉序列中的上下文信息。在C++中,您可以使用矩阵运算和线性代数操作来实现自注意力层。 3. 实现前馈神经网络层:前馈神经网络层用于对自注意力层的输出进行进一步的处理和映射。它通常由两个全连接层和激活函数组成。在C++中,您可以使用线性代数库或深度学习框架来实现前馈神经网络层。 4. 实现注意力层:注意力层用于解码器中,它根据编码器的隐藏表示和解码器的当前隐藏状态来计算上下文向量,以帮助生成输出序列。在C++中,您可以使用矩阵运算和线性代数操作来实现注意力层。 5. 训练和推理:实现模型的训练和推理过程,包括数据预处理、损失函数的定义、优化器的选择以及模型参数的更新和保存。 请注意,以上步骤仅为一般指导,具体的实现细节可能因您的具体需求和使用的库而有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值