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