1. 程式人生 > >用“ 快速卷積”來加速‘卷積’

用“ 快速卷積”來加速‘卷積’

在《【演算法+影象處理】2D卷積與快速卷積演算法C語言實現》一文找來一個快速卷積

//2D快速卷積演算法的實現  快速卷積演算法需要核2D核h能夠拆分成一個行向量和一個列向量的乘積的形式。
//實際實現也就是將2D卷積,拆分成兩次1D卷積的形式。設和的大小為n*n,這樣可以將演算法複雜度從n*n降低為2n。     
bool convolve2DFast(float* in, float* out, int dataSizeX, int dataSizeY,
                    float* kernel, int kernelSizeX, int kernelSizeY)

具體原理去看原文吧,為了應用該函式。需要轉化一下

定義一個卷積層

class 卷積層
{
	public:
	int		width;    //寬
	int     height;   //高
	int     depth;		  //通道 深度
	float * data;

	//建構函式
	卷積層(int iwidth,int iheight);
	卷積層(int iwidth,int iheight,int idepth);
	卷積層(int iwidth,int iheight,int c,float * data);
	~卷積層();
};

卷積層::卷積層(int iwidth,int iheight): width(iwidth),
                                            height(iheight)
{
	depth=1;
	data=NULL;

}

卷積層::卷積層(int iwidth,int iheight,int idepth): width(iwidth),
                                            height(iheight),depth(idepth)
{
	data=NULL;

}
卷積層::卷積層(int iwidth,int iheight,int idepth,float * fdata): width(iwidth),
                                            height(iheight),depth(idepth),	data(fdata)

{

}

卷積層::~卷積層()
{

}

記憶體分配就在外部了。

用下面的快速卷積代替原來的卷積

void 卷積快速(卷積矩陣*filter,卷積矩陣*arr, 卷積矩陣*res)
{
	卷積層 in=卷積矩陣2卷積層(arr);
	卷積層 out=卷積矩陣2卷積層(res);
	卷積層 kernel=卷積矩陣2卷積層(filter);

	//convolve2DFast(float* in, float* out, int dataSizeX, int dataSizeY,
 //                   float* kernel, int kernelSizeX, int kernelSizeY);
	convolve2DFast(in.data, out.data, in.width, in.height,
                    kernel.data, kernel.width, kernel.height);
	
	
	卷積層2卷積矩陣_複製(&out,res);

	
    delete []in.data;  in.data=NULL;  
    delete []out.data;  out.data=NULL;  
    delete []kernel.data;  kernel.data=NULL;  

}

相互轉換:

卷積層  卷積矩陣2卷積層(卷積矩陣 * a)
{
	int w=a->width;
	int h=a->height;

	卷積層 in(w,h,1);
	in.data=new float[w * h * sizeof(float)]; 
	float * t=in.data;
		
	for (int i = 0; i < w * h; i++)
		*t++=a->data[i];



	return in;

}
void  卷積層2卷積矩陣_複製(卷積層 * a,卷積矩陣 *r)
{
		int w=a->width;
		int h=a->height;

		if(w==r->width && h==r->height)
		//卷積矩陣 in(w,h);
		//float * t=a->data;
		{
		for (int i = 0; i < w * h; i++)
			r->data[i]=a->data[i];//*t++;
		}
		else
			cout<<"不能複製,矩陣大小不等 "<<endl;




}

這樣就比原來快一點了

效果圖:

原圖

2倍圖

3倍圖

4倍圖

程式下載:

https://download.csdn.net/download/juebai123/10528979

3 個不同放大倍率的VDSR 重建程式

和上個SRCNN 程式 。