由于《deblur-gan-master》(实现上用的是《deblur-gan-0c0c0296f143b7a070a0969cb64a8774f8e79f1d》)也有一个去模糊的生成模型 generator.h5。
先安装 Keras。
运行:
python scripts/deblur_image.py --image_path=test_blur.jpg
这个效果比前面的哪好个一点。
然后
导出模型到文本文件:
g.load_weights('generator.h5')
#-------------------------------------------------------------开始
fp = open('generator.h5.txt', 'w')
i=0
for layer in g.layers:
lconfig = layer.get_config()#该层的配置
i=i+1
fp.write('layer %d: %s\n' % (i, lconfig['name'])) #层序号,层名
print(i)
print(lconfig['name'])
fp.write(str(lconfig)) # 配置
fp.write('\n')
weights = layer.get_weights() # numpy数组列表
for weight in weights:
if weight.ndim == 4:
#v_4d.shape [ H, W, I, O ] 高,宽,输入,输出
weight = np.swapaxes(weight, 0, 2) # swap H, I
weight = np.swapaxes(weight, 1, 3) # swap W, O
weight = np.swapaxes(weight, 0, 1) # swap I, O
#v_4d.shape [ O, I, H, W ]
v_1d = weight.reshape(weight.shape[0]*weight.shape[1]*weight.shape[2]*weight.shape[3])
vshape = weight.shape[:]
fp.write('shape {\n') # 这个放前面方便一点
for s in vshape:
fp.write( ' ' + str(s)) # dim:
fp.write('\n')
fp.write('}\n')
fp.write(' blobs {\n') # 这个放后面
for vv in v_1d:
fp.write('%8f' % vv) # data:
fp.write('\n')
fp.write(' }\n')
elif weight.ndim == 1 :#
fp.write('shape {\n')
fp.write( ' ' + str(weight.shape[0])) # dim:
fp.write('\n')
fp.write('}\n')
fp.write('blobs {\n')
for vv in weight:
fp.write('%.8f' % vv) # data:
fp.write('\n')
fp.write('}\n')
fp.write('\n')
fp.close()
#-------------------------------------------------------------结束
这个和前面哪个基本相同,用批正则化代替实例正则化。
C++改编主函数:
void DeblurGAN(char * savefilename,DeblurGAN模型 & sr)
{
//
int wid=bmp.width;
int hei=bmp.height;
cout<<"输入图像宽度:"<<wid<<endl;
cout<<" 高度:"<<hei<<endl;
//
卷积层 rgb(wid,hei,3);//即rgb通道
rgb.data=new float[wid * hei *3];
//jpg转换为RGB卷积层
bmp2RGB(rgb);
卷积层 备份(wid,hei,3);
备份.data=new float[wid * hei * 3 ];
//总备份
卷积层复制(&rgb,&备份);
//伸缩零头:使宽,高保证为4的倍数而设,即 宽(高)除4的余数 + x0(y0) = 4
int x0=0, y0=0;
伸缩边(rgb, x0, y0);
wid=rgb.width;
hei=rgb.height;
//---------------------------------------------->
层数据 * 层;
//两个卷积层 交替前传(源,目标)
//用这个传回
卷积层 * di=(卷积层 *)malloc(sizeof(卷积层));
di->width=1;
di->height=1;
di->depth=1;
di->data=new float[1 ];
卷积层 *源,*目标;
源 = &rgb;
目标 = di;
int pad;
BatchNorm层数据 * bnorm=sr.BN层;
//定义一个宏
//用于各个层
#define 卷积和归一化(ConvX,步长)/* 上采样、下采样 */ \
\
层=sr.ConvX;/* Conv2 层 */ \
if(层->输出维度 != 目标->depth || 目标->width != wid || 目标->height != hei)\
Resize卷积层(*目标,wid,hei,层->输出维度);\
pad=层->核宽/2;\
vl_nnconv(源,目标,层 ,步长,步长,pad,pad,pad,pad);\
torch_BatchNorm(目标,bnorm->权重,bnorm->偏移,bnorm->均值,bnorm->方差);bnorm++;\
vl_nnrelu(目标);/*激励函数Prelu*/\
\
std::swap (源,目标);\
cout<<"输入层..."<<endl;
卷积和归一化(输入层,1);
cout<<"第一下采样层..."<<endl;
wid=wid/2;hei=hei/2;
卷积和归一化(下采样层1,2);
cout<<"第二下采样层..."<<endl;
wid=wid/2;hei=hei/2;
卷积和归一化(下采样层2,2);
//----------------------------------------------<
//第二部分 9残差层
卷积层 convfea5(wid,hei,源->depth);
convfea5.data=new float[wid * hei * 源->depth ];
卷积层 *源备份=&convfea5;
if(源->depth != 目标->depth || 目标->width != wid || 目标->height != hei)
Resize卷积层(*目标,wid,hei,源->depth);
残差块 * 残差块0=sr.块;
cout<<"9个残差块... 包括 2 组卷积"<<endl;
for (int k = 0;k<sr.残差块数量;k++)
{
cout<<"\r"<<k;
//备份
卷积层复制(源,源备份);
层=残差块0->卷积层;
vl_nnconv(源,目标,层 ,1,1,1,1,1,1);
torch_BatchNorm(目标,bnorm->权重,bnorm->偏移,bnorm->均值,bnorm->方差);bnorm++;
vl_nnrelu(目标);
//save_卷积层2jpg(目标,"cc0");
层++;
vl_nnconv(目标,源,层 ,1,1,1,1,1,1);
//vl_Norm(源);
torch_BatchNorm(源,bnorm->权重,bnorm->偏移,bnorm->均值,bnorm->方差);bnorm++;
// //求和
卷积层相加(源备份,源);
残差块0++;//到下残差块
}
cout<<endl;
del卷积层(*源备份);
//用于各个层
#define 反卷积和归一化(ConvX)/* 上采样、下采样 */ \
\
层=sr.ConvX;/* Conv2 层 */ \
if(层->输出维度 != 目标->depth || 目标->width != wid || 目标->height != hei)\
Resize卷积层(*目标,wid,hei,层->输出维度);\
vl_nnconvt(源,目标,层,2,2, 1,1,1,1) ;\
torch_BatchNorm(目标,bnorm->权重,bnorm->偏移,bnorm->均值,bnorm->方差);bnorm++;\
vl_nnrelu(目标);/*激励函数Prelu*/\
\
std::swap (源,目标);\
cout<<"第一上采样层..."<<endl;
wid=wid*2;hei=hei*2;
反卷积和归一化(上采样层1);
cout<<"第二上采样层..."<<endl;
wid=wid*2;hei=hei*2;
反卷积和归一化(上采样层2);
cout<<"输出层..."<<endl;
层=sr.输出层;
if(层->输出维度 != 目标->depth || 目标->width != wid || 目标->height != hei)
Resize卷积层(*目标,wid,hei,层->输出维度);
pad=层->核宽/2;
vl_nnconv(源,目标,层 ,1,1,pad,pad,pad,pad);
del卷积层(*源);
vl_tanh(目标);//激励函数
cout<<"图像转换成jpg格式... "<<endl;
伸缩边(*目标, x0, y0,false);
//加上输入
卷积层相加(&备份,目标);
del卷积层(备份);
//load_mat2卷积层 ("me/add_10.txt",目标) ; //Keras中保存的
//save_卷积层2txt (目标,"add10.txt") ; //比对
卷积层乘以(*目标,0.5f);//除了2
RGB2bmp(*目标);
del卷积层(*目标);
savejpg(savefilename);
cout<<"转换文件已经保存为: "<<savefilename<<endl;
}
下载:
win32去运动模糊程序2
由deblur-gan-master(Keras的generator.h5)改编过来的去运动模糊,对拍摄的太模糊的图可以试试,可能会清楚一点。
https://download.csdn.net/download/juebai123/11074848