有个博文介绍了这个 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<<"输入图像宽度:"<
层数据 * 层;
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<<"输入层..."<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<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<width<<","<<源->height<
效果图:
比ESRGAN差一点,速度也快一点,毕竟体量小一点。
超分辨率已经差不多了,暂时就不会有这个内容了。
下载:
超分辨重建SRFeat(4倍),由《SRFeat-master》中的模型 SRFeat_full.npz 改编而成
https://download.csdn.net/download/juebai123/11189298