5.14. Gaussovo vyhlazení a hrany

Dvě úlohy dominují tomu, k čemu se okenní okolí v klasickém strojovém vidění používá: čisté vyhlazování variací mezi pixely a hledání hran, kde se obraz prudce mění. Gaussův filtr je standardním nástrojem pro to první, detektory založené na Laplaciánu standardním nástrojem pro to druhé – a obojí se kombinuje, protože každý detektor hran funguje lépe na lehce vyhlazeném vstupu.

5.14.1. Gaussův filtr

gaussian() je středově vážený příbuzný metody mean(). Oba počítají průměr přes okolí každého pixelu, ale Gaussovy váhy nejsou rovnoměrné: pixely blíže středu okolí se počítají více, pixely na okraji okolí se počítají méně, přičemž váhy sledují známou zvonovitou křivku, která dala filtru jeho název.

Zvonovité vážení je to, co dělá Gaussův filtr hladším než box průměr. Průměrovací filtrování může produkovat viditelné artefakty na okrajích objektů – ostrý ořez ve vážení zavádí drobné vzory zvonění na prudkých přechodech. Hladce klesající váhy Gaussova filtru se tomuto zvonění vyhýbají a produkují výsledek, který vypadá blíže tomu, jak by mělo „rozmazání“ vypadat. Cenou je více výpočtů na pixel než u průměrovacího filtru, ale ne dramaticky – náklady na pixel jsou stále mnohem nižší než u bilaterálního filtru.

img.gaussian(1)    # 3x3 Gaussian -- a clean light blur
img.gaussian(2)    # 5x5 Gaussian -- stronger smoothing

Gaussovo vyhlazení je standardní první fází téměř každého řetězce pro detekci hran. Detektory hran níže všechny zesilují vysokofrekvenční obsah, včetně šumu senzoru, který algoritmus ve skutečnosti detekovat nechce. Spuštění lehkého Gaussova filtru jako prvního tento šum potlačí, aniž by příliš změkčilo skutečné hrany, a ponechá detektoru hran, aby hledal skutečné hrany místo zrnitosti.

5.14.2. Maska doostření (unsharp masking)

Gaussovsky rozmazaná kopie obrazu je surovinou, kterou používá technika unsharp mask pro klasické doostření. Nastavení unsharp=True na filtru jej přepne z „vyprodukuj rozmazaný obraz“ na „odečti rozmazaný obraz od originálu a rozdíl přičti zpět k originálu“ – efektem je, že se vysokofrekvenční hrany zesílí vůči hladkým vnitřkům.

img.gaussian(1, unsharp=True)

Volitelné parametry mul a add škálují sílu výsledku doostření; výchozí hodnoty (mul=1.0, add=0.0) představují mírné doostření, které nezveličuje šum senzoru.

5.14.3. Laplaciánův filtr

laplacian() provádí diskrétní aproximaci druhé prostorové derivace obrazu. Výstup je velký tam, kde se hodnoty pixelů mění rychle, a blízký nule tam, kde jsou konstantní nebo se mění lineárně. Přirozeným čtením výsledku je odezva na hrany: pixely, kde se obraz rychle mění, se rozsvítí, pixely v hladkých vnitřcích zůstávají tmavé.

img.laplacian(1)   # 3x3 Laplacian -- edge response

K dispozici jsou stejné parametry jako u gaussian. sharpen=True produkuje doostřený obraz (Laplacián přičtený zpět do originálu, nikoli vrácený samostatně). mul a add škálují odezvu.

Praktickým využitím nad rámec detekce hran je měření zaostření. Odezva Laplaciánu zprůměrovaná přes oblast dává hrubou míru toho, kolik vysokofrekvenčního obsahu oblast nese; na dobře zaostřeném snímku je tento průměr vysoký, na rozmazaném snímku klesá. Porovnávání odezvy Laplaciánu mezi snímky je levný způsob, jak se ptát „je objektiv zaostřený?“, aniž by byla potřeba dražší metrika kontrastu.

5.14.4. Metoda find_edges

find_edges() provádí kompletní řetězec detekce hran, nikoli jen filtr odezvy na hrany. Funguje na obrazech ve stupních šedi a výsledkem je binární obraz, jehož nenulové pixely označují pozice, kde má vstup ten druh změny jasu, který by se měl počítat jako hrana.

Metoda přijímá parametr edge_type, který vybírá mezi dvěma algoritmy:

EDGE_SIMPLE spustí horní propust, aplikuje práh a vrátí výsledek. Rychlé, ale výstup zahrnuje každou změnu jasu nad prahem, včetně šumu a textury, o které aplikaci pravděpodobně nejde. Rozumné pro čisté obrazy a pro případy, kdy bude šum vyčištěn pozdějším morfologickým průchodem.

EDGE_CANNY spustí detektor hran Canny – klasický vícestupňový algoritmus. Vypočítá gradient jasu, potlačí každou nemaximální odezvu ve směru gradientu (takže každá hrana je široká jeden pixel) a aplikuje hysterezní práh (takže hrana, která je v jednom místě silná, je vykreslena i tam, kde mezitím slábne). Výsledkem je čistá, tenká, propojená sada hranových pixelů toho druhu, který chce každý klasický algoritmus založený na hranách.

Parametr threshold je dvouprvková n-tice (low, high). Pro EDGE_CANNY je hodnota high mezí, nad kterou je pixel rozhodně hranou, a hodnota low je mezí, nad kterou je pixel hranou pouze tehdy, je-li propojen s jednoznačnou hranou. Pro EDGE_SIMPLE záleží pouze na hodnotě high; je to jediná mez, nad kterou se pixel počítá jako hrana. Výchozí hodnota (100, 200) je výchozím bodem, který stojí za vyladění pro konkrétní scénu.

img.gaussian(1)                                   # pre-smooth
img.find_edges(image.EDGE_CANNY, threshold=(50, 100))

Detektor Canny je lepší volbou téměř pro každou aplikaci, kde na hranách záleží. Rychlejší EDGE_SIMPLE stojí za zapamatování pro případy, kdy jsou náklady na Canny problémem a potlačení šumu jeho hysterezí ve skutečnosti není potřeba.

5.14.5. Adaptivní prahování na Gaussově filtru

Stejně jako statistické filtry přijímá gaussian() dvojici klíčových slov threshold=True / offset=N pro adaptivní prahování. Chování je stejné jako u mean(): Gaussova statistika v každé pozici se stává lokální mezí a zdrojový pixel je porovnán se statistikou plus offsetem, čímž vznikne binární výsledek.

Gaussova varianta je obvykle nejčistší volbou pro adaptivní prahování, když je vstup přiměřeně bez šumu. Vážený průměr dává hladší mez, než produkuje průměrovací filtr, s menším počtem artefaktů na prudkých přechodech osvětlení.