
clear all; 
close all;
clc;
addpath(genpath('Images\'));
addpath(genpath('Codes\'));
addpath(genpath('Utilize\'));

%% Read images
[filename, filepath, FilterIndex ] = uigetfile('Images/*.*','Read image');
O_Img =  double(imread(fullfile(filepath,filename))) ;
N_Img = O_Img + 5 * randn(size(O_Img));                                   % Generate noisy image

%% Symmetric boundary extension
Extend_boundary = 0;
if Extend_boundary == 1
    args.patsize = 51;
    N_Img1 = [N_Img fliplr(N_Img)];
    N_Img2 = N_Img1(:,1:size(N_Img,2) + floor(args.patsize/1) + 1,:);
    N_Img3 = [fliplr(N_Img) N_Img2];
    N_Img4 = N_Img3(:,size(N_Img,2)- floor(args.patsize/1) + 1:end,:);
    
    N_Img5 = [N_Img4;flipud(N_Img4)];
    N_Img6 = N_Img5(1:size(N_Img,1) + floor(args.patsize/1) + 1,:,:);
    N_Img7 = [flipud(N_Img4);N_Img6];
    N_Img8 = N_Img7(size(N_Img,1)- floor(args.patsize/1) + 1:end,:,:);
    N_Img = N_Img8;
end
figure; imshow(uint8(N_Img),[]);hold on;
%% Manual selection
initial_points=zeros(2, 2);
for i=1:2
    initial_points(:, i)=ginput(1)';
    plot(initial_points(1, i), initial_points(2, i), 'rx');  % It is recommended to choose the rain region with clear background
    hold on;
end

%% Transform rgb to ycbcr
[h,  w, ch]     =   size(O_Img);
if ch == 3
    NI_Img      =  rgb2ycbcr( uint8(N_Img) );
    N_Img       =  double( NI_Img(:,:,1));
    EImg(:,:,2)    =   NI_Img(:,:,2);
    EImg(:,:,3)    =   NI_Img(:,:,3);
    figure, imshow(N_Img,[]);
else
    N_Img       =  double( N_Img);
    figure, imshow(N_Img,[]);
end

%% Initialization
tic
args       =  parse_inputs(N_Img, initial_points);                         % parameter initialization
[ini_tfm_matrix] =  transformed_matrix_initial(args);                      % rotation matrix initilization
para       =  rainparaset;                                                 
toc

%% main function
tic
[E_Img]   =  RTLR_DeRaining( N_Img, ini_tfm_matrix,args);
toc 
if ch == 3
    EImg(:,:,1)   =  uint8(E_Img);
    E_Img          =  double(ycbcr2rgb( EImg ));
end
figure, imshow(uint8(E_Img),[]);
