完整SRCNN函数:
IMAGE SRCNN(IMAGE *jpg,int up_scale)
{
// 双三次插值
// 先将低分辨率图像使用双三次插值放大至目标尺寸(如放大至2倍、3倍、4倍)
//im_b = imresize(im_gnd, up_scale, 'bicubic');
IMAGE im_h=*jpg;
//双三次插值放大
ResizeGrayscaleImage(&im_h,up_scale ) ;
//saveimage("放大.jpg", &im_h);
//// //显示
putimage(im_h.getwidth(), 0, &im_h);
SCREEN模型 sr;
// 加载 CNN 模型参数
loadModel(&sr);
int wid=im_h.getwidth();
int hei=im_h.getheight();
//图像转化为卷积矩阵
#define 彩色 1
#if 彩色==1
//彩色
卷积矩阵 im_b(wid,hei);//即Y通道
卷积矩阵 U(wid,hei),V(wid,hei);
//RGB转换为YUV
RGB2YUV(&im_h,&im_b,&U,&V);
#else
//单色
卷积矩阵 im_b=im2卷积矩阵(&im_h);
//save_卷积矩阵 ("im_b.txt",&im_b); //保存权重
#endif
//用于保存调试图像的变量
IMAGE im_tt;
char txt[256];
// 第一层卷积:卷积核尺寸9×9(f1×f1),卷积核数目64(n1),输出64张特征图;
cout<<"第一层卷积..."<<endl;
//conv1_data = zeros(hei, wid, conv1_filters);
vector <卷积矩阵> conv1_data;//[64]结果
clock_t start_t, end_t;//计算时间
double total_t;
start_t = clock();
for (int i = 0 ;i<64;i++)
{
//weights_conv1 = reshape(weights_conv1, conv1_patchsize, conv1_patchsize, conv1_filters);
//准备卷积核
卷积矩阵 filter(9,9);
转换卷积核(&sr,&filter,1,i);
卷积矩阵 res(wid,hei);
// conv1_data(:,:,i) = imfilter(im_b, weights_conv1(:,:,i), 'same', 'replicate');
卷积(&filter,&im_b, &res);
// conv1_data(:,:,i) = max(conv1_data(:,:,i) + biases_conv1(i), 0);
加上偏移(&res,sr.偏移_conv1_数据,i);
conv1_data.push_back(res);
//
//保存64个卷积核
//sprintf(txt, "conv1_filter_%d.txt", i);
//save_卷积矩阵 (txt,&filter);
//保存64个卷积结果矩阵
//sprintf(txt, "conv1_data_%d.txt", i);
//save_卷积矩阵 (txt,&conv1_data[i]); //保存权重
//保存64张特征图
//im_tt=卷积矩阵2im(&res);
//sprintf(txt, "conv1_data_0%d.jpg", i);
//saveimage(txt, &im_tt);
end_t = clock();
total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
if(total_t>1.0){
cout<<i<<"/"<<64<<endl;//在大图时显示进度
start_t = clock();
}
}//end
cout<<"第二层卷积..."<<endl;
// 第二层卷积:卷积核尺寸1×1(f2×f2),卷积核数目32(n2),输出32张特征图;
vector <卷积矩阵> conv2_data;//[32];//结果
start_t = clock();
for (int i = 0;i<32 ;i++)
{
卷积矩阵 conv2(wid,hei);
for (int j = 0 ;j<64;j++)
{
//conv2_data(:,:,i) = conv2_data(:,:,i) + weights_conv2(j,:,i) * conv1_data(:,:,j);
第二层运算(&conv2,&sr,&conv1_data[j],i,j);
}//end
//conv2_data(:,:,i) = max(conv2_data(:,:,i) + biases_conv2(i), 0);
加上偏移(&conv2,sr.偏移_conv2_数据,i);
conv2_data.push_back(conv2);
//保存32张特征图
//im_tt=卷积矩阵2im(&conv2);
//sprintf(txt, "conv2_data_0%d.jpg", i);
//saveimage(txt, &im_tt);
end_t = clock();
total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
if(total_t>1.0){
cout<<i<<"/"<<32<<endl;
start_t = clock();
}
}//end
cout<<"第三层卷积..."<<endl;
// 第三层卷积:卷积核尺寸5×5(f3×f3),卷积核数目1(n3),输出1张特征图即为最终重建高分辨率图像。
//conv3_data = zeros(hei, wid);
卷积矩阵 conv3_data (wid,hei);
start_t = clock();
for(int i = 0;i<32;i++)
{
//conv3_subfilter = reshape(weights_conv3(i,:), conv3_patchsize, conv3_patchsize);
卷积矩阵 conv3_subfilter(5,5);
转换卷积核(&sr,&conv3_subfilter,3,i);
卷积矩阵 conv3_temp (wid,hei);
//conv3_data(:,:) = conv3_data(:,:) + imfilter(conv2_data(:,:,i), conv3_subfilter, 'same', 'replicate');
卷积(&conv3_subfilter,&conv2_data[i],&conv3_temp);
第三层运算(&conv3_data,&conv3_temp);//特征图迭加
//保存32张特征图
//im_tt=卷积矩阵2im(&conv3_temp);
//sprintf(txt, "conv3_temp_0%d.jpg", i);
//saveimage(txt, &im_tt);
//保存32次迭加图
//im_tt=卷积矩阵2im(&conv3_data);
//sprintf(txt, "conv3_data_0%d.jpg", i);
//saveimage(txt, &im_tt);
end_t = clock();
total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
if(total_t>1.0){
cout<<i<<"/"<<32<<endl;
start_t = clock();
}
}//end
cout<<"卷积完成"<<endl;
#if 彩色==1
//彩色
//YUV转回RGB
YUV2RGB(&conv3_data,&U,& V,&im_h);
#else
//单色
//卷积矩阵转化为图像
im_h=卷积矩阵2im(&conv3_data);
#endif
return im_h;
}
修改了套色,和边界的一些错误,效果:
最终的程序做了一些速度的优化
你可以在这里下载可执行程序:
https://download.csdn.net/download/juebai123/10463768
这个下载还有一点颜色没对准,我不知道怎么重新上传修改,已经下载的请留言或私信。我可以发到你的邮箱里
资源说明:
纯 C++ 实现的超分辨率重建, 你不用安装任何编程语言和神经网络库,马上使用超分辨率 非源代码,源代码都在博客的文章上了
只要 1 下载分,无下载分的可到百度网盘下载:
https://pan.baidu.com/s/1ibBH9DZOrYHuJIoRHBHcYA
网盘已经更新,可以下载正确的