% SVM klasifikacija blokova velicine 128x128 piksela izdvojenih sa
% aerofoto snimka Banje Luke

%% Parameters

categories = {'kuce','groblje','industrija','njiva','rijeka','zelenilo'};
Nclasses = length(categories);

% broj trening slika po klasi
Ntraining_class = 10;

%% Ucitavanje deskriptora

load bl_dense_bow_5k

Nsamples = size(hist, 2);

% odrediti oznake klasa za sve slike
C = zeros(Nsamples, 1);
for i = 1:Nsamples
    [path, filename] = fileparts(images{i});
    C(i) = strmatch(filename(1), categories);
end

%% Klasifikacija 

% klasifikacija se ponavlja Nruns puta sa razlicitim trening/test podjelama
% (N-fold cross validation)

Nruns = 1;

Cm = zeros(Nclasses, Nclasses, Nruns);
Cm_raw = zeros(Nclasses, Nclasses, Nruns);

for r = 1:Nruns
    % Podjela na trening i test skup
%     train_ind = [];
%     
%     for c = 1:Nclasses
%         class_ind = find(C == c);
%         ii = randperm(length(class_ind));
%         train_ind = [train_ind; class_ind(ii(1:Ntraining_class))];
%     end
%     test_ind = setdiff(1:Nsamples, train_ind);
    
    % Ucitavanje predefinisane podjele kolekcije na trening i test skup
    % Ako se zeli testiranje klasifikatora na vise razlicitih podjela
    % komentarisati sljedecu liniju i ukloniti komentare sa prethodnog bloka
    load training_test
    
    % LIBSVM ocekuje primjere u redovima
    training_set = transpose(hist(:, train_ind)); 
    test_set = transpose(hist(:, test_ind));
   
    % L2 normalizacija
    training_set = training_set ./ repmat(sqrt(sum(training_set.^2, 2)), 1, size(training_set, 2));
    test_set = test_set ./ repmat(sqrt(sum(test_set.^2, 2)), 1, size(test_set, 2));
          
    % obucavanje klasifikatora i klasifikacija
    scores = svm_lin(training_set, test_set, 100, C(train_ind), Nclasses);
    
    % 1-protiv-svih
    [foo, ctest_hat] = max(scores, [], 2);
    
    % Izracunavanje matrica konfuzija
    for j = 1:Nclasses
        for i = 1:Nclasses
            % red i, kolona j je dio slika iz klase i koje su klasifikovane u
            % klasu j
            Cm(i, j, r) = 100*sum((C(test_ind)==i) .* (ctest_hat==j))/sum(C(test_ind)==i);
            Cm_raw(i, j, r) = sum((C(test_ind)==i) .* (ctest_hat==j));
        end
    end
    
end

sss = zeros(Nruns, Nclasses);
for i = 1:Nruns
    sss(i, :) = diag(Cm(:, :, i));
end

figure, imagesc(mean(Cm, 3)); colorbar
colormap(jet)

title(['Macroavg: ' num2str(mean(mean(sss, 2)), '%.2f') ' \pm ' num2str(std(mean(sss, 2)), '%.2f') '%']);

