C++ 實現 超分 Meta-SR

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維),放到下一文章說明吧。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章