在matlab7.0中运行LapSRN 超分辨率重建

这个和前面差不多,

先外框架:

%        金字塔式网络实现的快速准确的超分辨率
clear all;

img_filename = '测试2.jpg';

%% 参数
scale  = 4; % SR 采样比例 可以是 2、4 或 8 倍

%% 设置路径
addpath(genpath('utils'));
addpath(fullfile(pwd, 'matconvnet/matlab'));
vl_setupnn;

%% 加载预训练模型
model_filename = fullfile('pretrained_models', sprintf('LapSRN_x%d.mat', scale));

fprintf('载入 %s\n', model_filename);
net = load(model_filename);
net=net.net;



%% 加载 LR 图像
fprintf('载入 %s\n', img_filename);
im_l=imread(img_filename);
im_l=rgb2ycbcr(im_l);
img_LR = single(im_l(:,:,1)) /255;%;



%% 应用 LapSRN
fprintf('应用 LapSRN for %dx SR\n', scale);

%返回 2、4 和 8 倍重建(根据选中网络而定)
[im_HR1,im_HR2,im_HR3] = myLapSRN(net, img_LR); 



%% 显示结果

im_H = imresize(im_l,2,'bicubic');
im_H=single(im_H);
im_H(:,:,1)= im_HR1*255;
im_H=ycbcr2rgb(uint8(im_H));
figure, imshow(im_H);title(sprintf('由  LapSRN %d 倍重建彩色', 2));
imwrite(im_H, ['LapSRN 2倍重建.jpg']);

if scale>2
    im_H = imresize(im_l,4,'bicubic');
    im_H=single(im_H);
    im_H(:,:,1)= im_HR2*255;
    im_H=ycbcr2rgb(uint8(im_H));
    figure, imshow(im_H);title(sprintf('由  LapSRN %d 倍重建彩色', 4));
    imwrite(im_H, ['LapSRN 4倍重建.jpg']);
end
if scale==8
    im_H = imresize(im_l,8,'bicubic');
    im_H=single(im_H);
    im_H(:,:,1)= im_HR3*255;
    im_H=ycbcr2rgb(uint8(im_H));
    figure, imshow(im_H);title(sprintf('由  LapSRN %d 倍重建彩色', 8));
    imwrite(im_H, ['LapSRN 8倍重建.jpg']);
end

核心函数:

% LapSRN 超分辨率重建 - 各层代码
function [hR1,hR2,hR3] = myLapSRN(net, imlow)

hR1=[];hR2=[];hR3=[];

%总层数
l=length(net.layers);


j=0;%卷积层计数,可以去掉

upsample_num=0;% 图像放大计数
residual_num=0;% 残差图计数

%循环各层直至结束
for i=1:l %
    
    disp(['第 ',num2str(i),' 层']);
%      disp(net.layers(i).name);
%     disp(net.layers(i).type);
%     disp(net.layers(i).inputs);
%     disp(net.layers(i).outputs);
%     disp(net.layers(i).params);
%     disp(net.layers(i).block);
    if strTong(net.layers(i).type,'dagnn.Conv')
        
            j=j+1
            disp('卷积层');
            
            
            %得到权重(也就是卷积核)和偏移
            disp('参数是:');
            disp(net.layers(i).params);
            fft=net.layers(i).params{1};
            for k=1:length(net.params)
                if strTong(net.params(k).name,fft)
                    weight=net.params(k).value;
                    break;
                end
            end
            if net.layers(i).block.hasBias==false
                bias=[]; % 无偏移
            else
                fft=net.layers(i).params{2};
                for k=1:length(net.params)
                    if strTong(net.params(k).name,fft)
                        bias=net.params(k).value;
                        break;
                    end
                end
            end
            %得到输入
            disp('输入是:');
            disp(net.layers(i).inputs);
            disp('输出是:');
            disp(net.layers(i).outputs);
            if strTong(net.layers(i).inputs{1},'LR') %第一层
                convfea = myconv(imlow,weight,bias,'Pad',1);%一图得出64特征图
            else %一以后
                if strBao(net.layers(i).outputs{:}, 'residual')
                    residual_num=residual_num+1;
                    
                    if residual_num==1
                        residual1= myconv(convfea,weight,bias,'Pad',1);% 2倍残差图
                    end
                    if residual_num==2
                        residual2= myconv(convfea,weight,bias,'Pad',1);% 4倍残差图
                    end
                    if residual_num==3
                        residual3= myconv(convfea,weight,bias,'Pad',1);% 8倍残差图
                    end
                else 
                        %中间层 64特征图合成1图 再重新生成深一层64特征图
                        convfea = myconv(convfea,weight,bias,'Pad',1);

                end
            end
    end
    if strTong(net.layers(i).type,'dagnn.ReLU' )
           
            disp('激励层');
            disp('输入是:');
            disp(net.layers(i).inputs);
            disp('参数是:');
            disp(net.layers(i).params);
            disp('输出是:');
            disp(net.layers(i).outputs);
            convfea = vl_nnrelu(convfea,'leak', 0.2);
        
    end
    
    
    if strTong(net.layers(i).type,'dagnn.ConvTranspose')
        
            
            disp('上采样层');%反向卷积,转置卷积
            
            
            disp('输入是:');
            disp(net.layers(i).inputs);
            
            %得到权重(也就是卷积核)和偏移
            disp('参数是:');
            disp(net.layers(i).params);
            fft=net.layers(i).params{1};
            for k=1:length(net.params)
                if strTong(net.params(k).name,fft)
                    weight=net.params(k).value;
                    break;
                end
            end
            if net.layers(i).block.hasBias==false
                bias=[]; % 无偏移
            else
                fft=net.layers(i).params{2};
                for k=1:length(net.params)
                    if strTong(net.params(k).name,fft)
                        bias=net.params(k).value;
                        break;
                    end
                end
            end
            disp('输出是:');
            disp(net.layers(i).outputs);
            
            upsample=net.layers(i).block.upsample;
            crop=net.layers(i).block.crop;
            numGroups=net.layers(i).block.numGroups;
            opts=net.layers(i).block.opts{:}
            % 字符串是否包含
            if strBao(net.layers(i).outputs{:}, 'img_up') %残差
                upsample_num=upsample_num+1;
                % 图像放大参数是        'upsample', 2 ,'crop', [1 1 1 1],'numGroups', 1
                if upsample_num==1 % 2倍放大图
                    img_up1 = vl_nnconvt(imlow, weight, bias,'upsample', upsample ,'crop', crop,'numGroups',numGroups, opts) ;
                    hR1=img_up1+residual1; % 合成2倍重建图

                else
                    if upsample_num==2 % 4倍放大图
                        img_up2 = vl_nnconvt(hR1, weight, bias,'upsample', upsample ,'crop', crop,'numGroups',numGroups,opts) ;%
                        hR2=img_up2+residual2; % 4倍

                    end
                    if upsample_num==3 % 8倍放大图
                        img_up3 = vl_nnconvt(hR2, weight, bias,'upsample', upsample ,'crop', crop,'numGroups',numGroups, opts) ;%
                        hR3=img_up3+residual3; % 8倍

                    end
                end
            else
                % 残差放大参数是 'upsample', 2 ,'crop', [0 1 0 1],'numGroups', 1
            convfea = vl_nnconvt(convfea, weight, bias,'upsample', upsample ,'crop', crop,'numGroups',numGroups,opts) ;%
                
            end
    end
end
   

%--------------------------------------------------------------------------
%加边并卷积后还原   
function [X] = myconv(X, F, B, option1, value1)
if nargin==3
    X = vl_nnconv(X, F, B);
else
   %消除四边一条线和左上角白点,否则会随着层数的增加,会越来越大
    BoundarySize=1;
    X = padarray(X, [BoundarySize,BoundarySize], 'replicate','both');

    X = vl_nnconv(X, F, B, option1, value1);
    X = X(BoundarySize+1:end-BoundarySize,BoundarySize+1:end-BoundarySize,:);
end

8倍重建效果图:

原图2倍4倍8倍

4倍网络重建图:

2

4倍

这里和前面不同之处,有一个残差放大卷积,图像放大卷积层,这里调用的是 matconvnet 的 vl_nnconvt 。

只好再来编译 vl_nnconvt.cpp 了。而这要用到转置乘法,上文的sgemm已经不够用了,再加一点:

	//printf("sgemm...\n");
	//C := alpha * op ( A ) * op ( B ) + beta * C,
	//beta=0 相当于清0
	//beta=1 相当于加上原来的值
printf("alpha:%f\n",alpha);
printf("beta:%f\n",beta);

//printf("m:%d\n",m);
//printf("n:%d\n",n);
//printf("k:%d\n",k);
//printf("lda:%d\n",lda);
//printf("ldb:%d\n",ldb);
//printf("ldc:%d\n",ldc);
char op[2]={0};
op[0]=op1;printf("op1:%s\n",op);
op[0]=op2;printf("op2:%s\n",op);

int i;
	if(beta==0.0) //这里完成 C = 0(beta) * C
		{
			float * c1=c;
			for(i=0;i<m*n;i++)
			{
				*c1++=0;
			}
		}
if((op2 == 'N') || (op2 == 'n')) //这里完成 C = 1(alpha)* A * B
	{
		int q1,q2;
		int p1,p2,p3;
		int o1,o2;
		o1=-m;p1=-m;
		for(i=0;i<m;i++)  
		{     
			p1++;p3=p1;
			q1=-k;
			o1++;o2=o1;//-m+i
			for(int j=0;j<n;j++)  
			{  
				q1+=k;q2=q1;//  j*k+q
				p2=p1;//q*m+i
				o1+=m;//j*m+i
				for(int q=0;q<k;q++)
				{  
					//c[j*m+i]+=a[q*m+i]*b[j*k+q]; 
					p1+=m;
					c[o1]+=a[p1]*b[q1++];  
				}  
				q1=q2;
				p1=p2;
				  
			} 
			o1=o2;
			p1=p3;
		}  
	}
	else
	{printf("start:t!\n");   ////这里完成 C = 1(alpha)* A * B'
		//就是把 b 转置成 tmpb 再矩阵相乘 
		float  * tmpb=new float[k*n*sizeof(float)];
		float  * tb2=tmpb;
		for(i=0;i<n;i++)
		{
			for(int j=0;j<k;j++)
			{

				*tb2++ =b[j*n+i];
			}
		}
		int q1,q2;
		int p1,p2,p3;
		int o1,o2;
		o1=-m;p1=-m;
		for(i=0;i<m;i++)  
		{     
			p1++;p3=p1;
			q1=-k;
			o1++;o2=o1;//-m+i
			for(int j=0;j<n;j++)  
			{  
				q1+=k;q2=q1;//  j*k+q
				p2=p1;//q*m+i
				o1+=m;//j*m+i
				for(int q=0;q<k;q++)
				{  
					//c[j*m+i]+=a[q*m+i]*b[j*k+q]; 
					p1+=m;
					c[o1]+=a[p1]*tmpb[q1++];  
				}  
				q1=q2;
				p1=p2;
				  
			} 
			o1=o2;
			p1=p3;
		}  
        delete []tmpb;  tmpb=NULL;  
	}

成功后生成一个vl_nnconvt.dll

这个还是比较快的,如果改编成C++的话,要先找一个放大卷积函数,或者反向卷积,转置卷积什么的

先这样吧

猜你喜欢

转载自blog.csdn.net/juebai123/article/details/81046640
今日推荐