function [output_name, statistiky, kvalita,elapset_time] = Genetic(filename,pocetjedincu,pocetreplikaci,pstmutace,procento_obrazu,uhel_rotace,maxit,maxmutaci,kriterium_kvality)
% Stabilizace videa pomocí genetického algoritmu 
%
%%
% pocetjedincu = 100;
% pocetreplikaci = 75;
% pstmutace = 0.7;
% procento_obrazu = 0.025;
% uhel_rotace = 4; % [°]
% maxit = 15;
% maxpok = 15;
% kriterium_kvality = 99.75;
%% PŘÍPRAVA VSTUPNÍHO SOUBORU
tic;
videoreader = VideoReader(filename); %kvuli parametrum snimky,vidH a vidW
snimky = ceil(videoreader.Duration * videoreader.FrameRate); % celkový počet snímků
progress_bar = waitbar(0,'Prosím čekejte');
%urceni rozmeru vystupniho obrazu
v_height_out = videoreader.Height;
v_width_out = videoreader.Width;
% vhodna prealokace proměnné movie pro spravne spusteni prikazem implay
movie(1:snimky) = struct('cdata', zeros(v_height_out, v_width_out),'colormap', []);
%%
hVideoSrc = vision.VideoFileReader(filename, 'ImageColorSpace', 'Intensity','VideoOutputDataType','double'); % Načtení vstupního souboru do visio kontejneru
hVPlayer = vision.VideoPlayer; % Vytvření video přehrávače
hVPlayer2 = vision.VideoPlayer; % Vytvření video přehrávače

imgAd = step(hVideoSrc); % načtení prvního snímku

k = 2;                          % alokace paměti
vektor_posunu_x = zeros(1,snimky);  % alokace paměti pro všechny snímky, nutné pro ořez
vektor_posunu_y = zeros(1,snimky);  % alokace paměti pro všechny snímky, nutné pro ořez
statistiky = zeros(3,snimky);       % alokace paměti
kvalita = zeros(2,snimky);
imgAi = readFrame(videoreader);         % načtení prvního snímku
while ~isDone(hVideoSrc)
    
    imgBd = step(hVideoSrc);            % načtení nového snímku v double podobě
    imgBi = readFrame(videoreader);     % načtení nového snímku v int podobě
    B = imgBi;
    kvalita(1,k) = ( (sum(sum(imgAd.*imgBd)))/(sqrt(sum(sum(imgAd.^2)))*sqrt(sum(sum(imgBd.^2)))) );
    if(kvalita(1,k) < kriterium_kvality)
        kvalita(2,k) = -1;
        j = 1;
        while(kvalita(2,k) < kriterium_kvality && j < maxit)
            [jedinec_temp,kvalita_temp,iterace] = evoluce(imgAd,imgBd,pocetjedincu,pocetreplikaci,pstmutace,procento_obrazu,uhel_rotace,maxmutaci,kriterium_kvality);%volání funkce genetická optimalizace
            statistiky(1,k) = statistiky(1,k) + iterace;
            if(kvalita_temp > kvalita(2,k))
                kvalita(2,k) = kvalita_temp;
                jedinec = jedinec_temp;
                fprintf('Update Image %d transformation\n',k);
            end
            fprintf('Restart No. %d of Image %d\n',j,k);
            j = j+1;
        end
    else
        jedinec = [0,0,0];
        kvalita(2,k) = NaN;
        statistiky(1,k) = 0;
    end
    tform = maketform('affine',[0+cos(jedinec(1,3)) 0+sin(jedinec(1,3)) 0;...
            0-sin(jedinec(1,3)) 0+cos(jedinec(1,3)) 0; jedinec(1,1) jedinec(1,2) 1]);
    vektor_posunu_x(k) = jedinec(1,1);    % uložení posunu pixelů v ose X
    vektor_posunu_y(k) = jedinec(1,2);    % uložení posunu pixelů v ose Y
    imgBd = imtransform(imgBd,tform,'XData',[1, v_width_out],'YData',[1, v_height_out]);
    imgBi = imtransform(imgBi,tform,'XData',[1, v_width_out],'YData',[1, v_height_out]);
    movie(k).cdata = imgBd;         % zápis výstupních dat
    
    [statistiky(2,k), statistiky(3,k)] =...
            mutualInfo(imgAi,imgBi);  % výpočet statistik
    fprintf('Image %d finished! Transform: %d %d %f\n',k,jedinec(1), jedinec(2), jedinec(3));
    % Průběžné zobrazení transformace proložením původního a nového obrázku
%     step(hVPlayer, imfuse(B,imgBi,'ColorChannels','red-cyan'));
%     step(hVPlayer2, imfuse(imgAi,imgBi,'ColorChannels','green-magenta'));
    waitbar(k/ snimky);
    k = k+1;
end
%% orez cernych pruhu
for l = 1:snimky
    orez_x = max(ceil(abs(vektor_posunu_x)));
    orez_y = max(ceil(abs(vektor_posunu_y)));
    if(orez_x == 0 && orez_y == 0)
        break;
    end
    if(orez_x == 0 )
        orez_x = 1;
    end
    if(orez_y == 0 )
        orez_y = 1;
    end
    movie(l).cdata = movie(l).cdata(orez_y:end-orez_y,orez_x:end-orez_x);
end
%% ZÁPIS DO AVI SOUBORU
filename = strsplit(filename,'\');
output_name = [...
    'Gen_', 'So_',num2str(procento_obrazu),...
    '_UhO',num2str(uhel_rotace),...
    '_PctJed',num2str(pocetjedincu),...
    '_Repl',num2str(pocetreplikaci),...
    '_KvKr',num2str(kriterium_kvality),...
    '_Pmut',num2str(pstmutace),...
    '_MaxIt',num2str(maxit),...
    '_MaxMu',num2str(maxmutaci),...
    '_', filename{end}];
output = VideoWriter(output_name,'Uncompressed AVI');
open(output);
for m = 1:snimky
    writeVideo(output,movie(m).cdata);
end
try
    close(output_name);
catch
end
% Uvolnění objektů a paměti
release(hVideoSrc);
release(hVPlayer);
elapset_time = toc;
close(progress_bar);
fprintf('Stabilizace hotova za: %d\n',elapset_time);
end