function START(handles,scalingFactor,ROI_extra,ROI_enhance,op1,op2,op3,op4,op5,op6,op7,op8, op9,realWidth,myUnit)
%**************************************************************************
%
% This is main function to peform plankton image analysis using a
% pre-trained VGG network. The main steps include:
% 1. Specify your file types, video or image. If it is a video file, the
%    program will create a folder and break the video file down to frame.
% 2. Navigate to the folder and read in all images.
% 3. Navigate to the folder containing library for training.
% 4. Perform classification using VGG network.
% 5. Create an excel datasheet and record results.
% Modification Date:2018-12-15  By: Hongsheng Bi
%**************************************************************************
% If you want to change the value of the default parameter:
%      PIE_MC_V2('scalingFactor',0.25,'FLAG_save_figure', false,  'FLAG_imadjust',false, ...
%      'FLAG_move_images',false,'FLAG_show',false,'FLAG_enhancement',false)
%**************************************************************************
% Modified by Kaichang CHENG in Dec. 28, 2018.
% The main work is to add the procedure of ROI enhancement.
%**************************************************************************
% Modified by Kaichang CHENG in Jan. 07, 2019.
% 1. The dataset was updated.(7 classes,train:7*2048,test:7*512)
% 2. The main difference is to use a new  finetuned Resnet50 model to replace
%    original vgg19 model. And the new Resnet50 model was trained on new
%    dataset, which is richer and more accurate. So, this new Resnet50 model
%    has a relatively better performance even without ROI enhancemnent.
%**************************************************************************
% Modified by Kaichang CHENG in Jan. 23, 2019.
% 1. Take the special color map for input image into consideration.
% 2. Update the procedure of ROI enhancement.Make sure the background is
%    totally white based on the maximum of color map.
% 3. Add the script file in .m format  of traing code for ResNet50.
%**************************************************************************
% Modified by Kaichang CHENG in Mar. 3, 2019.
% 1. Add the procedure to save figures with target in rectangular box.
% 2. Move the image into another folder after enumeration.
% 3. Add the procedure of pre-processing before display.
% 4. Reduce the target threshold to include more small-size target.
% 5. Use multi-cpu model to speed up (if possible).
% 6. All the functions have default value, and user can change them by
% indicating the value of function PIE_MC() in command line.
%**************************************************************************
% Modified by Kaichang CHENG in Mar. 6, 2019.
% 1. Change the classification procedure to parallel mode to speed up.
% 2. Unless specified by the user, files loaded by default are images.
% 3. Choose the folder including files not the files directly.
% 4. Add a parameter,note,for function video2image.m, making the procedure
%    to be compatible with system operation (Windows or Linux).
%**************************************************************************
% Modified by Kaichang CHENG in Mar. 15, 2019.
% 1. Control the number of negative samples in a folder is less than 5000.
% 2. Change the enhancement procedure to be more suitable for PlanktonScope
%    images.
%**************************************************************************
% Modified by Kaichang CHENG in Mar. 27, 2019.
% 1. Make it more compatible with different color map.
% 2. Use the newly developed adaptive ROI enhancement based on gradient
% and imsegkmeans.
% 3. Finetune the window size and k value of sauvola method to include more
% small targets.
%
%**************************************************************************
% Modified by Kaichang CHENG in Apr. 2, 2019.
% 1. Change the markup text to be more formal.
% 2. Change the
%
%**************************************************************************
% Modified by Kaichang CHENG in Apr. 22, 2019.
% 1. Use the Otsu's method to extract ROIs based on remove the uneven
% illumnination.
% 2. Use the Feng's method to enhance ROIs.
%
%**************************************************************************
% Modified by Kaichang CHENG in Sep. 09, 2019.
% 1. Add scale line mode.
% 2. Use more accurate classifier.
%
%**************************************************************************
% Modified by Kaichang CHENG in Dec. 15, 2019.
% 1. Use the optimized Sauvola method(sauvola_plankton) to extract ROIs.
%
%**************************************************************************
%
% GUI designed by Kaichang CHENG in Jul. 10, 2019.
%
%**************************************************************************
%gpuDevice(1);
global flag_stop
global flag_exit
global flag_finish %finish enumeration
flag_finish=true;
%check
FLAG_save_figure=logical(op4);
FLAG_imadjust=logical(op5);
FLAG_move_images=logical(op6);
FLAG_show=logical(op7);
%FLAG_enhancement=logical(op8);
%FLAG_enhancement=false;
% Test the oparation system of environment
My_sys=computer;
if My_sys(1)=='P'
    note='\';% For Windows
else
    note='/';% For Linux
end
%%
srcDir=uigetdir('Choose source directory.'); %Choose source directory
date_now=datestr(now,'yyyy-mm-dd_HH-MM-SS');
if ~isequal(srcDir,0)   % Check choice
    allnames_tif=struct2cell(dir([srcDir note '*.tif'])); % Only for .tif format
    allnames_tiff=struct2cell(dir([srcDir note '*.tiff'])); % Only for .tif format
    allnames_jpg=struct2cell(dir([srcDir note '*.jpg'])); % Only for .jpg format
    allnames_bmp=struct2cell(dir([srcDir note '*.bmp'])); % Only for .bmp format
    allnames_png=struct2cell(dir([srcDir note '*.png'])); % Only for .png format
    fileNames=[allnames_tif,allnames_tiff,allnames_jpg,allnames_bmp,allnames_png];
    
    if isempty(fileNames)
        warndlg('No image!',' Warning!')
        flag_finish=false;
        return
    end
    disp('Image processing... ');
else
    warndlg('No selection!',' Warning!')
    flag_finish=false;
    return
end
% Load the network
fprintf(['Input 1 for Plankton Scope Network\n',...
         'Input 2 for ZOOVIS Network\n']);
op8 = input('Selection ');
FLAG_enhancement = op8;
switch FLAG_enhancement
    case 1
        disp('PlanktonScope Library');
        %net = load('network_Resnet50_SouthChinaSea_equalScaling_V3.mat');
        net = load('network_Resnet50_SouthChinaSea_equalScaling_V3_retraining.mat');
        %net = load('network_Resnet50_SouthChinaSea.mat');
    case 2
        disp('ZOOVIS Library');
        net = load('network_Resnet50_ZOOVIS.mat');
    otherwise
        disp('Wrong selection');
end
%%
% %This section read in the group names for classification from library.

groupNames=net.network.Layers(end,1).ClassNames;
% Input size of the ROI for the network.
InputSize=net.network.Layers(1,1).InputSize;
%%
%=======================================================================
%This section set up the folder for ROI extractions for each group.
%Eumeration will be stored in a separate result file.
%=======================================================================
po=find(srcDir==note);
srcName=srcDir((po(end)+1):end);

PathTemp0=[srcDir(1:end)  '_Results_' date_now];
if ~exist(PathTemp0,'dir')
    mkdir(PathTemp0);
end

if ~isequal(srcDir,0) && ~isequal(fileNames,[]) %If the user has specified
    % Make the folder to save images finished enumeration
    if FLAG_move_images
        PathTemp1=[PathTemp0 note srcName '_Finished'];
        if ~exist(PathTemp1,'dir')
            mkdir(PathTemp1);
        end
        %the image file, continue.
        roiDir = [PathTemp1 note srcName '_PIE_Results']; %Create file directory for ROIs
        numberGroups = size(groupNames, 1);
        for idx = 1:numberGroups
            roiTemp = [roiDir note groupNames{idx}];
            if ~exist(roiTemp,'dir')
                mkdir(roiTemp);
            end
        end
        
        if FLAG_save_figure
            PathTemp2=[PathTemp0 note srcName '_Details' note 'Tragets with boxes'];
            if ~exist(PathTemp2,'dir')
                mkdir(PathTemp2);
            end
            
            PathTemp4=[PathTemp0 note srcName '_Details' note 'Binarized images'];
            if ~exist(PathTemp4,'dir')
                mkdir(PathTemp4);
            end
        end
    else
        %the image file, continue.
        roiDir = [srcDir(1:end) note srcName '_PIE_Results_' date_now]; %Create file directory for ROIs
        numberGroups = size(groupNames, 1);
        for idx = 1:numberGroups
            roiTemp = [roiDir note groupNames{idx}];
            if ~exist(roiTemp,'dir')
                mkdir(roiTemp);
            end
        end
        
        % Make the folder to save figures  with rectangular boxes
        if FLAG_save_figure
            PathTemp2=[PathTemp0 note srcName '_Details' note 'Targets with boxes'];
            if ~exist(PathTemp2,'dir')
                mkdir(PathTemp2);
            end
            
            PathTemp4=[PathTemp0 note srcName '_Details' note 'Binarized images'];
            if ~exist(PathTemp4,'dir')
                mkdir(PathTemp4);
            end
        end
    end
else
    warndlg('No file!',' Warning!')
    return
end

%%
%========================================================================
%Setting up output for result file
%Pre-allocate a matrix with n images and m groups.
%Set up rownames and columnames for the final result.
%========================================================================
if iscell(fileNames) == 0
    numberImage = 1;
    %colNames = fileNames;
else
    numberImage = size(fileNames, 2);
    %colNames = fileNames';
end
disp(['Number of image files: ',num2str(numberImage)]);
countResult = zeros(numberImage, numberGroups);
rowNames =  groupNames;
colNames = fileNames(1,:);
%%
%tic
% The number of nagative samples.
numNegative=0;
axes(handles.axes1);
for idxImg = 1 : numberImage
    if iscell(fileNames) == 0 %Single image will force the variable
        %fileNames becomes a string variable
        %instead of a cell array.
        tempName = fileNames;
    else
        tempName = fileNames{1, idxImg};
    end
    [tempImage,MAP] = imread([srcDir,note, tempName]); % CKC  
    if ~isempty(MAP)
        tempImage=ind2gray(tempImage,MAP);
    end
    %Convert image to a grayscale image.
    if size(tempImage, 3) == 3
        tempImage = rgb2gray(tempImage);
    end
    meanIntensity=mean(double(tempImage(:)));
    if (meanIntensity>=255||meanIntensity<=5)
        disp(['Image ', num2str(idxImg), ' : ', tempName,'(Invalid)']);
        continue;
    end
    
    scaleImage = imresize(tempImage, ceil(size(tempImage).*scalingFactor));
    if FLAG_show
        if FLAG_imadjust    
            tempImage1 = imadjust(tempImage);
        else
            tempImage1 = tempImage;
        end
    end

    if op1==1
        S=ROI_extra(1);
        T=ROI_extra(2);
        M=ROI_extra(3);
        A=ROI_extra(4);
        [propROI, outBW] = PS_roiExtraction_local(scaleImage,S,T,M,A);
        expandSize=20;
    else
        M=ROI_extra(5);
        A=ROI_extra(6);
        [propROI, outBW] = PS_roiExtraction_global(scaleImage,M,A);
        expandSize=40;
    end
    if isempty(propROI) == 0
        lenROI = size(propROI, 1);
        % All the ROIs of one image saved in a 4-D array (h,w,c,N).
        ROIs_array=uint8(zeros([InputSize,lenROI]));
        cropBox_array=zeros(lenROI,4);
        outROI_cell=cell(1,lenROI);
        %parfor idxROI = 1: lenROI
        for idxROI = 1: lenROI
            tempBox = (propROI(idxROI).BoundingBox)*(1/scalingFactor);
            cropBox = roiExpand(tempImage, tempBox, expandSize);
            tempCrop =  imcrop(tempImage, cropBox);
            if FLAG_enhancement
                if op2==1
                    S=ROI_enhance(1);
                    M=ROI_enhance(2);
                    B=ROI_enhance(3);
                    outROI = PS_roiEnhance_threshold(tempCrop,S,M,B); %
                else
                    M=ROI_enhance(4);
                    B=ROI_enhance(5);
                    outROI = PS_roiEnhance_energy(tempCrop,M,B);
                end
            else
                outROI=tempCrop;
            end
            if sum(outROI(:)) ~= 0
                %************************************************
                %   without  equal scaling
                %tempROI = imresize(outROI, InputSize(1:2));
                %classROI = cat(3, tempROI, tempROI, tempROI);
                %************************************************
                %   with  equal scaling
                classROI=equalScaling(outROI,InputSize(1));
                %figure,imshow(classROI);
                %************************************************
                ROIs_array(:,:,:,idxROI)=classROI;
                cropBox_array(idxROI,:)=cropBox;
                outROI_cell(idxROI)={outROI};
                %roiResult = classify(net.network, classROI);
            end
        end
        if FLAG_show()
            imshow(tempImage1,'InitialMagnification','fit')
            drawnow();
        end
        %predictResult = cellstr(classify(net.network, ROIs_array));
        [temp_results,scores]=classify(net.network, ROIs_array);
        pp=max(scores,[],2);
        predictResult = cellstr(temp_results);  
        colors=cell(1,lenROI);
        lables=cell(1,lenROI);
        for idxROI = 1: lenROI
            outROI=outROI_cell{idxROI};
            roiResult=predictResult{idxROI};
            
            [tf, groupResult] = ismember(roiResult, groupNames);
            if ~any(strcmp(char(roiResult), {'Negative','negative','False','false'}))
                if tf == 1
                    colors{idxROI}="c";
                    %lables{idxROI}=strcat(num2str(idxROI), ':', char(roiResult));
                    lables{idxROI}=strcat(num2str(idxROI), ':', char(roiResult),'(',num2str(100*pp(idxROI),4),'%)');
                    roiName = [tempName, '_', num2str(idxROI), '.bmp'];
                    classFolder=groupNames{groupResult};
                    roiPath = [roiDir note classFolder];
                end
            else
                numNegative=numNegative+1;
                if tf == 1
                    colors{idxROI}="yellow";
                    lables{idxROI}=num2str(idxROI);
                    roiName = [tempName, '_', num2str(idxROI), '.bmp'];
                    classFolder=groupNames{groupResult};
                    indexNegative=floor(numNegative/5000);
                    if indexNegative>0
                        PathTemp3 = [roiDir note classFolder '_' num2str(indexNegative)];
                        if ~exist(PathTemp3,'dir')
                            mkdir(PathTemp3);
                        end
                        roiPath = PathTemp3;
                    else
                        roiPath = [roiDir note classFolder];
                    end
                end
            end
            if(~isempty(outROI))
                imwrite(outROI,[roiPath, note, roiName]);
            end
        end
        if FLAG_show
            if size(tempImage,1)>=2000
                textSize=38;
                lineWid=5;
            else
                textSize=24;
                lineWid=2;
            end
            myText=insertObjectAnnotation(tempImage1,'rectangle',cat(1,cropBox_array),...
                lables,'Color',colors,'TextColor','m','TextBoxOpacity',0.3,'Font','Times New Roman','LineWidth',lineWid,'FontSize',textSize);
            %imshow(annotation,'InitialMagnification','fit');
            if op9
                annotation=addScaleLine(myText,realWidth,myUnit,textSize,lineWid);
            else
                annotation=myText;
            end
            imshow(annotation,'InitialMagnification','fit');
            drawnow();
        end
    end
    %====================================================================
    %This part start to enumerate each taxa in one image by examining the
    %classified result for each ROI.
    %====================================================================
    disp(['Image ', num2str(idxImg), ' : ', tempName]);
    
    % Move the image into another folder after enumeration.
    if FLAG_move_images
        movefile([srcDir,note tempName],PathTemp1);
    end
    
    % Save figures with target in rectangular box.
    if FLAG_save_figure && FLAG_show
        imwrite(annotation,[PathTemp2 note tempName '.png']);% save gcf
        imwrite(outBW,[PathTemp4 note tempName '_BW.png']);
    end
    %save the result
    if op3==0
        predictResults=string(predictResult);
        if ~isempty(predictResults)
            fid=fopen([roiDir,note,'ROIs_PIE_Details.txt'],'a+');           
            fprintf(fid,['<Image %d>  %s:'],idxImg,string(tempName));
            for idx = 1:numberGroups
                speciesCount=length(find(predictResults==groupNames{idx}));
                fprintf(fid,['  %s[%d]'],string(groupNames{idx}),speciesCount);
            end
            fprintf(fid,' \r\n');
            fclose(fid);
        end
    end
    countResult(idxImg, :) = getCounts(groupNames, predictResult);
    if flag_stop || flag_exit
        %Save count result as excel file
        if op3==1
            countCell = num2cell(countResult);     %Convert data to cell array
            countMatrix=[{'ImageName'} rowNames'; colNames' countCell];%Join cell arrays
            outFile = [roiDir, note, 'countResults.xlsx'];
            status=xlswrite(outFile,countMatrix);     %Write data and both headers
            
            if ~status
                warndlg('Writing to Excel failed!',' Warning!')
                return
            end
        else
            predictResults=string(predictResult);
            if ~isempty(predictResults)
                fid=fopen([roiDir,note,'ROIs_PIE_Details.txt'],'a+');          
                fprintf(fid,['<Image %d>  %s:'],idxImg,string(tempName));
                for idx = 1:numberGroups
                    speciesCount=length(find(predictResults==groupNames{idx}));
                    fprintf(fid,['   %s[%d]'],string(groupNames{idx}),speciesCount);
                end 
                fprintf(fid,' \r\n');
                fclose(fid);
            end
        end
        if flag_stop
            disp('Stop!')
        end
        if flag_exit
            close gcf;
            disp('Exit!')
        end
        % Finished enumeration£¡
        msgbox('Finished Enumeration!','Caution!','warn');
        flag_finish=false;
        return
    end
end
%toc
%%
%=====================================================================
%Save count result as excel file
if op3==1
    countCell = num2cell(countResult);     %Convert data to cell array
    countMatrix=[{'ImageName'} rowNames'; colNames' countCell];%Join cell arrays
    outFile = [roiDir, note, 'countResults.xlsx'];
    status=xlswrite(outFile,countMatrix);     %Write data and both headers
    
    if ~status
        warndlg('Writing to Excel failed!',' Warning!')
        return
    end
else
%     predictResults=string(predictResult);
%     if ~isempty(predictResults)
%         fid=fopen([roiDir,note,'ROIs_PIE_Details.txt'],'a+');
%         fprintf(fid,['<Image %d>  %s:'],idxImg,string(tempName));
%         
%         for idx = 1:numberGroups
%             speciesCount=length(find(predictResults==groupNames{idx}));
%             fprintf(fid,['   %s[%d]'],string(groupNames{idx}),speciesCount);
%         end
%         fprintf(fid,' \r\n');
%         fclose(fid);
%     end
end
% Finished enumeration£¡
msgbox('Enumeration complete!','Done','warn');
flag_finish=false;
end