5.5. Oblasti a masky

Každá operace v modulu image se ve výchozím nastavení dotýká každého pixelu svého zdrojového obrazu. To je nejjednodušší chování, které lze popsat, a správné tehdy, když úkolem algoritmu skutečně je pokrýt celý snímek – rovnoměrná korekce barev, globální histogram, kódovací průchod pro přenos. V praxi však většina algoritmů chce zpracovat méně než to. Sledovač blobů hlídající barevnou značku se zajímá o tu část scény, kde se značka může objevit, nikoli o zeď za ní. Morfologický čisticí průchod je bezpečný pouze nad pixely, které předchozí fáze označila jako kandidáty. Detektor obličejů může běžet jen uvnitř ohraničujícího rámečku, který už zúžil hrubší detektor. Modul image tuto práci podporuje prostřednictvím dvou mechanismů, které omezují operaci na podmnožinu pixelů: pomocí obdélníkových oblastí zájmu a binárních masek. Volně se kombinují a téměř každá metoda, která se dotýká pixelů, přijímá jeden nebo druhý – nebo oba – jako pojmenovaný argument.

5.5.1. Oblasti zájmu

Oblast zájmu je obdélník pixelů pojmenovaný čtveřicí (x, y, w, h) představenou na stránce o souřadnicích. Asi třicet metod v rozhraní přijímá pojmenovaný argument roi; je-li přítomen, operace běží pouze na pixelech uvnitř tohoto obdélníku a zbytek obrazu ponechá nedotčený. Když je roi rovno None nebo je vynecháno, operace běží nad celým obrazem – stejně, jako by bylo předáno roi=(0, 0, width, height).

V kódu se klíčové slovo nachází vedle jakýchkoli dalších argumentů, které operace přijímá:

# Compute a histogram over a centred crop of the image.
h = img.get_histogram(roi=(64, 64, 128, 128))

První věcí, kterou ROI přinášejí, je kontrola falešně pozitivních výsledků. Barevný sledovač, který se dívá pouze na stůl, se nikdy nespustí na košili procházející kolem; detektor hran, který běží jen uvnitř definované pracovní oblasti, nikdy nenahlásí hrany samotného držáku kamery. Zúžení prohledávané oblasti na tu část scény, o kterou se algoritmus skutečně zajímá, je nejlevnější zlepšení spolehlivosti, které může pipeline sama u sebe provést.

Druhou věcí, kterou přinášejí, je pipeline od hrubého k jemnému. Objekty s výsledky detekce – blob, rect, apriltag a tak dále – vystavují své ohraničující rámečky jako tutéž čtveřici (x, y, w, h), kterou přijímá roi. Hrubá první fáze tak může vrátit ohraničující rámeček, ten rovnou poslouží jako roi další fáze a druhá fáze běží nad užší oblastí. Každé postupné zúžení jak zrychluje další fázi, tak činí její výsledky spolehlivějšími, protože prohledávaný prostor už byl odfiltrován.

5.5.2. Binární masky

Obdélník je správná forma, když je oblast zájmu zarovnaná s osami. Když tomu tak není – zakřivená oblast, nekonvexní oblast, pixely, které nějaká dřívější fáze klasifikovala jako „shody“ – operaci je třeba sdělit, aby se omezila místo toho na libovolný vzor pixelů. Mechanismem pro to je binární maska: samostatný objekt Image o stejných rozměrech jako zdroj, používaný jako přepínač zapnuto/vypnuto pro jednotlivé pixely. Nenulový pixel v masce říká „zahrň odpovídající zdrojový pixel“; nulový pixel říká „nech zdrojový pixel být.“

Maska je obvykle obraz BINARY – formát s jedním bitem na pixel, který existuje přesně pro tento účel – ale funguje jakýkoli jednokanálový obraz, protože spotřebitel považuje za zapnutou jakoukoli nenulovou hodnotu.

Metody filtrování, prahování a aritmetiky přijímají pojmenovaný argument mask. Forma je u každé stejná: samostatně alokovaný binární obraz o stejných rozměrech jako zdroj, předaný dále.

ROI a masky se kombinují. Předejte oba a operace poběží pouze na pixelech, které jsou uvnitř ROI a zároveň zapnuté v masce. Tyto dva mechanismy dávají aplikačnímu kódu nezávislé páky – jednu pro obdélníkovou oblast zájmu, druhou pro libovolný vzor uvnitř ní – aniž by kterákoli z forem zdědila omezení od té druhé.

Malá mřížka představující obraz. Přerušovaný obdélník nakreslený přes horní střední část mřížky označuje ROI: uvažují se pouze pixely uvnitř tohoto obdélníku. Uvnitř ROI označuje zhruba kruhová množina vyplněných buněk masku: skutečně se upraví pouze tyto vyplněné buňky. Zbývající buňky jsou lehce zašeděné, aby naznačily, že zůstávají nedotčené.

ROI omezuje operaci na obdélník zarovnaný s osami. Maska ji dále zužuje na libovolný vzor pixelů. Tyto dvě věci se kombinují: upraví se pouze pixely uvnitř ROI a zároveň zapnuté v masce.

5.5.3. Vytváření masek

Tři metody objektu Image vytvářejí běžné geometrie masek na místě tím, že vynulují pixely vně zvolené oblasti:

Každá z nich přijímá (x, y, w, h) (pro obdélník a elipsu) nebo (x, y, radius) (pro kruh). Zavolání kterékoli z nich bez argumentů vycentruje geometrii a nastaví jí velikost tak, aby vyplnila obraz, což je forma, po níž aplikace sahá, když je cílem jednoduchý oval či kruh přes celý obraz, který neskrývá nic kromě rohů.

mask = image.Image(img.width(), img.height(), image.BINARY)
mask.clear()              # start from all zeros
mask.mask_ellipse()       # centred, full-size oval

Zajímavé masky vznikají jen zřídka ze samotných metod mask_*. Pocházejí z dřívějších fází pipeline: prahovací průchod vytvoří binární obraz, jehož nenulové pixely označují shody, což je přesně ta správná forma pro předání argumentu mask= další fáze. Morfologický čisticí průchod tuto masku zpřesní, aniž by změnil její formu. Cokoli, co skončí jako jednokanálový obraz, je samo o sobě platnou maskou.

5.5.4. Jak operace upravují obraz

Vzor viditelný v každém úryvku kódu na posledních několika stránkách – operace vracející tentýž objekt img pro zřetězení – stojí za to explicitně zdůraznit, aby se nemusel znovu uvádět pokaždé, když je představena nová metoda. V rozhraní Image se objevují tři rodiny metod, z nichž každá zachází se zdrojovým obrazem odlišně:

  • Operující metody upravují pixely zdroje na místě a vracejí tentýž obraz pro zřetězení. Takto se chovají rodiny kreslení, aritmetiky, prahování i filtrů. img.gaussian(1) rozmaže img a vrátí tentýž img; opětovné přiřazení – img = img.gaussian(1) – je neškodné, ale zbytečné.

  • Konverzní metody ve výchozím nastavení pracují na místě stejně jako operující metody, ale přijímají copy=True a copy_to_fb=True k alokaci samostatného výsledného obrazu, když je třeba zdroj zachovat. Hlavními členy této rodiny jsou konverze formátů a geometrické kopie.

  • Inspekční metody čtou pixely a vracejí objekt s výsledkem – seznam detekovaných příznaků, histogram, sadu statistik – aniž by zdrojový obraz jakkoli upravovaly.

Toto rozdělení do tří skupin je konzistentní napříč celým rozhraním. Vědět, do které rodiny metoda patří, říká aplikaci, co od volání očekávat: zda pixely zdroje zůstanou neporušené, zda bude alokován samostatný výsledný obraz a zda je návratovou hodnotou samotný zdroj, nebo něco jiného.