Meta-SR(任意放大倍数的超分辨率),大概意思是 :可以是非整数倍的,并且只要一个模型(就可以实现2,3,4 倍及它们之中间倍数,比如,2.3, 3.5 倍等)
在《Meta-SR--master》中提供了 一个训练好的模型 (百度盘),这里用C++实现下(便于没有安装Pytorch的电脑运行)。
分成 特征学习、元放大 两块。
先定义数据池,把训练模型数据载入:
struct 层数据
{
int 权重长度;
float * 权重_数据;
int 偏移长度;
float * 偏移_数据;
int 输入维度;
int 输出维度;
int 核宽;
};
struct Linear权重//这个全连接以前是直接用“层数据”,并且用卷积代替这里的torch.nn.Linear
{
int 权重长度;
float * 权重_数据;
int 偏移长度;
float * 偏移_数据;
int 输入维度;
int 输出维度;
};
struct 密集残差块 // 8+1个卷积层
{
//输入 0; -->64
//0 连续存储 64
层数据 * conv1;//64-->64
//0,1 连续存储 128
层数据 * conv2;//128-->64
//0,1,2 连续存储 192
层数据 * conv3;//192-->64
//0,1,2,3 连续存储 256
层数据 * conv4;//256-->64
//0,1,2,3 ,4连续存储 320
层数据 * conv5;//320-->64
层数据 * conv6;//384-->64
层数据 * conv7;//448-->64
层数据 * conv8;//512-->64
层数据 * conv9;//576-->64 局部特征融合 1x1卷积
};
struct Meta_SR模型
{
层数据 * sub_mean;//减均值
层数据 * add_mean;//加均值
//浅层特征提取
层数据 * conv1;//3->64
层数据 * conv2;//64->64
//密集残差块
int 密集残差块数量;//16块
密集残差块 * 块;
//16个密集残差块连续存储 1024
层数据 * conv3; //1024-->64 特征融合 1x1卷积
层数据 * conv4; //64-->64
//全局残差相加
//放大
Linear权重 * Pos2Weight1; //in:3, out:256
Linear权重 * Pos2Weight2; //in:256,out:1728
//构造函数
Meta_SR模型();
};
主函数:
void Meta_SR(char * savefilename, Meta_SR模型 & 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;
RGB2BGR(*源);
卷积前传无RELU(sr.sub_mean);
cout<<"输入层..."<<endl;
卷积前传无RELU(sr.conv1);
//备份
卷积层 conv1备份(wid,hei,源->depth);//f__1
conv1备份.data=new float[wid * hei * 源->depth ];
卷积层复制(源,&conv1备份);
卷积前传无RELU(sr.conv2);
//第二部分 密集残差块
密集残差块总成(sr,*源);
cout<<"GFF_out:";
卷积层相加(&conv1备份,源);del卷积层(conv1备份);
cout<<"当前宽,高,深度:"<<源->width<<","<<源->height<<","<<源->depth<<endl;
卷积层 x(1,1);
Resize卷积层(x,源->width,源->height,源->depth);
卷积层复制(源,&x);
//---------------特征学习模块-----------------------<
//--------------- 元放大模块 ----------------------->
cout<<"矩阵宽,高:"<<源->width<<","<<源->height<<endl;
float scale=2.0f;//可以是小数倍数
cout<<"\n"<< scale<<" 倍\n\n";
int scale_int=(int)ceil(scale);
cout<<"倍数选择矩阵:\n";
void input_matrix_wpn(int inH,int inW,float scale,卷积层 &out);//
input_matrix_wpn(源->height,源->width,scale,*源);
cout<<"当前宽,高,深度:"<<源->width<<","<<源->height<<","<<源->depth<<endl;
vl_nnLinear(源,目标,sr.Pos2Weight1);
swap(源,目标);
cout<<"当前宽,高,深度:"<<源->width<<","<<源->height<<","<<源->depth<<endl;
vl_nnrelu(源);
vl_nnLinear(源,目标,sr.Pos2Weight2);
swap(源,目标);
cout<<"当前宽,高,深度:"<<源->width<<","<<源->height<<","<<源->depth<<endl;
删除模型数据(sr);
cout<<"多维前传:\n";
多维前传(x,*源,scale_int);
//--------------- 元放大模块 -----------------------<
wid = 源->width;hei = 源->height;
//加均值
后处理(*源);
RGB2BGR(*源);
cout<<"生成宽,高:"<<wid<<","<<hei<<endl;
RGB2bmp(*源);
cout<<"图像转换成jpg格式... "<<endl;
char filename[255];
sprintf_s(filename,"Meta %d 倍",scale_int);
savejpg(filename);
cout<<"转换文件已经保存为: "<<filename<<endl;
del卷积层(*源);
del卷积层(*目标);
}
左面的特征学习模块还是按以前的方法运行,右面的元放大模块的原理也没有看懂,只能按《Meta-SR--master》中的pytorch 代码照样运行。由于其中要用到多维张量(3,5,6维),放到下一文章说明吧。