这个DeblurGAN的生成网络和风格转换的生成网络差不多,除了残差块从5个加到9个外,全局也是一个残差结构:
output = input + output
其它都相同了。所以就不详细讲了,请参看风格转换部分。
主函数:
void DeblurGAN(char * savefilename,DeblurGAN模型 & 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);
RGB2BGR(rgb) ;
卷积层 备份(wid,hei,3);
备份.data=new float[wid * hei * 3 ];
//总备份
卷积层复制(&rgb,&备份);
//伸缩零头:使宽,高保证为4的倍数而设,即 宽(高)除4的余数 + x0(y0) = 4
int x0=0, y0=0;
伸缩边(rgb, x0, y0);
wid=rgb.width;
hei=rgb.height;
//---------------------------------------------->
层数据 * 层;
//两个卷积层 交替前传(源,目标)
//用这个传回
卷积层 * di=(卷积层 *)malloc(sizeof(卷积层));
di->width=1;
di->height=1;
di->depth=1;
di->data=new float[1 ];
卷积层 *源,*目标;
源 = &rgb;
目标 = di;
int pad;
//定义一个宏
//用于各个层
#define 卷积和归一化(ConvX,步长)/* 上采样、下采样 */ \
\
层=sr.ConvX;/* Conv2 层 */ \
if(层->输出维度 != 目标->depth || 目标->width != wid || 目标->height != hei)\
Resize卷积层(*目标,wid,hei,层->输出维度);\
pad=层->核宽/2;\
vl_nnconv(源,目标,层 ,步长,步长,pad,pad,pad,pad);\
vl_Norm(目标);\
vl_nnrelu(目标);/*激励函数Prelu*/\
\
std::swap (源,目标);\
cout<<"输入层..."<<endl;
卷积和归一化(输入层,1);
cout<<"第一下采样层..."<<endl;
wid=wid/2;hei=hei/2;
卷积和归一化(下采样层1,2);
cout<<"第二下采样层..."<<endl;
wid=wid/2;hei=hei/2;
卷积和归一化(下采样层2,2);
//----------------------------------------------<
//第二部分 9残差层
卷积层 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<<"9个残差块... 包括 2 组卷积"<<endl;
for (int k = 0;k<sr.残差块数量;k++)
{
cout<<"\r"<<k;
//备份
卷积层复制(源,源备份);
层=残差块0->卷积层;
vl_nnconv(源,目标,层 ,1,1,1,1,1,1);
vl_Norm(目标);
vl_nnrelu(目标);
层++;
vl_nnconv(目标,源,层 ,1,1,1,1,1,1);
vl_Norm(源);
// //求和
卷积层相加(源备份,源);
残差块0++;//到下残差块
}
cout<<endl;
del卷积层(*源备份);
//用于各个层
#define 反卷积和归一化(ConvX)/* 上采样、下采样 */ \
\
层=sr.ConvX;/* Conv2 层 */ \
if(层->输出维度 != 目标->depth || 目标->width != wid || 目标->height != hei)\
Resize卷积层(*目标,wid,hei,层->输出维度);\
vl_nnconvt(源,目标,层,2,2, 1,1,1,1) ;\
vl_Norm(目标);\
vl_nnrelu(目标);/*激励函数Prelu*/\
\
std::swap (源,目标);\
cout<<"第一上采样层..."<<endl;
wid=wid*2;hei=hei*2;
反卷积和归一化(上采样层1);
cout<<"第二上采样层..."<<endl;
wid=wid*2;hei=hei*2;
反卷积和归一化(上采样层2);
cout<<"输出层..."<<endl;
层=sr.输出层;
if(层->输出维度 != 目标->depth || 目标->width != wid || 目标->height != hei)
Resize卷积层(*目标,wid,hei,层->输出维度);
pad=层->核宽/2;
vl_nnconv(源,目标,层 ,1,1,pad,pad,pad,pad);
del卷积层(*源);
vl_tanh(目标);//激励函数
cout<<"图像转换成jpg格式... "<<endl;
伸缩边(*目标, x0, y0,false);
//加上输入
卷积层相加(&备份,目标);
del卷积层(备份);
RGB2BGR(*目标) ;
RGB2bmp(*目标);
del卷积层(*目标);
savejpg(savefilename);
cout<<"转换文件已经保存为: "<<savefilename<<endl;
}
结束。
下载:
win32去运动模糊程序
由DeblurGAN改编过来的去运动模糊,对拍摄的太模糊的图可以试试,可能会清楚一点。
本文介绍DeblurGAN模型的实现过程,该模型通过增加残差块的数量来提高图像去模糊的效果。文章详细展示了从输入图像到输出清晰图像的具体步骤,包括预处理、下采样、残差块处理及上采样等。
1268





