用“ 快速卷積”來加速‘卷積’
阿新 • • 發佈:2019-01-29
在《【演算法+影象處理】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 程式 。