function [E_Img,FPN]   =  LSSC_DeNoising( N_Img, J, S, Par )

E_Img           = N_Img;                                                        % Estimated Image
[Height, Width]  = size(E_Img);  
[Neighbor_arr, Num_arr, Self_arr] =	NeighborIndex(N_Img, Par);                  % PreCompute the all the patch index in the searching window 
for iter = 1 : Par.inner_max_iter        
    E_Img             	=	E_Img + Par.inner_delta*(N_Img - E_Img);
    [CurPat, Sigma_arr]	=	Im2Patch( E_Img, Par);                        % image to patch and estimate local noise variance
    
    if (mod(iter-1,2)==0)
        Par.inner_patnum = Par.inner_patnum - 5;                                            % Lower Noise level, less NL patches
        NL_mat  =  Block_matching(CurPat, Par, Neighbor_arr, Num_arr, Self_arr);% Caculate Non-local similar patches for each
        if(iter==1)
            Sigma_arr = Par.nSig * ones(size(Sigma_arr));                       % First Iteration use the input noise parameter
        end
    end
    [EPat, W]       =  PatEstimation( NL_mat, Self_arr, Sigma_arr, CurPat, Par );   % Estimate all the patches
    [IMout, Weight] =  Patch2Im( EPat, W, Par.inner_patsize, Height, Width );
    [FPN]           =  FPN_updata(N_Img, E_Img, 'svds', Par );
    [E_Img]         =  ImUpdata(N_Img, E_Img, FPN, IMout, Weight, Par );
end
return;


