clear  
close all 
clc

% Load training and test data using |imageDatastore|.
Training_Dir   = fullfile(toolboxdir('vision'),'visiondata','digits','synthetic');
Testing_Dir = fullfile(toolboxdir('vision'),'visiondata','digits','handwritten');

% imageDatastore recursively scans the directory tree containing the
% 
trainingSet = imageDatastore(Training_Dir,'IncludeSubfolders',true,'LabelSource','foldernames');
testingSet     = imageDatastore(Testing_Dir,'IncludeSubfolders',true,'LabelSource','foldernames');
%% Show a few of the training and test images
close all 
figure;

subplot(3,3,1);
imshow(trainingSet.Files{81});

subplot(3,3,2);
imshow(trainingSet.Files{315});

subplot(3,3,3);
imshow(trainingSet.Files{810});
subplot(3,3,4);
imshow(trainingSet.Files{1000});
subplot(3,3,5);
imshow(trainingSet.Files{500});

subplot(3,3,6);
imshow(testingSet.Files{10});

subplot(3,3,7);
imshow(testingSet.Files{35});

subplot(3,3,8);
imshow(testingSet.Files{80});
subplot(3,3,9);
imshow(testingSet.Files{105});

%% Show pre-processing  and Feature Extraction results
exTestImage = readimage(testingSet,37);
Gray_IM=im2gray(exTestImage);
Binary_IM = imbinarize(Gray_IM);

figure;

subplot(1,3,1)
imshow(exTestImage)
subplot(1,3,2)
imshow(Gray_IM)
subplot(1,3,3)
imshow(Binary_IM)


% Extract HOG features from image

img = readimage(trainingSet, 206);
cellSize = [4 4];
[hog_4x4, vis4x4] = extractHOGFeatures(img,'CellSize',cellSize);
figure
plot(vis4x4); 

%% Extracting HOG Features

% HOG features from each image in training set.


hogFeatureSize = length(hog_4x4);
numImages = numel(trainingSet.Files);
trainingFeatures = zeros(numImages,hogFeatureSize,'single');
for i = 1:numImages
    img = readimage(trainingSet,i);
    
    img = im2gray(img); %convertign the specified truecolor The RGB Images to a grayscale intensity image 
    
   
    img = imbinarize(img);   %  pre-processing step to conver the Imges into black & white
    
    trainingFeatures(i, :) = extractHOGFeatures(img,'CellSize',cellSize);  
end

% similar procedure will be used  with testing set.

numImages_test = numel(testingSet.Files);

testingFeatures = zeros(numImages_test,hogFeatureSize,'single');
for i = 1:numImages_test
    img = readimage(testingSet,i);
    
    img = im2gray(img); %convertign the specified truecolor The RGB Images to a grayscale intensity image 
    
   
    img = imbinarize(img);   %  pre-processing step to conver the Imges into black & white
    
    testingFeatures(i, :) = extractHOGFeatures(img,'CellSize',cellSize);  
end
%% Train and Testing a Decision Tree Classifier


% Get labels for each image.
trainingLabels = trainingSet.Labels;
tree = fitctree(trainingFeatures,trainingLabels);

% Evaluating the the Classifier
% Get labels for each image.
testLabels = testingSet.Labels;

predictedLabels = predict(tree, testingFeatures);

% Tabulate the results using a confusion matrix.
 
cm = confusionchart(testLabels,predictedLabels,'RowSummary','row-normalized','ColumnSummary','column-normalized');

%confMat = confusionmat(testLabels, predictedLabels);
%% Testing Bagging, RF, AdaBoost classifier
clc
close all 

%Create decision tree template; MaxNumSplits is the number of splits
%per tree 
t = templateTree('MaxNumSplits',50,'Reproducible',true);

% the number of trees in the classifier
numTrees = 350; 
Mdl_Bagging = TreeBagger(numTrees,trainingFeatures,trainingLabels,'Method','classification');
predictedLabels_Bagging = predict(Mdl_Bagging, testingFeatures);
figure
confusionchart(testLabels,categorical(predictedLabels_Bagging),'RowSummary','row-normalized','ColumnSummary','column-normalized','Title','Bagging');




%Method — Ensemble aggregation method
%'Bag' | 'Subspace' | 'AdaBoostM1' | 'AdaBoostM2' | 'GentleBoost' | 'LogitBoost' | 'LPBoost' | 'RobustBoost' | 'RUSBoost' | 'TotalBoost'
% Random Forest 
Mdl_RF = fitcensemble(trainingFeatures,trainingLabels,'Method','Bag','Learners',t,'NumLearningCycles',numTrees);
predictedLabels_RF = predict(Mdl_RF, testingFeatures);
figure
 confusionchart(testLabels,predictedLabels_RF,'RowSummary','row-normalized','ColumnSummary','column-normalized','Title','RF');

 figure
plot(loss(Mdl_RF, testingFeatures,testLabels,'Mode','Cumulative'))
hold on
xlabel('Number of trees')
ylabel('Test classification error')

 
 % Boosting " AdaBoost Algorithm" 


 t = templateTree('MaxNumSplits',30,'Reproducible',true);


Mdl_AdaBoost = fitcensemble(trainingFeatures,trainingLabels,'Method','AdaBoostM2','OptimizeHyperparameters','auto'); 
%Mdl_AdaBoost = fitcensemble(trainingFeatures,trainingLabels,'Method','AdaBoostM2','Learners',t,'LearnRate',0.1,'CrossVal','on');
predictedLabels_AdaBoost = predict(Mdl_AdaBoost, testingFeatures);
figure
 confusionchart(testLabels,predictedLabels_AdaBoost,'RowSummary','row-normalized','ColumnSummary','column-normalized','Title','AdaBoost');


%% Testing the performance of Trained model on some testing images 

M=75;
predicted_Image = predict(tree, testingFeatures(M,:))
predicted_Image_Bagging = categorical(predict(Mdl_Bagging, testingFeatures(M,:)))
predicted_Image_RF = predict(Mdl_RF, testingFeatures(M,:))
predicted_Image_Ada = predict(Mdl_AdaBoost, testingFeatures(M,:))
figure
imshow(testingSet.Files{M});

