%TESTOVANIE DETEKCIE PRE ANATOMICKU STRUKTURU MEATUS ACUSTICUS EXTERNUS NA
%PACIENTSKEJ DATABAZE no.47

load('MAE_databaza_augment.mat'); %nacítanie celej tréningovej databázy
load('MAE_oznacene47.mat'); %nacitanie oznacenych dat pre pacienta 47 pre hodnotenie

%pacienti = {'data_46.mat' 'data_47.mat'};
    pacient = load('data_47.mat'); %nacitanie 
    pacient = struct2cell(pacient);
    pacient = pacient{1};
    
%*************Zmenit na spravne*************
testovacie_negativne = testovacie_negativne47;
testovacie_pozitivne = testovacie_pozitivne47;

%V prípade pacienta no.46
%testovacie_negativne = testovacie_negativne46;
%testovacie_pozitivne = testovacie_pozitivne46;
    
mkdir HOGmae47 %vytvorenie priecinku
folder = "HOGmae47/" %adresovanie priecinku
nazovPacienta = "47"
useVGG = false; % aké príznaky sa majú využiť v prípade VGG - true, v prípade HOG false

for cSize=2:2:12 %definuje veľkosť parametru cell size pre HOG extrakciu
    for s=3:3:24 %definuje kroky s ktorým sa prechádzajú rezy

        if useVGG
            net = vgg16(); %využitie VGG-16 konvolučných neurónových sietí
        end

        l=length(vysledok_negativne); %počet snímok v databázy negatívne detekcie
        w=size(vysledok_pozitivne{1},1); %veľkosť anatomickej štruktúry
        h=size(vysledok_pozitivne{1},2);
        
        %EXTRAKCIA PRIZNAKOV pre negativnu triedu
        for k=1:l
            bunka=vysledok_negativne{k}; %vyberie zaradom všetky snímky z databázy
            bunka = uint8(255 .* ((double(bunka)-min(bunka(:)))) ./ (max(bunka(:)-min(bunka(:)))));% normalizacia
           %EXTRAKCIA PROSTREDNICTVOM VGG
            if useVGG 
                z=imresize(bunka,[224 224]); %zmena velkosti obrazu pre vstup do VGG
                bunka = cat(3, z, z, z);
                featureVector = activations(net, bunka, 'pool5', ...
                'MiniBatchSize', 1, 'OutputAs', 'columns'); %extrakcia priznakov z 5. pooling vrstvy
            
                %extrahuje HOG príznaky z danej snímky
                featureVector = transpose(featureVector);
            %EXTRAKCIA PROSTREDNICTVOM HOG
            else
                [featureVector,hogVisualization] = extractHOGFeatures(bunka,'CellSize',[cSize cSize]);
            end

            Priznakovy_vektor_neg(k,:)=featureVector(1,:); %vždy sa na daný riadok uloží príznakový vekto
        end

    %EXTRAKCIA PRIZNAKOV pre pozitivnu triedu
        m=length(vysledok_pozitivne);
        for k=1:m 
            bunka=vysledok_pozitivne{k};
            bunka = uint8(255 .* ((double(bunka)-min(bunka(:)))) ./ (max(bunka(:)-min(bunka(:)))));% normalizacia
            if useVGG
                z=imresize(bunka,[224 224]);
                bunka = cat(3, z, z, z);
                featureVector = activations(net, bunka, 'pool5', ...
                'MiniBatchSize', 1, 'OutputAs', 'columns'); 
                featureVector = transpose(featureVector);
            else
                [featureVector,hogVisualization] = extractHOGFeatures(bunka,'CellSize',[cSize cSize]);
            end
            Priznakovy_vektor_poz(k,:)=featureVector(1,:); %vždy sa na daný riadok uloží daný
        end

        %TVORBA POPISOV pre extrahovane priznaky
        neg=length(vysledok_negativne);
        poz=length(vysledok_pozitivne);

        negativne_titles = strings(neg,1); %vytvorenie negativnych priznakov
        for i=1:neg
            negativne_titles(i)='negativne';
        end

        pozitivne_titles = strings(poz,1); %vytvorenie pozitivnych priznakov
        for i=1:poz
            pozitivne_titles(i)='pozitivne';
        end
        
        priznaky_titles=[negativne_titles;pozitivne_titles];
        priznaky=[Priznakovy_vektor_neg;Priznakovy_vektor_poz]; %spojenie príznakov
        %do jedného súboru

%TRENOVANIE CLASSIFIKATORU
        classifier=fitcecoc(priznaky,priznaky_titles);

        
        predictions = zeros(1,length(testovacie_negativne)+length(testovacie_pozitivne));
        %vytvorenie predikcii pre maticu zamen (confusion matrix)
        %t.j. porovnanie s tzv. groundtruth t.j. ručne označenými datami
        
        for n=1:length(testovacie_negativne)
            bunka=testovacie_negativne{n};
            z=bunka; 
            z = uint8(255 .* ((double(z)-min(z(:)))) ./ (max(z(:)-min(z(:)))));% normalizacia
            if useVGG
                z=imresize(z,[224 224]);
                bunka = cat(3, z, z, z);
                featureVector = activations(net, bunka, 'pool5', ...
                'MiniBatchSize', 1, 'OutputAs', 'columns'); %vytahnuti priznaku z dataNegativne
                featureVector = transpose(featureVector); %ulozenie do riadku
      %EXTRAKCIA PRIZNAKOV - HOG     
            else
                [featureVector,hogVisualization] = extractHOGFeatures(z,'CellSize',[cSize cSize]);
            end
            [label,score] = predict(classifier,featureVector); %predikcia klasifikačnej triedy
            if label == "pozitivne"
                predictions(n)=1;
            else
                predictions(n)=0;
            end 
        end

        for n=1:length(testovacie_pozitivne)
            bunka=testovacie_pozitivne{n};
            z=bunka; 
            z = uint8(255 .* ((double(z)-min(z(:)))) ./ (max(z(:)-min(z(:)))));% normalizacia
            if useVGG
                z=imresize(z,[224 224]);
                bunka = cat(3, z, z, z);
                featureVector = activations(net, bunka, 'pool5', ...
                'MiniBatchSize', 1, 'OutputAs', 'columns'); %extrakcia priznakov - pooling 5 vrstva VGG
                featureVector = transpose(featureVector);
            
            else
                [featureVector,hogVisualization] = extractHOGFeatures(z,'CellSize',[cSize cSize]);
            end
            [label,score] = predict(classifier,featureVector);

            if label == "pozitivne"
                predictions(n+length(testovacie_negativne))=1;
            else
                predictions(n+length(testovacie_negativne))=0;
            end
        end

        groundThruthNegativne = zeros(1,length(testovacie_negativne)); %vytvorenie popisov k označeným datam
        groundThruthPozitivne = ones(1,length(testovacie_pozitivne));
        groundThruthTitles=[groundThruthNegativne groundThruthPozitivne];
        %confusionchart(groundThruthTitles,predictions) %vypísanie matice
        %zamen
        %confusionmat(groundThruthTitles,predictions) %zobrazenie matice
        %zamen

        vysledky = {};
        pocetRezov = size(pacient,3);
        vsetkyH = [];
        maxH = 0;
        maxAR = 0;

        jeden_rez=pacient(:,:,pocetRezov); 
        bunka = uint8(255 .* ((double(jeden_rez)-min(jeden_rez(:)))) ./ (max(jeden_rez(:)-min(jeden_rez(:)))));% normalizacia
        blackMax=length(bunka(bunka<30))/(512*512);

        jeden_rez=pacient(:,:,1); 
        bunka = uint8(255 .* ((double(jeden_rez)-min(jeden_rez(:)))) ./ (max(jeden_rez(:)-min(jeden_rez(:)))));% normalizacia
        blackMin=length(bunka(bunka<30))/(512*512);

        treshold = blackMax-((blackMax-blackMin)*0.9);


        maxH=0    
        rez=1;
        tic;
        for AR=bod(3):1:bod(4)
            tic
            jeden_rez=pacient(:,:,AR); 
            bunka = uint8(255 .* ((double(jeden_rez)-min(jeden_rez(:)))) ./ (max(jeden_rez(:)-min(jeden_rez(:)))));% normalizacia
            black=length(bunka(bunka<30))/(512*512);

                [r,c]=size(bunka); %velkost rezu
                Hf=zeros(r,c);
                r=floor((r-h)/s)+1; %kolko krokov sa zmestí na výšku
                c=floor((c-w)/s)+1; %kolko krokov sa zmestí na šírku
                r=r*s;
                c=c*s;
 
                r1=1;  %pociatocná inicializácia súradnic
                c1=1;
                for n=1:s:c
                    for m=1:s:r
                        img=bunka(n:n+(w-1),m:m+(h-1)); %výrez okna        
               %EXTRAKCIA PRIZNAKOV VGG     
                        if useVGG
                            z=imresize(img,[224 224]);
                            z = cat(3, z, z, z);
                            featureVector = activations(net, z, 'pool5', ...
                            'MiniBatchSize', 1, 'OutputAs', 'columns'); %vytahnuti priznaku z dataNegativne
                            featureVector = transpose(featureVector);
                            
               %EXTRAKCIA PRIZNAKOV - HOG             
                        else
                            [featureVector,hogVisualization] = extractHOGFeatures(img,'CellSize',[cSize cSize]);
                        end
                        [pred,scores]=predict(classifier,featureVector);       
                        Hf(n,m)= -scores(1);        
                    end    
                end  
                toc
                [suradnicaRow,suradnicaCol]=find(max(Hf(:))==Hf);
                detectedBBox{rez} = [suradnicaCol suradnicaRow d1 d2];
                rez=rez+1;
                if maxH < max(Hf(:))
                        %[suradnicaRow,suradnicaCol]=find(max(Hf(:))==Hf);
                        maxAR = AR;
                        maxH = max(Hf(:))
                        vysledok = [suradnicaRow suradnicaCol maxAR];
                end
                max(Hf(:))
                [rowShow,co1Show]=find(max(Hf(:))==Hf);
                jeden_rez=pacient(:,:,AR); 
                bunka = uint8(255 .* ((double(jeden_rez)-min(jeden_rez(:)))) ./ (max(jeden_rez(:)-min(jeden_rez(:)))));% normalizacia

                bunka = insertShape(bunka,'Rectangle',[co1Show rowShow (h-1) (w-1)],'LineWidth',3);
                imshow(bunka)
        end

        jeden_rez=pacient(:,:,vysledok(3)); 
        bunka = uint8(255 .* ((double(jeden_rez)-min(jeden_rez(:)))) ./ (max(jeden_rez(:)-min(jeden_rez(:)))));% normalizacia

        bunka = insertShape(bunka,'Rectangle',[vysledok(2) vysledok(1) (h-1) (w-1)],'LineWidth',3);
        
        %pridanie popisov do obrazov obsahujucich vysledne detekcie
        if useVGG
            bunka = insertText(bunka, [0 0], string(nazovPacienta) + ' s=' + string(s)+' rez='+string(vysledok(3)));
        else
            bunka = insertText(bunka, [0 0], string(nazovPacienta) + ' s=' + string(s)+' cellSize='+string(cSize)+' rez='+string(vysledok(3)));
        end
        
        if useVGG
            imwrite(bunka,string(folder)+string(nazovPacienta)+'detektor_MAE_HOG'+'s'+string(s)+'rez'+string(vysledok(3))+'.png','png')
        else
            imwrite(bunka,string(folder)+string(nazovPacienta)+'detektor_MAE_HOG'+'s'+string(s)+'cellSize'+string(cSize)+'rez'+string(vysledok(3))+'.png','png')
        end

        groundTruthBBox = [bod(1) bod(2) d1 d2]; %nacitanie z oznacenych dat pre pacienta 47
        mIOU = 0;
        mPrecision = 0;
        mRecall = 0;
        for n=1:length(detectedBBox)
            mIOU = mIOU + bboxOverlapRatio(detectedBBox{n},groundTruthBBox); %vypocet IOU (Intersection over union)
            [precision,recall] = bboxPrecisionRecall(detectedBBox{n},groundTruthBBox);
            mPrecision = mPrecision + precision;  %vypocet precision (presnosti)
            mRecall = mRecall + recall; % vypocet recall (uplnosti)
        end

        mIOU = mIOU / length(detectedBBox) %priemerná hodnota
        mPrecision = mPrecision / length(detectedBBox)
        mRecall = mRecall / length(detectedBBox)    
        
        if useVGG
            fid = fopen(string(folder)+string(nazovPacienta)+'detektor_MAE_HOG'+'s'+string(s)+'cellSize'+string(cSize)+'rez'+string(vysledok(3))+'.txt','wt');
        else
            fid = fopen(string(folder)+string(nazovPacienta)+'detektor_MAE_HOG'+'s'+string(s)+'cellSize'+string(cSize)+'rez'+string(vysledok(3))+'.txt','wt');
        end
        
        fprintf(fid, 'mIOU:'+string(mIOU)+'\nmPrecision:'+string(mPrecision)+'\nmRecall:'+string(mRecall));
        fclose(fid);
    end
    
    %vymazanie pouzitych premennych
    clearvars Priznakovy_vektor_neg Priznakovy_vektor_poz neg poz negativne_titles pozitivne_titles priznaky_titles priznaky classifier vysledky vsetkyH Hf vysledok groundTruthBBox
    confusionMatrix = confusionmat(groundThruthTitles,predictions)
    dlmwrite(string(folder)+string(nazovPacienta)+'cellSize'+string(cSize)+'confusionMatrix.txt',confusionMatrix)
    if useVGG
        break
    end
    
end
confusionchart(groundThruthTitles,predictions) %vypisanie matice zámen 
title('SVM+HOG MAE detection')

clear all
