%% Treinamento das feições HOG (Histogram of Oriented Gradients)

% Baseado em "Digit classification using HOG Features", do MathWorks
% http://www.mathworks.com/help/vision/examples/digit-classification-using-hog-features.html
clear 
clc

% Setar pasta com as amostras
pathLetras = fullfile(pwd, 'Caracteres', 'letras');
pathNum = fullfile(pwd, 'Caracteres', 'num');

% Escanear recursivamente as imagens para o treinamento 
trainSetLetras = imageSet(pathLetras, 'recursive');
trainSetNum = imageSet(pathNum, 'recursive');

%% Testar tamanho do histograma
% 
% img = read(trainSetNum(3), 4);
% 
% % Extract HOG features and HOG visualization
% [hog_16x16, vis2x2] = extractHOGFeatures(img,'CellSize',[16 16]);
% [hog_4x4, vis4x4] = extractHOGFeatures(img,'CellSize',[4 4]);
% [hog_8x8, vis8x8] = extractHOGFeatures(img,'CellSize',[8 8]);
% 
% % Show the original image
% figure
% subplot(2,3,1:3), imshow(img);
% 
% subplot(2,3,5), plot(vis4x4)
% title({'CellSize = [4 4]'; ['Feature length = ' num2str(length(hog_4x4))]});
% 
% subplot(2,3,6), plot(vis8x8)
% title({'CellSize = [8 8]'; ['Feature length = ' num2str(length(hog_8x8))]});
% 
% % Visualize the HOG features
% subplot(2,3,4), plot(vis2x2)
% title({'CellSize = [16 16]'; ['Feature length = ' num2str(length(hog_16x16))]});

%% Escolher com base no gráfico anterior

cellSize = [8 8];


%% Treinar a classificação das letras

img = read(trainSetLetras(3), 4);
[hog_8x8, vis8x8] = extractHOGFeatures(img,'CellSize',cellSize);
hogFeatureSize = length(hog_8x8);

trainFeaturesLetras = [];
trainLabelLetras = [];

for digit = 1:numel(trainSetLetras)
    
    numImagem = trainSetLetras(digit).Count;
    features = zeros(numImagem,hogFeatureSize,'single');
    
    for i = 1:numImagem
        img = read(trainSetLetras(digit),i);
        
        % pre-processamento da amostra
        lThresh = graythresh(img);
        img = im2bw(img,lThresh);
        
        features(i,:) = extractHOGFeatures(img,'CellSize',cellSize);
    end
    
    % Usar o nome da pasta como rótulo do treinamento
    label = repmat(trainSetLetras(digit).Description,numImagem,1);
    
    trainFeaturesLetras = [trainFeaturesLetras; features];
    trainLabelLetras = [trainLabelLetras; label];
end


%% Treinar a classificação dos números

img = read(trainSetNum(3), 4);
[hog_8x8, vis8x8] = extractHOGFeatures(img,'CellSize',cellSize);
hogFeatureSize = length(hog_8x8);

trainFeaturesNum = [];
trainLabelNum = [];

for digit = 1:numel(trainSetNum)
    
    numImagem = trainSetNum(digit).Count;
    features = zeros(numImagem,hogFeatureSize,'single');
    
    for i = 1:numImagem
        img = read(trainSetNum(digit),i);
        
        % pre-processamento da amostra
        lThresh = graythresh(img);
        img = im2bw(img,lThresh);
        
        features(i,:) = extractHOGFeatures(img,'CellSize',cellSize);
    end
    
    % Usar o nome da pasta como rótulo do treinamento
    label = repmat(trainSetNum(digit).Description,numImagem,1);
    
    trainFeaturesNum = [trainFeaturesNum; features];
    trainLabelNum = [trainLabelNum; label];
end


%% Treino do classificador

classLetras = fitcecoc(trainFeaturesLetras, trainLabelLetras);
classNum = fitcecoc(trainFeaturesNum, trainLabelNum);

%% Salvar as variáveis
save('trainHOG4.mat')



