% ============================================================================ %
% Encoding: UTF-8 (žluťoučký kůň úpěl ďábelšké ódy)
% ============================================================================ %

% ============================================================================ %
\nn{Úvod}
V celém světě je snaha o vývoj chytrých dopravních systémů. Cílem je poskytnout vyšší míru bezpečnosti, zvýšit pohodlí cestování a naopak snížit cenu a čas dopravy. Důležitou roli v těchto systémech hraje zpracování obrazu. Díky zpracování obrazu je možné sledovat a vyhodnocovat dopravní situaci v reálném čase a zajistit tak vyšší plynulost dopravy.  V souvislosti se zvyšováním výpočetního výkonu, zvyšováním datové propustnosti a snižováním ceny těchto řešení lze předpokládat, že tento rozvoj bude pokračovat i nadále.

Důležitou roli hrají také kamery umístněné v automobilu. Specializované zařízení umístněné v policejních automobilech umožňují snímání dopravní situace za jízdy, vyhodnocování nebezpečných situací nebo odhalení dopravních přestupků. Zpracování obrazu v této oblasti výrazně zvyšuje efektivitu práce policejních složek.
Kamery umístněné v soukromých automobilech slouží jako důkazní materiál v případě dopravní nehody.

Z pohledu automomního řízení automobilu existuje pět katerogií \cite{autonomniVozidla}. Do první kategorie patří automobily bez jakékoliv automatizace. Páta kategorie reprezentuje zcela autonomní automobily, který nepotřebují řidiče.  Ačkoli jsou autonomní automobily hodně diskutovaným tématem, stále platí, že většina automobilů spadá pouze do druhé kategorie. Tato katogeorie obsahuje systémy pro podporu řízení, např. detekci překážek, systém pro automatické parkování a další. Je nutné, aby automobil v této kategorii řídil člověk, který je odpovědný za řízení. Systémy nejsou způsobilé pro samostatnou jízdu. Je tedy zřejmé, že se jedná o oblast, ve které se nachází velký potenciál pro inovace a  vylepšení. Výraznou roli zde bude hrát zpracovní obrazu, které musí probíhat ve vysokém rozlišení, v reálném čase a hlavně bez jakýchkoliv chyb.

Cílem této práce je čtenáře seznámit s možnostmi zpracování obrazu, který obsahuje záznam z dopravní stiuace.

\section*{Obsah práce}
První kapitola této práce se zabývá teorií o reprezentaci obrazu v digitální podobě. Seznámíme se s reprezentací obrazu, barevnými modely a histogramy.
V druhé kapitole jsou probrány možnosti předzpracování obrazu pomocí lineární filtrace. Jsou zde popsány základní operace předzpracování jako podvzorokování, rozmazání, mediánová filtrace a morfologické operace.
Třetí kapitola se zabývá metodami pro detekci objektů v obraze. Čtenář je seznámen s metodami prahování a detektory hran.
Poslední teoretická kapitola se zabývá metodami pro popis tvaru objektu. Je zde také vysvětlen princi Houghovy transformace.

Na úvod praktické části jsou uvedeny a popsány poždavky na výsledné algoritmy. Na základě teoretických poznatků z předcházejících kapitol je zde navržen a implementován algoritmus pro detekci a sledování automobilu v obraze. Nedílnou součástí této práce je také algoritmus pro detekci jízdních pruhů. Následuje popis výsledné aplikace, vyhodnocení úspěšnosti a výpočetní náročnosti implementovaných algoritmů.
V závěru jsou shrnuty veškeré poznatky z této práce a je zde nastíněno možné rozšíření, tak aby algoritmy pracovaly efektivněji.

% ============================================================================ %
\cast{Teoretická část}

\n{1}{Obraz a jeho reprezentacce}
Existují dva základní způsoby reprezentace obrazu a sice rastrový a vektorový. Tato práce se zabývá výhradně zpracováním rastrového obrazu. Rastrový obraz je definová pomocí funkce $f(x,y)$, kde $x$ a $y$ určují pozici v obraze, funkční hodnota funkce určuje hodnotu jasu v daném bodě. Podle použitého barevného modelu, je tato hodnota definována jedním číslem pro šedotonový obraz, nebo třemi čísly pro barevný obraz. Maximální hodnoty kterých může nabývat $x$ a $y$ určují rozlišení  obrazu. \cite{obraz}
\n{2}{Barevné modely}
Barevné modely slouží pro matematickou reprezentaci barvy. Barva je  definována jako bod v trojrozměrném prostoru. Každá osa daného prostoru reprezentuje jeden barevný kanál.
Existují dva způsoby, kterými lze získat výslednou barvu \cite{barvy}. Prvním způsobem je aditivní míchání barev, kdy se jednotlivé barevné kanály sčítají. Druhým způsobem je substraktivní míchání barev, kdy se jednotlivé barevné kanály odečítají. 
Rozsah hodnot, které můžou jednotlivé barevné kanály nabývat, určuje bitovou hloubkou daného obrazu. Bitová hloubka udává kolik bitů je použito k reprezentaci jednoho barevného kanálu. Typicky se používá 8-bitová hlubka, tedy každý kanál může nabývat hodnoty z rozsahu $<0,255>$.
\n{3}{Barevný model RGB}
Jedná se o nejčastěji používaný barevný model. Princip tohoto modelu je založný na faktu, že lidské oko je citlivé na tří základní barvy - červenou, zelenou a modrou. Ostatní barvy jsou definovány pomocí sytosti těcho barev. Každý pixel je reprezentován třemi hodnotami, které odpovídají jasu červené (R), zelené (G) a modré (B) barvy. Výsledná barva je dána smícháním všech tří kanálů, jedná se tedy o aditivní model. V některých případech se používá také model RGBA, kde A značí tzv. alfa kanál udávající průhlednost. Černá barva je reprezentována číslem 0, bílou barvu naopak reprezentuje hodnota 255. Typickým příkladem aplikace tohoto modelu je ukládání obrázků v digitální podobě. Reprezentace RBG modelu pomocí krychle je zobrazena na obrázku \ref{fig:RGB_model}.
\obr{RGB krychle \cite{RGB}}{fig:RGB_model}{0.4}{graphics/img/rgb.png}

\n{3}{Barevný model HSV}
Barevný model HSV definuje barvu pomocí tří složek a sice odstínu (hue), sytosti (saturation) a hodnoty jasu (value).
Hlavní výhodou tohoto barevného modelu je intuitivní definice barvy. HSV model zachovává sousednost barev, to znamená, že podobné barvy jsou reprezentovány pomocí blízkých hodnot. Této vlastnosti se využívá při detekci barev v obraze. Typickým příkladem, kde tento model nachází uplatnění jsou grafické editory. Grafické znázornění HSV modelu je znázorněno na obrázku \ref{fig:HSV_model}.
\obr{Barevný model HSV \cite{HSV}}{fig:HSV_model}{0.4}{graphics/img/hsv.png}

\n{3}{Stupně šedi}
Jedná se o model, ve kterém je barva každého pixelu reprezentována jako hodnota jasu. Lidské oko má různou citilivost na jednotlivé barvy, nejvíce citlivé je na zelenou barvu, nejméně na modrou. Proto se pro převod barevného obrázku do stupňů šedi využívá rovnice
\begin{equation}
Y = 0, 299R + 0, 587G + 0, 114B,
\end{equation} 
kde Y je výsledná hodnota jasu, R,G,B jsou hodnoty jednolivých barevných kanálů původního barevného obrázku \cite{MITTNER}.
Pro zpracování obrazu je výhodné převést obrázek do stupňů šedi z důvodu zjednodušení a zrychlení výpočtu. Na obrázku \ref{fig:Stupne_sedi} je ukázka převodu do stupňů šedi.
\obr{Ukázka snímku převedeného do stupňů šedi}{fig:Stupne_sedi}{0.7}{graphics/img/stupne_sedi.png}

\n{2}{Histogram}
Histogram digitálního obrazu je diskrétní funkce, která pro jednotlivé hodnoty jasu, určuje jejich počet v daném obraze. Z histogramu tedy lze vyčíst rozložení jasu v obraze. Znázornění histogramu se provádí pomocí sloupcového grafu. Osa $x$ je pomocí intervalů rozdělena na jednotlivé třídy, na ose $y$ jsou znázorněny četnosti výskytu dané třídy. Vlevo se znázorňují hodnoty s nulovou úrovní jasu - černé pixely. Naopak vpravo jsou znázorněny pixely s vysokou úrovní jasu - bílé pixely. Součet všech hodnot histogramu, by měl odpovídat součtu všech pixelů v daném obraze. V praxi se hodnoty normalizují, tedy na ose $y$ lze vidět procentuální zastoupení daného intervalu. Pomocí histogramu lze určit, jestli daný obrázek netrpí defekty jako přeexponování nebo podexponování obrazu. Ukázka histogramu je znázorněna na \ref{fig:Histogram}.
\obr{Ukázka histogramu}{fig:Histogram}{0.7}{graphics/img/histogram.png}

\n{3}{Ekvalizace historgramu}
Ekvalizace histogramu je mapování distribuční funkce histogramu zpracovávaného obrazu $H(i)$ na novou distribuční funkci $H'(i)$.
\begin{equation}
H'(i) = \sum_{0\leq j<i} H(j)
\end{equation} 
Nová distribuční funkce by měla být šírší a mít rovnoměrnější rozložení hodnot jasu. Přepočtené hodnoty jednotlivých pixelů získáme pomocí vzorce
\begin{equation}
vysledek(x,y) = H'(puvodni(x,y)).
\end{equation}
Cílem ekvalizace histogramu je upravit obraz tak, aby se zvýšil lokální kontrast obrazu.
Výhodou je jednoduchost výpočtu a s tím související nízká časová náročnost.
Obecnou nevýhodou ekvalizace histogramu je fakt, že nerozlišuje užitečná data od těch neužitečných. Může se tedy stát, že po aplikaci dojde ke zvýraznění šumu.
Typickým příkladem, kdy využijeme ekvalizaci histogramu je zesvětlení nebo ztmavení obrazu.
Existují také adaptivní metody ekvalizace histogramu, které původní obraz rozdělí na menší části a na každou část aplikují ekvalizaci histogramu. Tyto metody dosahují lepších výsledků při aplikaci na nerovnoměrně osvětlený obraz \cite{OpenCV}. Na obrázku \ref{fig:Vyrovnani_histogramu} je znázorněna ukázka ekvalizace histogramu.  Obrázek \ref{fig:hist} zobrazuje histogram před a po ekvalizaci.

\obr{Výsledný obraz po ekvalizaci histogramu}{fig:Vyrovnani_histogramu}{0.7}{graphics/img/equalize_histogram.png}
\obr{Srovnání histogramu před a po ekvalizaci}{fig:hist}{1}{graphics/img/histo.eps}

\n{1}{Předzpracování obrazu}
Obraz určený ke zpracování může být ovlivněn různými faktory. Podle typu a kvality snímacího zařízení obsahuje obraz různé hodnoty a druhy šumu. Obraz je také výrazně ovlivněn světelnými podmínkami za kterých byl pořízen. Cílem předzpracování je odstranit tyto defekty a upravit obraz do takové podoby, aby co nejlépe vyhovoval dalším metodám zpracování. Metody pro předzpracování obrazu je nutné volit s ohledem na další zpracování. Předzpracování se provádí pomocí filtrace. Existují dva druhy filtrů - lineární a nelineární.

\n{2}{Lineární filtrace}
Linearní filtry jsou takové filtry, pro které platí princip superpozice
\begin{equation}
f(x1 + x2) = f(x1) + f(x2).
\end{equation} 
Výstupní hodnota musí být dána pomocí lineární kombinace vstupní hodnoty. Jednodušší lineární filtry jsou implementovány pomocí konvoluce, složitější využívají FFT. Typickým příkladem lineární filtrace je rozmazání obrazu nebo detekce hran \cite{OpenCV}.

\n{2}{Nelineární filtrace}
Nelinéární filtry, jsou takové filtry, pro které neplatí princip superpozice. Tedy výstupní hodnota není stanovena jako lineární kombinace vstupní hodnoty, ale je vypočtena na základně hodnot v okolí. Typickým příkladem nelineárního filtrů pro zpracování obrazu je mediánový filtr \cite{OpenCV}.
Některé nelineární filtry (např. Sobelův detektor hran) jsou složeny z více lineárních filtrů. 

\n{2}{Diskrétní konvoluce}
Diskrétní konvoluce je matematický operátor definovaný jako
\begin{equation}
f(x,y) * h(x,y)= \sum_{i=-k}^k \sum_{j=-k}^k f(x -i, y-j)*h(i,j),
\end{equation}
kde $f(x,y)$ je funkce definující obraz a $h(x,y)$ je tzv. konvoluční jádro \cite{Konvoluce}.
Z výše uvedené rovnice vyplývá postup výpočtu konvoluce, kdy pro každý pixel v obraze provedeme následující kroky:
\begin{enumerate}
\item Střed konvolučního jádra umístníme nad zpracovávaný pixel
\item Vynásobíme hodnoty konvolučního jádra s hodnotami zpracovávaného obrazu, které leží pod konvolučním jádrem.
\item Součet těchto násobků uložíme do právě zpracovávané buňky
\item Posuneme se na další pixel
\end{enumerate}
Konvoluční jádro je matice o malých rozměrech, typicky se používá  rozměr $3\times3$, $5\times5$ nebo $7\times7$. Součet všech hodnot v kovolučním jádru musí být roven číslu 1. Z toho důvodu definujeme tzv. měřítko pomocí kterého hodnoty upravíme tak, aby součet odpovídal jedné. Měřítko se definuje jako součet hodnot konvolučního jádra \cite{Konvoluce}.

\n{2}{Podvzorkování}
Cílem podvzorkování obrazu je snížit počet jeho pixelů. Podvzorkování se provádí tak, že vytvoříme novou matici, která nebude obsahovat některé řádky a sloupce z původního obrazu. Výběr řádků a sloupců, které nebudou zařazeny do nové matice se provádí rovnoměrně napříč obrazem. Tedy při podvzorkování na poloviční rozlišení bude nová matice obsahovat každý druhý řádek a sloupec. Díky snížení počtu zpracovávaných bodů bude výpočetní čas dalšího zpracování obrazu kratší. Při podvzorkování dochází ke ztrátě informace. Poměr mezi velikostí původního a podvzorkovaného obrazu je proto nutné volit s ohledem na další zpracování, které se bude s obrazem provádět.

\n{2}{Rozmazání}
Rozmazání obrazu je filtr založený na konvoluci. Nový pixel je vypočítán jako vážený průměr z okolních hodnot. Nejjednodušší formou je lineární rozmazání, kde má každý okolní pixel stejnou váhu. Matice \ref{eq:rozmazani} zobrazuje konvoluční jádro pro jednoduché rozmazání. Dalším často používaným rozmazáním je tzv. Gaussovo rozmazání, které má váhy definované pomocí Gaussova rozložení. Matice \ref{eq:gauss} reprezentuje konvoluční jádro pro Gaussovo rozmazání. Při zpracování obrazu se rozmazání používá pro odstranění šumu z obrazu \cite{OpenCV}.

\begin{equation}\label{eq:rozmazani}
\begin{bmatrix}
  1 & 1 & 1 \\
  1 & 1 & 1 \\
  1 & 1 & 1 
\end{bmatrix}
\end{equation}

\begin{equation}\label{eq:gauss}
\begin{bmatrix}
  1 & 2 & 1 \\
  2 & 4 & 2 \\
  1 & 2 & 1 
\end{bmatrix}
\end{equation}


\n{2}{Mediánový filtr}
Mediánový filtr se řadí mezi nelineární filtry.  Při výpočtu je pro každý pixel v obraze spočítán medián okolních bodů a výsledek se použije hodnota daného pixelu v novém obraze. Velikost okolí pro výpočet mediánu je určeno pomocí velikosti jádra filtru, typicky se volí hodnoty $3\times3$, $5\times5$ nebo $7\times7$.
Mediánový filtr se využívá například pro odstranění šumu typu pepř a sůl. Na obrázku \ref{fig:Median} je vidět výsledek po provedení mediánové filtrace. 
\obr{Ukázka zpracování mediánovým filtrem}{fig:Median}{0.8}{graphics/img/median.png}

\n{2}{Morfologické operace}
Základním principem morfologickcých operací je prozkoumání obrazu pomocí jednoduchého objektu, který má předdefinovaný tvar. Tento objekt se nazývá strukturní prvek. Výsledkem je informace jak tento prvek zapadá do tvarů v obraze. Vstupem pro morfologické operace je binární obraz a strukturní prvek. Strukturní prvek je dvourozměrná matice o rozměrech $m\times n$. Rozměry této matice ovlivňují maximální velikost děr, které je možno zaplnit a určují minimální, respektive maximální vzdálenost mezi objekty, které budou sloučeny, respektive rozděleny. Podle hodnot strukturního prvku určujeme jeho tvar. Standardně se používá čtvercový, kruhový nebo křížový tvar. Je potřeba si uvědomit, že u morfologických operací se zabýváme binárním obrazem, nikoliv šedotónovým. Pokud pixel nabývá nulové hodnoty, má bílou barvu. Hodnota jedna značí barvu černou. 

\begin{equation}\label{eq:obdelnik}
\begin{bmatrix}
      1 & 1 & 1 & 1 & 1 \\
      1 & 1 & 1 & 1 & 1 \\
      1 & 1 & 1 & 1 & 1 \\
      1 & 1 & 1 & 1 & 1 \\
      1 & 1 & 1 & 1 & 1
\end{bmatrix}
\end{equation}

Matice \ref{eq:obdelnik} popisuje obdelníkový strukturální prvek.

\begin{equation}\label{eq:kruh}
\begin{bmatrix}
      0 & 0 & 1 & 0 & 0 \\
      1 & 1 & 1 & 1 & 1 \\
      1 & 1 & 1 & 1 & 1 \\
      1 & 1 & 1 & 1 & 1 \\
      0 & 0 & 1 & 0 & 0
\end{bmatrix}
\end{equation}

Matice \ref{eq:kruh} popisuje kruhový strukturální prvek.

\begin{equation}\label{eq:cross}
\begin{bmatrix}
      0 & 0 & 1 & 0 & 0 \\
      0 & 0 & 1 & 0 & 0 \\
      1 & 1 & 1 & 1 & 1 \\
      0 & 0 & 1 & 0 & 0 \\
      0 & 0 & 1 & 0 & 0
\end{bmatrix}
\end{equation}

Matice \ref{eq:cross} popisuje křížový strukturální prvek.

\n{3}{Eroze}
Strukturní element je posouván po obraze (stejně jako 2D konvoluce). Výsledný pixel nabývá hodnoty 1 pouze v případě kdy nabývají hodnoty 1 všechny pixely pod strukturním elementem. V opačném případě je výsledkem nulová hodnota. Prakticky to znamená, že všechny pixely v blízkosti hranice budou odstraněny. Blízkost hranice je definována pomocí rozměru strukturního prvku. Výsledný objekt pak bude o něco menší než v orginálním obraze. Pokud je v objektu úzká oblast, dojde k rozdělení objektu na dva nové objekty \cite{SEBELA}.
\n{3}{Diletace}
Jedná se o opak eroze. Výsledný pixel nabývá hodnoty 0 v případě, kdy alespoň jeden pixel pod strukturním elementem nabývá hodnoty 1. Hranice objektů ve výsledném obraze budou větší o velikost strukturního elementu.  Pokud jsou v obraze objekty, mezi kterými je úzká hranice, budou tyto objekty sloučeny do jednoho celku.
\n{3}{Otevření a uzavření}
Otevření je běžně používané jméno pro erozi následovanou diletací. Tato operace se používá pro odstranění šumu typu z obrazu, odstranění tenkých linek v obraze nebo vyhlazení kontur objektů.
Uzavření aplikuje otevření a uzavření v opačném pořadí než otevření, tedy nejprve je aplikována eroze a poté následuje diletace.  Tato operace se používá pro vyplnění drobných děr v obraze, vyhlazení kontur objektů nebo spojení blízkých objektů do jednoho celistvého objektu.
Výhodou těchto operací je zachování původní velikosti objektů v obraze \cite{SEBELA}. Tato vlastnost platí pouze při použití stejného strukturního prvku pro erozi i diletaci. Na obrázku \ref{fig:Otevreni} je znázorněna ukázka aplikace otevření.
\obr{Ukázka aplikace otevření}{fig:Otevreni}{0.8}{graphics/img/open.png}

\n{1}{Metody pro detekci objektů}
Pro získání objektů z obrazu je potřeba obraz upravit a získat tzv. kandidáty na 
objekty. U těchto kandidátů následně srovnáme jejich vlastnosti s vlastnostmi požadovaných objektů. Mezi způsoby detkce objektů patří zejména prahování a detekce hran. V závěru této kapitoly jsou popsány také předtrénované klasifikátory.
\n{2}{Prahování}
Prahování patří mezi základní metody pro segmentaci obrazu. Nastavíme hodnotu prahu, pokud daný pixel nabývá větší hodnoty než práh, nastavíme mu výstupní hodnotu 1. Naopak pokud je hodnota pixelu menší než práh nastavíme mu hodnotu 0. Výsledkem je binární obraz, který obsahuje dvě barvy - obvykle černou a bílou. Nastavení správné hodnoty prahu výrazným způsobem ovlivňuje výsledek. Práh lze nastavit jako konstantu, nebo vypočítat pro každý snímek. Konstantní nastavení prahu se využije v případech, kdy víme že rozložení jasu bude na všech snímcích velmi podobné. Na obrázku \ref{fig:Prahovani} je ukázka prahování s konstantním prahem. Automatické nastavení prahu naopak využijeme v případech, kdy lze předpokládat, že rozložení jasu mezi jednotlivými snímky se bude výrazně měnit, například z důvodu různých světelených podmínek při pořízení snímku. 
\obr{Ukázka prahování s konstantní hodnotou prahu}{fig:Prahovani}{0.8}{graphics/img/treshold.png}

\n{3}{Automatická hodnota prahu}
Výpočet automatické hodnoty prahu je založen na předpokladu, že obraz obsahuje dvě množiny pixelů a sice popředí a pozadí. Při výpočtu se využívá histogramu. Mezi nejznámější algoritmy patří tzv. Otsuova metoda. Změnou hodnoty prahu T se mění velikost popředí a pozadí. Cílem je nalézt takovou hodnotu prahu T, pro kterou se co nejméně překrývá hustota pravděpodobnosti popředí a pozadí. Teoretický základ, ze kterého tato metoda vychází je podroběji popsán v \cite{Otsu}. Algoritmus výpočtu je následující:
Pro každou hodnotu prahu T vypočteme:
\begin{enumerate}
\item Podle úrovně jasu vytvoříme množinu bodů patřící do popředí a množinu bodů patřící do pozadí.
\item Vypočítáme průměrnou hodnotu jasu pro obě množiny.
\item Vypočítáme druhou mocninu rozdílu průměrů těchto množin.
\item Vypočtenou hodnotu vynásobíme počet pixelů v jedné množině krát počet pixelů v druhé množině.
\end{enumerate}

Tedy výsledný vzorec je 
\begin{equation}
\sigma^2(T)=N_1(T)\times N_2(T)\times [\mu_1(T)-\mu_2(T)]^2.
\end{equation}
Jako výsledná hodnota prahu T je použita ta pro kterou platí, že $\sigma^2(T)$ je největší \cite{Otsu}.

\n{3}{Adaptivní hodnota prahu}
V předcházejících případech jsem uvažovali jednu hodnotu prahu pro celý obraz. Tento způsob je nevýhodný, pokud je rozložení jasu napříč obrazem nerovnoměrné. Z toho důvodu se používá adaptivní hodnota prahu. V této metodě je obraz rozdělen na malé oblasti a pro každou oblast je dynamicky vypočítána hodnota prahu. Pro výpočet prahu se používá metoda průměrování nebo Gaussova metoda. Ukázka prahování s prahem vypočteným pomocí Gaussovy metody je na obrázku \ref{fig:Gaus}. Při průměrování je nový práh každé oblasti je určen jako průměrná hodnota jasu v  dané oblasti. Gaussova metoda využívá stejného principu jako průměrování, ale každá hodnota v regionu má přiřazenou váhu na základě Gaussova rozdělení.
\obr{Aplikace Gaussova adaptivního prahování}{fig:Gaus}{0.8}{graphics/img/adaptive_gaus.png}

\n{2}{Detekce hran}
Za hranu je v obraze považováno místo, kde dochází k prudké změně jasu mezi sousedními pixely. Detekce hran tedy znamená nalezení těchto míst. V praxi se k tomuto výpočtu využívá první nebo druhá derivace intenzity jasu. Při využití první derivace získáme kromě pozice hrany také její směr a velikost.
\begin{itemize}
\item Metody založené na první derivaci \cite{OpenCV}
\begin{itemize}
\item Sobelův filter,
\item Cannyho hranový detektor,
\item Robertsův operátor,
\item operátor Prewittové.
\end{itemize}
\item Metody založené na druhé derivaci:
\begin{itemize}
\item Laplaceův operátor,
\item Laplaceův Gaussovský operátor.
\end{itemize}
\end{itemize}

Na detektory hran máme tyto požadavky:
\begin{itemize}
\item Přesnost - určená hrana musí co nejvíce odpovídat realitě,
\item Minimální chybovost - počet false pozitive musí být co nejmenší,
\item Jednoznačnost - každá hrana musí být označena právě jednou.
\end{itemize}

Postup při detekci je následující \cite{OpenCV}
\begin{enumerate}
\item Odstranění šumu, např. pomocí Gaussova filtru.
\item Určení gradientu, pomocí první nebo druhé derivace.
\item Nalezení lokálních extrémů.
\item Odstranění nevýznamných hran (prahování).
\end{enumerate}

\n{3}{Sobelův filtr}
Sobelův filter je založen na aproximaci gradientu intenzity jasu. Výhodou tohoto filtru je nízká míra ovlivnění pomocí šumu a možnost detekovat hrany pouze v určitém směru. Pomocí vzorců \ref{eq:gx} a \ref{eq:gy} vypočítáme gradient změny ve směru osy $x$ a ve směru osy $y$. $I$ reprezentuje námi zpracovávaný obraz.

\begin{equation}\label{eq:gx}
 G_x = 
\begin{bmatrix}
      -1 & 0 & 1  \\
      -2 & 0 & 2  \\
      -1 & 0 & 1  \\
\end{bmatrix}\times I
\end{equation}

\begin{equation}\label{eq:gy}
 G_y = 
\begin{bmatrix}
      -1 & -2 & -1 \\
      0 & 0 & 0 \\
      1 & 2 & 1 \\
\end{bmatrix}\times I
\end{equation}

Následně pro každý bod obrazu vypočítáme gradient v obou směrech pomocí vzorce
\begin{equation}
G = \sqrt{G_x^2 + G_Y^2}.
\end{equation}
V případě potřeby detekce hran pouze v jednom směru je nutné příslušné matice upravit. Pro detekci šimkých hran je potřeba matice rotovat. Obrázek \ref{fig:Sobel} ukazuje příklad použití Sobelova detektoru hran.
\obr{Ukázka aplikace sobelova filtru}{fig:Sobel}{0.8}{graphics/img/sobel.png}
\n{3}{Cannyho hranový detektor}
Cannyho hranový detektor je vylepšením Sobelova detektoru. Sobelův detektor produkuje tlusté hrany, které jsou rozmazané, což je nežádoucí jev, který cannyho detektor odstraňuje. Po aplikaci Sobelovat detektoru prochází jednotlivé  hrany po pixelech a porovnává aktuální pixel s pixely v pozitivním a negativním gradientu. Pokud je hodnota pixelu větší než ostatní pixely ve směru hrany, zůstává jeho hodnota zachována, v opačném případě je pixel z hrany odstraněn.

Po odstranění nežádoucích pixelů se provede dvojité prahování. Stanoví se horní a dolní prahovací mez, pokud je hodnota pixelu menší než dolní mez je odstraněn z výběru, pokud je hodnota pixelu větší než horní mez je zařazen mezi tzv. silné hrany. Pixel jehož hodnota náleží mezi dolní a horní mez je zařazen mezi tzv. slabé hrany. Na závěr jsou odstraněny všechny slabé hrany, které nejsou napojeny na silné hrany. \cite{OpenCV}
Výsledkem je binární obraz, ve kterém jsou všechny hrany reprezentovány stejnou hodnotou. Ukázka detekce hran pomocí Cannyho detektoru je znázorněna na obrázku \ref{fig:Canny}.
\obr{Ukázka aplikace Cannyho hranového detektoru}{fig:Canny}{0.8}{graphics/img/canny.png}

\n{2}{Detekce barvy}
Pro detekci barvy je vhodné využít barevného modelu HSV, protože v něm lze jednoduše a intuitivně definovat podobné barvy. Definujeme si hledanou barvu a maximální požadovanou odchylku, ta nám určuje které barvy jsou si ještě podobné. Platí, že čím větší odchylka, tím větší rozsah barev je označen jako podobný. U systosti a jasu vezmeme hodnotu hledáné barvy, odečtením odchylky vznikne spodní mez rozsahu $s$, naopak přičetním odchylky vznikne horní mez výsledného rozsahu, kterou označíme $h$. U odstínu je situace složitější.  Meze získáme stejným způsobem jako u jasu a sytosti. Při stanovení mezí u odstínu je potřeba využít modulo aritmetiku tak, aby bylo zaručeno že výsledné meze budou v rozsahu $(0, 359)$. Pokud vyjde $s >h$, stanoví se intervaly dva. První v rozsahu $(0, h)$, druhý v rozsahu $(s, 359)$. Na obrázku \ref{fig:color} je znázorněna detekce bílé barvy.
\obr{Ukázka detekce bílé barvy}{fig:color}{0.8}{graphics/img/color_treshold.png}

\n{2}{Hledání shluků}
Jedná se o metody, jejichž cílem je v obraze nalézt shluky bodů, které mají shodné určité vlastnosti. V našem případě předpokládáme použití na binární obraz a jako vlastnost uvažujeme příslušnost daného pixelu k černé nebo bílé barvě. Pro další popis je nutné definovat okolí bodu. Okolí bodu udává, které body jsou považovány za sousední. Existuje několik používaných typů okolí bodu. Mezi nejznámější a nejpoužívanější patří čtyřokolí a osmiokolí. Grafickou reprezentaci okolí bodu lze vidět na obrázku \ref{fig:okoli}.
\obr{Zleva - čtyřokolí, osmiokolí, křížové okolí}{fig:okoli}{0.6}{graphics/img/okoli.eps}

Při hledání shluků se postupně prochází celý obraz a pro každý bod se zkontroluje okolí bodu. Pokud má některý z okolních bodů shodnou vlastnost a je označen příslušným štítkem, nastavíme stejný štítek i na současný bod. Pokud některý ze sousedních bodů má stejnou vlastnost, ale není označen štítkem, vytvoříme nový štítek, kterým jej označíme. Pod pojmem štítek si můžeme představit např. barvu. Výsledkem této metody je rozdělení pixelů do skupin shluků podle určené vlastnosti. Ukázka použití tohoto algoritmu je znázorněna na obrázku \ref{fig:Blobs}. V některé literatuře lze tuto metodu naléz pod označením component labeling. \cite{MITTNER}

\obr{Ukázka hledání shluků}{fig:Blobs}{0.8}{graphics/img/blobs.png}

\n{2}{Předtrénované modely}\label{sec:haar}
Předtrénované modely patří do skupiny strojového účení s učitelem. Použití těchto modelů má dvě fáze:
\begin{enumerate}
\item Učení modelu
\item Klasifikace pomocí modelu
\end{enumerate}
Pro natrénování modelu potřebujeme dostatečné množství trénovacích dat. Pro kvalitní model jsou to řádově tisíce trénovacích snímků. Trénovací data lze rozdělit do dvou kategorií:
\begin{itemize}
\item Pozitivní - data která obsahují námi hledaný objekt
\item Negativní - data ve kterých se nevyskytují hledané objekty
\end{itemize}
Pro získání větší robustnosti modelu se doporučuje trénovací data duplikovat a na duplikovanou množinu aplikovat např. rozostření nebo zašumění\cite{OpenCV}. Výpočet modelu je velmi náročný, proto se zpravidla provádí na nějakém výkonném serveru s možností hardwarevé akcelerace. Výsledkem trénovací fáze je model např. ve formě .xml souboru, který se při klasifikační fázi použije k hledání daného objektu.

Princip fungování těchto modelů si vysvětlíme na jednom z nejrozšířenějších modelů a sice kaskádovém klasifikátoru.
V prvním kroku je potřeba vypočítat tzv. Haarovy funkce. Tyto funkce spočítají pro každý bod součet intenzity okolních bodů a následně určují rozdíly mezi těmito součty. Haarovy funkce patří mezi slabé klasifikátory, to znamená, že jejich použitím dokážeme získat řešení jen o něco málo lepší než náhodné. Příkladem může být informace o tom, že mezi dvěma koly u automobilu musí být světlejší barva reprezentující vozovku. U automobilu tento postup povede k detekci, nicméně existuje velké množství snímků, kde jsou mezi dvěma tmavšími body světlejší.
Z toho důvodu se pomocí algoritmu Adaboost vytvoří kaskády, které vytvoří tzv. silné klasifikátory. Podrobný princip algoritmu AdaBoost je popsán v \cite{OpenCV}.
Detektor označí hledaný objekt na daném místě až v případě, kdy projde celou kaskádou a poslední fáze klasifikátoru skončí s pozitivním výsledkem. Při klasifikaci se vychází z předpokladu, že větší část obrazu neobsahuje vyhledávaný objekt. Algoritmus je navrhnutý tak, aby co nejdříve zamítnul negativní vzorky, naopak pro ty pozitivní se postupně prochází až do konce. Výhodou tohoto postupu je vysoký výpočetní výkon.

Další možností je využití neuronových síťí. Jedná se o velmi rozsáhlou problematiku, která přesahuje oblast této práce a proto se jim zde dále nebudeme věnovat.
\n{1}{Detekce tvarů}
V předcházející kapitole jsou popsány způsoby jakými lze rozdělit obraz na jednotlivé segmenty. V této kapitole bude posáno jakým způsobem lze popsat vlastnosti daných segmentů. Existují dva způsoby popisu:
\begin{itemize}
\item Popis vnější hranice 
\item Popis vnitřních vlastností
\end{itemize}
V prvním případě se zabýváme body, které leží na hranici daného segmentu a popisují jeho tvar. Mezi zkoumané vlastnosti lze zařadit např. délku, tvar, plochu, orientaci nebo poměr poměr stran.
Při popisu vnitřních vlastností se zaměřujeme na vlastnosti celku např. barva objektu nebo textura. 
V této kapitole se dále budeme zabývat popisem vnější hranice.
\n{2}{Popis hranic objektu}
Každý objekt je možné ohraničit pomocí rámečku. Ohraničení objektu rámečkem je vhodné pro jednodušší tvary, které neobsahují členité hranice. Existuje několik typů rámečků, mezi nejčastěji používané patří:
\begin{itemize}
\item Obdelníkový rámec,
\item Rámec minimalizující plochu,
\item Kruhový rámec.
\end{itemize}
Výpočet obdelníkového rámce je jednoduchý. Z detekovaného objektu vezmeme nejmenší a největší hodnoty na osách $x$ a $y$, pomocí těchto bodů vytvoříme obdelník, který popisuje daný objekt. Nevýhodou je vyšší míra nepřesnosti u objektů s členitými obrysy.
Pro výpočet rámce minimalizujícího plochu musíme objektem rotovat kolem jeho středu. Pro každé pootočení se vypočítá obedlníkový rámec a jeho plocha. Jako výsledný rámec se použije ten, který má nejmenší plochu. Je vhodné jej využít zvláště u natočených či jinak zkreslených objektů.

Pokud má objekt složitější hranice provedeme popis jeho hranic pomocí aproximace křivek. Výsledkem je hierarchicky členěný seznam křivek, který obsahuje mimo jiné informace o vztahu mezi jednotlivými křivkami. 
\n{2}{Houghova transformace}
Při implementaci Haugfhovy transformace je potřeba znát analytický popis hledaného tvaru, proto se využívá zejména pro detekci přímky, kružnice nebo elipsy. Výhodou této metody je kvalitní řešení i v případě  nepravidelné nebo přerušované křivky. Nevýhodou této metody je vysoká výpočetní náročnost. Pokud potřebujeme najít úsečky je třeba algoritmus rozšířit, protože výstupem houghovy transformace jsou pouze přímky.

Každá přímka v rovině $x$ a $y$ lze popsat pomocí parametrů $(r, \theta)$ kde $r$ udává vzdálenost od středu souřadného systému a $\theta$ udává úhel od osy $x$.
Rovnici přímky zapíšeme jako
\begin{equation}
r = x*\sin(\theta) + y*\sin(\theta).\label{eq:rovnice_primky}
\end{equation}

\obr{Grafické znázornění popisu přímky}{fig:Hog}{0.5}{graphics/img/primka.eps}

Do rovnice \ref{eq:rovnice_primky} dosadíme souřadnice bodu $(x,y)$, množina všech možných řešení $(r, \theta)$ vytvoří v Houghově prostoru křivku. Tato křivka bude mít tvar funkce sinus. Pokud si do Houghova prostoru promítneme všechny body tvořící přímku, zjistíme že všechny křivky se protnou v jednom bodě $(r,\theta)$. Tento bod tvoří parametry námi hledané přímky \cite{Hough}.


\n{2}{Kruhovost}
K určení kruhovosti lze využít houghovy transformace. Dalším možným způsobem je určení těžiště objektu. Následně tento objekt rotujeme kolem tohoto těžiště. U kružnice platí, že těžiště odpovídá středu kružnice. Pokud se tedy pozice objektu při rotaci nemění, lze jej označit za kruh.



% ============================================================================ %

% Pokud Vaše práce neobsahuje analytickou část, stačí odstranit či zakomentovat nasledujících pár rádků
%\cast{Analytická část}

%\n{1}{Nadpis}

%\n{2}{Podnadpis}


% ============================================================================ %

\cast{Praktická část}
\n{1}{Úvod}
Cílem práce je navrhnout algoritmus pro detekci a sledování automobilu z videokamery umístněné na palubní desce automobilu. Na obrázku \ref{fig:inputData} je zachycen snímek s předpokládanými vstupními daty. Na algoritmus máme tyto požadavky:
\begin{itemize}
\item Detekce automobilu jedoucího před námi,
\item Detekce pouze jednoho automobilu,
\item Sledování daného automobilu a měření jeho relativní velikosti.
\end{itemize}
Z výše uvedených požadavků vyplývá, že cílem je popis charakterických vlastností automobilu z pohledu „zezadu“. Schéma znázorňující základní charakteristiky automobilu je na obrázku \ref{fig:car_scheme}. Mezi základní charakteristické rysy patří \cite{ComputerVision}:
\begin{itemize}
\item Rozměry a poměr stran detekovaného automobilu
\item Státní poznávací značka
\item Barva detekovaného automobilu
\item Brzdová světla
\end{itemize}

Poměr stran se zásadním způsobem liší u osobních a nákladních automobilů. Pro osobní automobily je poměr šířka/výška asi 0,8. U nákladních automobilů je situace složitější, vzhledem k existenci velkého množství typů nákladních automobilů není možné poměr stran jednoduše určit. Pro výpočty byla stanovena minimální šířka automobilu jako 5\,\% z celkové šířky obrazu. Tato hodnota odpovídá 40 pixelům, u menších objektů již není možné rozpoznat zda se jedná o automobil. U výšky automobilu žádná minimální ani maximální hranice nebyla stanovena z důvodu různé výšky nákladních automobilů.

Státní poznávací značka se nachází ve spodní části automobilu, typicky má bílou barvu. Rozměr státní poznávací značky používané v České republice pro osobní automobily je $520 \times 110 mm$. Poměr stran šířka/výška je tedy cca 4,7 \cite{SPZ}. 

Při pohledu zezadu není barva až tak rozhodující. Velkou část plochy zabírá zadní sklo, která má obdelníkový tvar a charakteristickou barvu.

Tvar brzdových světel nelze obecně určit, každý výrobce automobilů používá jiný tvar. Lze říct, že brzdová světla jsou na automobilu dvě a jsou umístněna symetricky.  Brzdová světla mají charakterickou červenou barvu. Pro použití na záznamy pořízené za denního světla není detekce brzdových světel vhodná \cite{ComputerVision}. Detekci brzdových světel by bylo možné využít u nočních snímků, nicméně toto není součástí implementace.

\obr{Schematické znázornění charakteristických prvků auta}{fig:car_scheme}{0.4}{graphics/img/car_scheme.eps}

\n{2}{Použité technologie}
Aplikace je implementována v programovacím jazyce C++, grafická část je vytvořena v Qt frameworku. Při vývoji byl pro rychlé prototypové návrhy využit také programovací jazyk Python.

Pro zpracovní obrazu byla použita knihovna OpenCV. Jedná se o open source knihovnu, která obsahuje velké množství předdefinovaných funkcí pro zpracování obrazu. OpenCV je distribuována pod BSD licencí. První verze této knihovny vyšla v roce 2000 a je stále aktivně vyvíjena. Hlavní programovací jazyk je C++, ale existují i doplňky do jazyka Python, Java nebo Matlab. Knihovnu OpenCV je možné zkompilovat s podporou HW akcelerace, kdy je možné využití technologii OpenCL nebo CUDA. Aplikace a algoritmy jsou vytvořeny a zkoušeny ve verzi OpenCV 3.4.1. U ostatních verzí není správná funkcionalita zaručena.

\obr{Ukázka vstupních dat}{fig:inputData}{0.8}{graphics/img/inputData.png}

\n{1}{Detekce a sledování automobilu}\label{sec:carDetect}
V této kapitole jsou popsány dva způsoby pro detekci automobilu. První způsobem je použítí kaskádového klasifikátoru. Druhým způsobem je detekce pomocí segmentace obrazu. Pro sledování automobilu a určení jestli se vzdaluje nebo oddaluje byly implementovány také dva způsoby. První porovnává velikost vůči pevně stanovenému místu ve videosouboru. Druhý způsob funguje na principu klouzavého průměru.
\n{2}{Použití předtrénovaného klasifikátoru}
Jako první byla implementována detekce automobilu za pomoci kaskádového klasifikátoru. Princip je popsán v kapitole \ref{sec:haar}. Trénovací množina dat byla stažena z internetového zdroje \cite{carDataset}. Pro trénování a klasifikaci byla použita knihovna OpenCV a její funkce $CascadeClassifier$. Výsledky této metody nejsou uspokojivé. Téměř každý snímek obsahuje množství falešných detekcí. Ukázka falšené detekce je na obrázku \ref{fig:haar}. Pokud došlo ke správné detekci, není detekce přesná. Příklad detekce, která není přesná je zobrazen na obrázku \ref{fig:haar_ok}. Podrobnější zhodnocení výsledků je uvedeno v kapitole \ref{sec:vysledky}.
\obr{Výstup z předtrénovaného modelu}{fig:haar_ok}{1}{graphics/img/haar_ok.jpg}
\obr{Ukázka množství falešných detekcí u předtrénovaného klasifikátoru}{fig:haar}{1}{graphics/img/haar.jpg}

\n{2}{Detekce automobilu pomocí segmentace obrazu}
Druhým implementovaným algoritmem pro detekci automobilu je detekce pomocí segmentace obrazu. Nejprve je aplikováno předzpracování obrazu a poté následuje segmentace a detekce. 
\n{3}{Podvzorkování a ořezání obrazu}
Vstupní data obsahují obraz ve vysokém rozlišení. Toto rozlišení zbytečně zpomaluje výpočet, proto jsou vstupní data na začátku podvzorkována na rozlišení $800\times y$, kde $y$ je vypočteno tak, aby zůstal zachován původní poměr stran. Ve vstupních datech jsou obsaženy data vypálená přímo do obrazu, to způsobuje problémy při detekci. Z toho důvodu je tato oblast ořezána. Veškeré výpočty jsou dále prováděny nad podvzorkovanými a ořezanými daty, na závěr je výsledek přepočítán a vykreslen do původního rozlišení.

\n{3}{Odstranění kapoty}
Zdrojový materiál je natočen pomocí kamery, která umožňuje až $30\times$ optické přiblížení. Pokud obsluha kamery nastaví přiblížení v rozmezí $1\times$ nebo $2\times$, je ve vstupních datech vidět kapota automobilu. Ta způsobuje problémy při segmentaci obrazu. Výsledek segmentace obrazu, který obsahuje záběr kapoty, lze vidět na obrázku \ref{fig:kapota}. Algoritmus byl upraven tak, aby dokázal automaticky detekovat kapotu a provedl oříznutí této části obrazu.
\obr{Pokus o segmentaci obrazu pokud je vidět kapota}{fig:kapota}{1}{graphics/img/kapota.png}

\n{3}{Definice oblasti zájmu}
\obr{Definice oblasti zájmu}{fig:ROI}{1}{graphics/img/ROI.png}
Z důvodu odstranění falešných výsledků je stanovena oblast zájmu. Hledáme automobil jedoucí před námi, tomu tvarově odpovídá oblast zájmu. Levá strana je více zkosená z důvodu vyloučení automobilů jedoucích v protisměru. Tvar této oblasti lze vidět na obrázku \ref{fig:ROI}.  Pokud je spodní hrana detekovaného automobilu mimo tuto oblast je automobil ignorován. Pro určení přesné velikosti oblasti zájmu bylo použito 50 snímků, kdy se hledala taková oblast, která jim všem vyhovuje. Nevýhodou stanovení této oblasti je nutnost nastavení správné pozice kamery. Pokud je pozice kamery v automobilu příliš vychýlená dolů, dojde ke snížení úspěšnosti detekce. Naopak pokud je pozice kamery příliš vychýlená nahoru, dojde ke zvýšení falešných detekcí.

\n{3}{Postup při detekci}
Vstupní data byla nejprve ořezána a podvzorkována. Následuje převod do stupňů šedi a ekvalizace histogramu. Dále byl obraz rozostřen pomocí Gaussova filtru s velikostí konvolučního jádra $7 \times 7$. Jako nejlepší metoda prahování se pro tento účel ukázala adaptivní hodnota prahu s prahem vypočteným pomocí Gaussovy metody. Na výsledný binární obraz byla aplikována morfologická operace otevření se strukturálním prvkem o velikosti 10 pixelů. Po nalezení shluků jsou aplikovány doplňující podmínky na velikost, poměr stran a pozici. Objekty které zůstanou, jsou označeny jako kandidáti na automobil. Následně jsou tito kandidáti otestováni na charakteristické vlastnosti automobilu. V oblasti výskytu kandidáta se hledá bílý obdelník, reprezentující státní poznávací značku a obdelník reprezentující zadní sklo automobilu. Pokud není ani jedna z těchto vlastností nalezena, dojde k vyřazení kandidáta.  Pokud je výsledkem více automobilů je označen ten, který pozicí více odpovídá očekávanému výskytu, tj. ten který se v ose $x$ nachází blíže středu obrazu.
Vývojový diagram algoritmu detekce je znázorněn na obrázku \ref{fig:vyvojak}.
\obr{Vývojový diagram algoritmu pro detekci automobilu}{fig:vyvojak}{0.8}{graphics/img/vyvojak.png}

\n{2}{Měření relativní velikosti a sledování vozidla}
Výsledkem detekce vozidla je obdelník, který toto vozidlo popisuje. Při měření relativní velikosti jsou srovnávány velikosti těchto obdelíků mezi dvěmi snímky.
Měření relativní velikosti probíhá v pixelech. Pro měření skutečné velikosti by bylo potřeba použít stereo kamery a nebo provést kalibraci kamery \cite{MITTNER}. 
Pro měření relativní velikosti vozidla byly implementovány dva algoritmy.

V prvním případě probíhá porovnání velikosti vozidla vůči pevně stanovenému místu ve videosekvenci. Tento princip je využitelný v případě, kdy potřebujeme určit jestli se vozidlo přiblížilo nebo vzdálilo v rámci pevně stanoveného úseku.

Druhý implementovaný způsob počítá průměrnou velikost z posledních 25 snímků, tento průměr je následně porovnán s akutální velikostí.
Výsledkem je informace o tom, jestli se automobil aktuálně vzdaluje nebo přibližuje. Nevýhodou tohoto algoritmu je časté střídání informace vzdaluje/přibližuje v případech, kdy některý z předcházejících snímků je určen s nízkou přesností.
Pokud se vozidlo přibližuje je označeno červeným obdelníkem, naopak pokud se vozidlo vzdaluje je označeno zeleným obdelníkem.
\obr{Ukázka vzdalujícího se automobilu}{fig:Car_green}{1}{graphics/img/car_green.png}
\obr{Ukázka přibližujícího se automobilu}{fig:Car_red}{1}{graphics/img/car_red.png}

Pro sledování vozidla je důležité mezi snímky určit, jestli se jedná o stejné vozidlo. Toho je dosaženo pomocí několika kritérií. Mezi snímky je porovnávána pozice automobilu, zde je vzhledem k pohybu a chybě určení vozidla stanovena povolená odchlylka 10\,\% oproti pozici na předcházejícím snímku. Dále je porovnáván poměr stran rozměrů vozidla a barva automobilu. Pokud není některá z těchto podmínek splněna, není možné porovnat relativní velikost vozidla mezi snímky, neboť se pravděpodobně jedná o dvě ruzná vozidla.

\n{1}{Detekce jízdních pruhů}
Při detekci jízdních pruhů dochází podobně jako při detekci automobilu k ořezání obrazu, jeho podvzorkování, vyhledání a odstranění kapoty automobilu. Při detekci jízdních pruhů je použita stejná oblast zájmu jako při detekci automobilu. V dalším kroku je aplikována detekce bílé barvy. Souběžně je obraz převeden do stupňů šedi a na tento obraz je aplikováno prahování s hodnotou prahu 200. Nad těmito dvěma obrazy je provedena binární operace $OR$ \cite{Lanes}. Výsledkem je černobílý obraz, ve kterém jsou vyznačeny body společné pro oba vstupní obrázky.

Tento obraz slouží jako vstup pro Houghovu transformaci. Výsledné přímky jsou podle svislé osy obrazu rozdělěny na dvě poloviny. Dále se kontroluje úhel těchto přímek. Přímky musí mít úhel s osou $x$ v rozmezí $45° - 90°$, jinak jsou z výběru odstraněny. Tento úhel odpovídá rozmezí ve kterém se můžou vyskytovat jízdní pruhy \cite{Lanes}.
\obr{Vývojový diagram algoritmu pro detekci jízdních pruhů}{fig:vyvojak_lines}{0.5}{graphics/img/vyvojak_lines.png}

\obr{Detekce bílé barvy}{fig:lane}{1}{graphics/img/lane.png}
\obr{Výsledek detekce jízdních pruhů, detekované pruhy jsou zvýrazněny žlutou barvou}{fig:lane_result}{1}{graphics/img/lanes_result.png}


\n{1}{Aplikace Image filters}
Výsledkem této práce je aplikace Image filters. Aplikace  umožňuje uživateli provádět filtraci obrazu. Součástí této aplikace jsou výše popsané algoritmy pro detekci automobilu a jízdních pruhů. Uživateli je umožněno na obraz aplikovat předdefinové filtry. Dále si uživatel může z těchto filtrů poskládat vlastní, složitější, filtry. Je umožněno zpracovávat jak obrázky tak videosoubory.  

\n{2}{Ovládání aplikace}
Základní obrazovka aplikace je tvořena dvěma okny pro obrazová data. Jedno pro zobrazeni vstupních dat, druhé pro zobrazení dat po použití filtrů. Vpravo je seznam aktuálně načtených souborů.
Pokud je zašrtnuto tlačítko $Save$ budou výsledky každého zpracování uloženy. Vedle tlačítka $Save$ je možné nastavit název výstupního souboru. Pokud již soubor se stejným jménem existuje, bude přepsán.
Pod obrazovými daty se nachází ovládání k přidávání, odebírání a upravování filtrů. Sloupec vlevo obsahuje seznam aktuálně přiřazených filtrů, v pravém sloupci se nachází seznam všech filtrů, které lze přesunout do levého sloupce. Po označení filtru, který se nachází v seznamu aktivních filtrů, se vpravo zobrazí možnosti pro upravení jeho parametrů. Ihned po změně parametrů je výsledek přepočítán.
V dolní statusové liště se zobrazuje čas v milisekundách, který udává dobu zpracování jednoho snímku. Vedle se nachází informace o aktuální pozici kurzoru v rámci obrazu.

\obr{Screenshot aplikace Img filter}{fig:ImgFilter}{1}{graphics/img/imageFilter.png}
Po přepnutí na přehrávání videosouborů se pod obrazem objeví tlačítka pro přehrávání videousouborů. Detail těchto tlačítek je znázorněn na obrázku \ref{fig:VideoControl}. Popis ovládacích tlačítek:
\begin{itemize}
\item Play/Pause - přehrání/pozastavení přehrávání videosouboru
\item Previous -  Přepnutí na předcházející snímek
\item Nex -  Přepnutí na následující snímek
\item Set start frame -  Nastavní aktuální snímek jako referenční pro měření vzdálenosti, funguje poouze při zaškrtnutém tlačítku $Fixed$
\item Fixed - Výběr algoritmu pro měření relativní velikosti 
\item Moving  avg - Výběr algoritmu pro měření relativní velikosti 
\end{itemize}
Podrobnější popis algoritmů na měření vzdálenosti je popsán v kapitole \ref{sec:carDetect}.

\obr{Detail tlačítek pro ovládání přehrávání videosouborů}{fig:VideoControl}{0.8}{graphics/img/videoControl.png}

\n{2}{Ukládání a načítání filtrů}
Aplikace umožňuje ukládání a načítání filtrů, které si uživatel nadefinuje. Data se ukládají ve formátu $xml$. Soubor s platným seznamem filtrů musí obsahovat kořenový element $FilterList$. Další vnořené elementy reprezentují jednotlivé filtry a jejich parametry. K načtení a ukládání slouží tlačítka $LoadFilter$ a $SaveFilter$, která jsou umístněny v horním menu. 

Ukládání a načítání filtrů má na starosti třída $ImgProc$, která obsahuje metody $loadFilter$ a $saveFilter$. Při načítání filtru dochází ke kontrole, jestli je daný filter platný. V případě nekompatibility je uživatel upozorněn chybovou hláškou.
\obr{Ukázka uloženého filtru ve formátu Xml}{fig:Xml}{0.8}{graphics/img/xml_filter.png}

%\begin{lstlisting}
%<?xml version="1.0" encoding="UTF-8">
%<summary>Tootsie roll tiramisu macaroon wafer carrot cake. &#xD;Danish topping sugar plum tart bonbon caramels cake.</summary>
%\end{lstlisting}

\n{2}{Nastavení aplikace}
Aplikace umožňuje základní nastavení. Je možné nastavit defaultní složku odkud se budou načítat data a defaultní složku pro načítání a ukládání filtrů. Dále je možné nastavit defaultní složku pro ukládání výstupu.
\n{2}{Implementace}
Jádro celé aplikace tvoří třída $ImgProc$, která slouží k ukládání a použití aktuálně nastavených filtrů. Jednotlivé filtry vychází z abstraktní třídy $ImgFilter$. Každý filtr obsahuje seznam paramterů. Objektové třídy pro jednotlivé parametry vychází z abstraktní třídy $ImgFilterParam$. 

\n{1}{Testování a zhodnocení úspěšnosti}\label{sec:vysledky}
Důležitou součástí práce je také zhodnocení výsledků, které je popsáno v této kapitole. Zhodnocení výsledků je reprezentováno graficky pomocí grafů, tabulek a matic změn.
\n{2}{Testovací data}
První část testovacích dat byla pořízena za ideálních podmínek, mimo veřejnou komunikaci. Druhá část byla pořízena v reálném provozu na běžné silnici druhé třídy. Dohromady tyto dvě části tvoří jeden dataset na kterém probíhalo testování.

Pro nahrání testovacích dat byla použita kamera SONY FCB EV7520. Videosoubory jsou nahrány v HD rozlišení. Datový tok byl nastaven na 4 MB/s. Testovací data jsou uložena v kontejneru mp4, použitý kodek je h.264.
\obr{Fotografie kamery, se kterou byly pořízeny testovací data}{fig:Kamera}{0.8}{graphics/img/camera.png}

\n{2}{Výpočetní náročnost}
Pro testování výpočetní náročnosti daného algoritmu byli zvoleny tři výpočetní stroje. Prvním je stolní PC osazené procesorem Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz a 16 GB paměti RAM. Druhým je notebook s procesorem  Intel(R) Core(TM) i3 CPU M 350  @ 2.27GH a 4 GB paměti RAM. Jako třetí testovací zařízení byl zvolen embeded počítač s procesorem NXP i.MX 6 1 GHZ a 4 GB paměti RAM.
Záměrně byl zvolen jeden výkonější počítač, druhý bežný notebook a třetí embedded počítač. Srovnáním doby výpočtu na těchto zařízeních bude možné si udělat představu o výpočetní náročnosti algoritmů. Jako reprezentativní vzorek bylo použito tisíc snímků, což odpovídá asi čtyřiceti sekundám videozáznamu.

V tabulkách  \ref{tab:klasifikator}, \ref{tab:car}, \ref{tab:lanes} je zobrazeno srovnání doby výpočtu jednotlivých alogoritmů na testovacích zařízeních. Průměrné hodnoty byly počítány ze vzorku dat o velikosti 1000 snímků.  Grafické znázornění je v grafech \ref{fig:segmentace_vykon}, \ref{fig:model_vykon} a \ref{fig:lane_vykon}. Graf \ref{fig:vykon_srovnani} zobrazuje srovnání výpočetní doby algoritmů. Z naměřených hodnot vyplývá, že předtrénovaný klasifikátor je z implementovananých algoritmů, nejrychlejší a tedy výpočetně nejméně náročný. Z výsledků lze vidět, že algoritmus pro detekci jízdních pruhů je o něco náročnější, než klasifikátor. To je způsobeno použitím Houghovy transformace, která je výpočetně náročná.

\tab{Srovnání doby výpočtu pomocí předtrénovaného klasifikátoru}{tab:klasifikator}{1}{| c | c | c | c | c |}{
  \hline
   & Min. čas [ms] & Max. čas [ms] & Průměrný čas [ms] & Max. fps \\ \hline
  \emph{Stolní PC} & 4 & 18 & 11,0 & 90  \\ \hline
  \emph{Notebook} & 34 & 67 & 50.5 & 19  \\ \hline
  \emph{Embedded PC} & 58 & 109 & 82.8 & 12  \\ \hline
}

\tab{Srovnání doby výpočtu detekce automobilu}{tab:car}{1}{| c | c | c | c | c |}{
  \hline
   & Min. čas [ms] & Max. čas [ms] & Průměrný čas [ms] & Max. fps \\ \hline
  \emph{Stolní PC} & 7 & 25 & 15.9 & 63  \\ \hline
  \emph{Notebook} & 47 & 88 & 67.9 & 14  \\ \hline
  \emph{Embedded PC} & 85 & 123 & 103.9 & 9  \\ \hline
}

\tab{Srovnání doby výpočtu detekce jízdních pruhů}{tab:lanes}{1}{| c | c | c | c | c |}{
  \hline
   & Min. čas [ms] & Max. čas [ms] & Průměrný čas [ms] & Max. fps \\ \hline
  \emph{Stolní PC} & 4 & 22 & 12.4 & 77  \\ \hline
  \emph{Notebook} & 47 & 78 & 57.9 & 17  \\ \hline
  \emph{Embedded PC} & 79 & 115 & 97.1 & 10  \\ \hline
}

\obr{Srovnání doby výpočtu detekce automobilu pomocí segmentace}{fig:segmentace_vykon}{0.8}{graphics/img/segmentace_vykon.eps}

\obr{Srovnání doby výpočtu detekce automobilu pomocí klasifikátoru}{fig:model_vykon}{0.8}{graphics/img/model_vykon.eps}

\obr{Srovnání doby výpočtu detekce jídzních pruhů}{fig:lane_vykon}{0.8}{graphics/img/lane_vykon.eps}

\obr{Srovnání výpočetní doby algoritmů}{fig:vykon_srovnani}{0.8}{graphics/img/vykon_srovnani.eps}

Za povšimnutí stojí fakt, že doba výpočtu se mezi jednotlivými snímky liší, v některých případech až několikanásobně. Ze všech naměřených hodnot lze konstatovat, že navrhnuté algoritmy pro detekci automobilu a jízdních pruhů jsou schopny pracovat v reálném nebo téměř reálném čase. Pokud budeme výpočet provádět na méně vykonném zařízení, je potřeba počítat s tím, že FPS bude nižší a výsledné zobrazení tedy nebude tak plynulé.

\n{2}{Úspěšnost detekce sledovaného objektu v obraze}
Data pro testování úspěšnosti detekce byla rozdělena na dva typy, první jsou data která obsahují hledaný objekt. Zde bylo hodnoceno jestli došlo k detekci a jestli byl rozpoznán požadovaný objekt. V druhém datovém souboru jsou snímky bez hledaného objektu, cílem je určit množství falešných detekcí. Z obou datových souborů bylo použito 1000 snímků.

Z naměřených výsledků vyplývá, že předtrénovaný klasifikátor dává velké množství falešných detekcí. Při nepřítomnosti automobilu, označil automobil v 895 případech z 1000. Tedy téměř 90\% chyba. V případě přítomnosti automobilu jej algoritmus detekoval v 620 případech z 1000. Úspěšnost detekce činí u předtrénovaného klasifikátoru 62,0\,\%. Celková úspěšnost, kdy algoritmus správně detekuje automobil je pouze 36,2\,\%. Tento výsledek je z větší části ovlivněn množstvím falešných detekcí. Z výše uvedného vyplývá, že algoritmus nedosahuje uspokojivých výsledků. Zhodnocení výsledků pomocí matice změn je zobrazeno v tabulce \ref{tab:matice_model}.

\tab{Matice změn pro detekci automobilu pomocí klasifikátoru}{tab:matice_model}{1}{| c | c | c | }{
  \hline
  &  \multicolumn{2}{|l|}{ Skutečnost} \tabularnewline
    \hline
   & \emph{Automobil} &  \emph{Není automobil}  \\ \hline
  \emph{Detekce automobilu} 		  & \textbf{620} & 895  \\ \hline
  \emph{Automobil není detekován} & 380 & \textbf{105} \\ \hline
}


Klasifikace pomocí segmentace obrazu dosahuje výrazně lepších výsledků. V případě přítomnosti automobilu tento jej tento algoritmus správně detekoval v 782 případech z 1000. Dosáhl tedy úspěšnosti 78,2\,\%. Z 1000 snímků bez automobilu tento alogoritmus na 158 detekoval automobil. Falešných detekcí je tedy 15,8\,\%. Celková úspěšnost algoritmu činní 81,2\,\%. I tento výsledek je ovlivněn falešnými detekcemi, i když ne tak výrazně jako v předcházejícím případě. Na obrázku \ref{fig:result_1} a \ref{fig:result_2} je vidět ukázka výsledků detekce. Zhodnocení výsledků pomocí matice změn je zobrazeno v tabulce \ref{tab:matice_seg}.

\tab{Matice změn pro detekci automobilu pomocí segmentace obrazu}{tab:matice_seg}{1}{| c | c | c | }{
  \hline
    &  \multicolumn{2}{|l|}{ Skutečnost} \tabularnewline
    \hline
   & \emph{Automobil} &  \emph{Není automobil}  \\ \hline
  \emph{Detekce automobilu} 	  & \textbf{782} & 158  \\ \hline
  \emph{Automobil není detekován} & 218 & \textbf{842} \\ \hline
}

\obr{Ukázka výsledků detekce pomocí segmentace obrazu}{fig:result_1}{1}{graphics/img/result_1.jpg}
\obr{Ukázka výsledků detekce pomocí segmentace obrazu}{fig:result_2}{1}{graphics/img/result_2.jpg}

Dekektor jízdních pruhů úspěšně dětekoval na 795 snímcích z 1000.  Úspěšnost detekce tedy činní 79,5\,\%. Počet falešných detekcí byl 118 z tisíce snímků.  Úroveň falešných detekcí u detektoru jízdních pruhů činní 11,8\,\%. Celková úspěšnost algoritmu pak činní 83,8\,\%. Výsledky detekce jízdních pruhů jsou zobrazeny na obrázku \ref{fig:result_lanes}. Zhodnocení výsledků pomocí matice změn je zobrazeno v tabulce \ref{tab:matice_lines}.
\tab{Matice změn pro detekci jízdních pruhů}{tab:matice_lines}{1}{|c | c | c | }{
  \hline
  &  \multicolumn{2}{|l|}{ Skutečnost} \tabularnewline
    \hline
  &\emph{Jízdní pruh} &  \emph{Není jízdních pruh}  \\ \hline
   \emph{Detekce jízdního pruhu} & \textbf{795} & 118  \\ \hline
   \emph{Pruh není detekován} &  205 & \textbf{882} \\ \hline
}

\obr{Ukázka výsledků detekce jízdních pruhů}{fig:result_lanes}{1}{graphics/img/lanes_result.jpg}

\n{2}{Přesnost určení rozměrů sledovaného vozidla}
Porovnání přesnosti probíhalo na testovací sadě 20 snímků. Při hodnocení chyby měření byly použity pouze takové snímky, kde algoritmus dokázal úspěšně detekovat automobil. Testovací množina je tedy pro každý algoritmus různá. Výsledky jsou zobrazeny v tabulkách \ref{tab:data} a \ref{tab:data_1}. Jako hodnotící kritérium byla zvolena procentuální odchylka od skutečné šířky  v pixelech. Porovnání přesnosti měření probíhalo ručním způsobem, ve výsledcích je tedy zahrnuta subjektivní chyba hodnotitele. Data jsou zaokrouhleny na desítky pixelů. Detektor jízdních pruhů nebyl na přesnost testován. Z výsledků je zřejmé, že detekce automobilu pomocí segmentace obrazu dosahuje $6\times$ vyšší přesnosti než předtrénovaný klasifikátor. Průměrná odchylka u předtrénovaného klasifikátoru činí 109,5\,\%. Průměrná odchylka u detekce pomocí segmentace obrazu je 12,1\,\%. Grafické srovnání průměrné odchylky velikosti je zobrazeno v grafu \ref{fig:odchylka}.

\tab{Testovací data pro odchylku velikosti - detekce pomocí segmentace}{tab:data}{1}{| c | c | c | c | }{
  \hline
    \emph{Snímek} &  \emph{Skutečná velikost [px]} &  \emph{Naměřená velikost [px]} &  \emph{Odchylka [\%]} \\ \hline
  1 & 200 & 200 & 0,0  \\ \hline
  2 & 150 & 160 & 6,6  \\ \hline
  3 & 250 & 240 & 4,0  \\ \hline
  4 & 200 & 220 & 10,0  \\ \hline
  5 & 400 & 440 & 10,0  \\ \hline
  6 & 230 & 230 & 0,0  \\ \hline
  7 & 240 & 300 & 25,0  \\ \hline
  8 & 200 & 220 & 10,0  \\ \hline
  9 & 100 & 80 & 20,0  \\ \hline
  10 & 100 & 60 & 40,0  \\ \hline
  11 & 50 & 60 & 20,0  \\ \hline
  12 & 80 & 100 & 25,0  \\ \hline
  13 & 350 & 340 & 2,8  \\ \hline
  14 & 750 & 850 & 13,0  \\ \hline
  15 & 600 & 660 & 10,0  \\ \hline
  16 & 580 & 480 & 17,0  \\ \hline
  17 & 340 & 340 & 0,0  \\ \hline
  18 & 210 & 220 & 4,7  \\ \hline
  19 & 210 & 175 & 16,0  \\ \hline
  20 & 240 & 220 & 8,0  \\ \hline
}

\tab{Testovací data pro odchylku velikosti - klasifikátor}{tab:data_1}{1}{| c | c | c | c | }{
  \hline
    \emph{Snímek} &  \emph{Skutečná velikost [px]} &  \emph{Naměřená velikost [px]} &  \emph{Odchylka [\%]} \\ \hline
  1 & 180 & 300 & 66,6  \\ \hline
  2 & 130 & 260 & 100  \\ \hline
  3 & 270 & 240 & 11,1  \\ \hline
  4 & 190 & 300 & 57,8  \\ \hline
  5 & 260 & 520 & 100  \\ \hline
  6 & 600 & 620 & 3,3  \\ \hline
  7 & 180 & 400 & 122,2  \\ \hline
  8 & 40 & 360 & 10,0  \\ \hline
  9 & 100 & 80 & 20,0  \\ \hline
  10 & 50 & 320 & 540,0  \\ \hline
  11 & 90 & 400 & 344,5  \\ \hline
  12 & 80 & 22 & 175,0  \\ \hline
  13 & 600 & 440 & 26,6  \\ \hline
  14 & 550 & 700 & 27  \\ \hline
  15 & 450 & 850 & 88,8  \\ \hline
  16 & 700 & 560 & 20  \\ \hline
  17 & 360 & 440 & 19,4  \\ \hline
  18 & 190 & 400 & 110  \\ \hline
  19 & 40 & 120 & 200  \\ \hline
  20 & 120 & 300 & 150  \\ \hline
}

\obr{Srovnání průměrné odchylky naměřené velikosti od skutečné velikosti}{fig:odchylka}{1}{graphics/img/odchylka.eps}

% ============================================================================ %
\nn{Závěr}
V této práci byly teoerticky popsány metody pro zpracování digitálního obrazu. V úvodu je popsán digitální obraz a formy jeho reprezentace. Dále jsou nastíněny možnosti předzpracování obrazu a způsoby detekce hran. Následuje popis metod pro detekci objektů a popis jejich vlastností. Tyto teoretické poznatky byly dále využity v praktické části.

Za pomoci programovacího jazyka C++, Qt frameworku a knihovny OpenCV byla vytvořena aplikace s název Image Filters.  Tento program umožňuje aplikovat na obrázky nebo videosoubory předdefinované grafické filtry. Uživateli je také umožněno pomocí předdefinovaných filtrů vytvářet vlastní, složitější, filtry.

Na základě získaných teoretických poznatků byly implementovány dva algoritmy pro detekci automobilu v obraze a jeden algoritmus pro detekcí jízdních pruhů. Všechny tyto algoritmy jsou součástí aplikace Image Filters.

Výsledné algoritmy byly podrobeny testování na datech z reálného provozu. Z hlediska výpočetní výkonnosti proběhlo srovnání na třech různě vykonných zařízeních. Testy prokázaly, že všechny tři algoritmy jsou schopny, na nejvýkonnějším zařízení, pracovat v reálném čase s FPS větším něž 30. Na nejméně vykonném zařízení pak dosahují 9 FPS.

Při testování algoritmu na detekci automobilu pomocí předtrénovaného klasifikátoru bylo zjištěno, že algoritmus nedosahuje uspokojivých výsledků. Tato metoda dává velké množství falešných detekcí. Poměr úspěšné/neúspěšné detekce je 1/3. Tedy pouze každá třetí detekce odpovídá skutečnosti.
Pokud se algoritmu podaří správně detekovat automobil, je zvýrazněná plocha téměř 2x větší než skutečnost.
Lze tedy konstatovat, že tento algoritmus není vhodný pro přesnou detekci automobilu. Po eliminaci falešných nálezů, by tento algoritmus bylo možné použít pro hrubý odhad oblasti výskytu automobilu.

Algoritmus detekce automobilu pomocí segmentace obrazu dosahuje celkem uspokojivých výsledků. Celková úspěšnost na testovací množině dat činní 81,2\,\%. Hlavní výhodou této metody je vysoká přesnost měření. Průměrná odchylka od skutečného rozměru je 12,4\,\%.

Detekce jízdních pruhů je také funkční. Chybných detekcí se v testovací množině vyskytuje 10\,\%. Celková úspěšnost tohoto algoritmu se blíží 90\,\%. Tento algoritmus by se dal vylepšit tak, aby v zatáčkách lépe odpovídal skutečnosti.

Detekce jízdních pruhů a automobilu má některé společné výpočetní kroky, nicméně tyto kroky jsou prováděny v každém algoritmu samostatně.
Dalším prostorem pro zlepšení je úprava algritmu tak, aby došlo ke zlepšení detekce nákladních automobilů.
% ============================================================================ %
