function [EllipseData] = EllipseDetect(Canny,Distortion,Bigmin,Bigmax,Small,Convar,Tol,CutOff);

%Ucel funkce je v obraze, ktery byl upraven Cannyho hranovym operatorem,
%najit elipticke oblasti. Vstupem do algoritmu je obraz upraveny Canyho
%algoritmem a parametry pro vytrideni eliptickych objektu (potencialnich
%kalibr. znacek), vystupem jsou data tykajici se vytridenych eliptickych
%oblasti (parametry elipsy, jeji stred, delka hlavni a vedlejsi poloosy,
%uhel orientace)

stats = regionprops(bwconncomp(Canny),'MajorAxisLength','MinorAxisLength','FilledArea','ConvexArea', 'PixelList','Centroid', 'Orientation');
                                                                            %vypsani dulezitych vlastnosti regionu (spojitych oblasti) v obraze = potencialnich elips                                                                          

%TRIDENI REGIONU DLE KRITERII

EllipseIndex = [];                                                          %pripraveni matice      
for i = 1:length(stats)                                                     %pro vsechny regiony
    
    a = stats(i).MajorAxisLength;                                           %hlavni poloosa regionu
    b = stats(i).MinorAxisLength;                                           %vedlejsi poloosa regionu
    Sconv = stats(i).ConvexArea;                                            %obsah konvexni obalky regionu
    Sfill = stats(i) .FilledArea;                                           %obsah vyplneneho regionu
    
    if (a / b < Distortion &&  a > Bigmin && b > Small && a < Bigmax && Sconv / Sfill < Convar);
                                                                            %aplikace kriterii
                                                                            
        EllipseIndex = horzcat(EllipseIndex, i);                            %ulozeni indexu regionu, ktere vyhovovaly
        
    end
end

%TRIDENI DLE ZBYTKU PO FITTINGU ELIPS - VYBERE POUZE ELIPTICKE OBJEKTY

%Rovnice elipsy: Ax2 + Bxy + Cy2 - (2Ah + kB)x - (2Ck + Bh)y + Ah2 + Bhk + Ck2 - 1 = 0.

EllipseData=[];                                                             %matice vysledku

for i=EllipseIndex                                                          %pres vsechny elipsy co prosly predchozim kriteriem
                                                                            %pozn. - x a y jsou prohozeny kvuli ruznym souradnym systemum snimku a matice obrazu (jsou vuci sobe pootoceny o 90 stupnu), 
                                                                            %kvuli stejnemu duvodu jsou prohozeny cleny A a C v parametrech rovnice elipsy. dale je delka hlavni a vedlejsi poloosy podelena konstantou,
                                                                            %kvuli algoritmu funkce "regionprops", ktery neni uzpusoben k praci s pouhou hranici objektu, viz help
                                                                            
    Fi = stats(i) .Orientation;                                             %orientace elipsy - uhel mezi jeji hlavni poloosou a kladnou poloosou x                                           
    a = stats(i) .MajorAxisLength/2/sqrt(2);                                %hlavni poloosa elipsy
    b = stats(i) .MinorAxisLength/2/sqrt(2);                                %vedlejsi poloosa elipsy                                           
    x = stats(i) .PixelList (:,2);                                          %souradnice bodu hranice elipsy
    y = stats(i) .PixelList (:,1);
    x0 = stats(i) .Centroid(2);                                             %souradnice teziste
    y0 = stats(i) .Centroid(1);
    
    A = (sind(Fi)/(a))^2+(cosd(Fi)/(b))^2;                                  %parametry rovnice elipsy (v budoucnu lze goniometricke funkce nahradit algebraickymi kvuli uspore vypocetniho casu)
    B = -2*cosd(Fi)*sind(Fi)*(1/(a^2)-1/((b)^2));
    C = (cosd(Fi)/(a))^2+(sind(Fi)/(a))^2;
                                                                 
    a0 = [A B C x0 y0];                                                     %prichystani startovnich hodnot pro metodu nelinearnich nejmensich ctvercu
                                                                                                                                                  
    f = @(a) (a(1).*((x).^2))+(a(2).*(x).*(y))+(a(3).*((y).^2))-((2.*a(1).*a(4)+a(2).*a(5)).*(x))-((2.*a(3).*a(5)+a(2).*a(4)).*y)+(a(1).*(a(4).^2))+(a(2).*a(4).*a(5))+(a(3).*(a(5).^2))-1;
                                                                            %zavedeni rovnice elipsy
    options = optimset('Display','off');                                    %nastaveni metody nelinearnich nejmensich ctvercu - default, pouze vypnuto zobrazeni vysledku ve workspace
                                                                     
    [af,r] = lsqnonlin(f, a0, [], [],options);                              %fittnig pomoci nejmensich ctvercu - vypsani vyslednych parametru a zbytku                                                                                                                                                %stats(idx2(i)) .PixelList (:,1)-a(1)).^2)/a(2).^2 + ((stats(idx2(i)) .PixelList (:,2)-a(3)).^2)/a(4).^2 -1
    if r < Tol;                                                             %vybrani elips podle zbytku - nastavitelny parametr
        
        if af(5)>CutOff && af(5)<(size(Canny,2)-CutOff) && af(4)>CutOff && af(4)<(size(Canny,1)-CutOff)
                                                                            %podminka - elipsy na okrajich snimku nejsou uvazovany - kvuli skenovani kodu, kdy by skenovaci paprsky mohly zasahnout mimo matici obrazu 
            EllipseData(size(EllipseData,1)+1,:)=horzcat(af,a*sqrt(2),b*sqrt(2),Fi); 
                                                                            %vypsani vysledku - parametry elips co prosly kriterii + dalsi dulezite informace z regionprops - parametry elipsy tyto informace sice obsahuji, 
                                                                            %nicmene jejich ziskani ze zminenych parametru je znacne vypocetne narocne
        end
    end
end
end

