5.5. Területek és maszkok¶
Az image modul minden művelete alapértelmezés szerint a forráskép minden képpontját érinti. Ez a legegyszerűbben leírható viselkedés, és akkor a megfelelő, amikor az algoritmus feladata valóban a teljes képkockára terjed ki – egyenletes színkorrekció, globális hisztogram vagy egy átvitelre szánt kódolási menet. A gyakorlatban azonban a legtöbb algoritmus ennél kevesebbet szeretne megvizsgálni. Egy színes jelölőt figyelő foltkövető a jelenetnek azt a részét tekinti fontosnak, ahol a jelölő megjelenhet, nem pedig a mögötte lévő falat. Egy morfológiai tisztító menet csak azokon a képpontokon biztonságos, amelyeket egy korábbi szakasz jelöltként jelölt meg. Egy arcdetektor csak azon a határoló dobozon belül futhat, amelyet egy durvább detektor már leszűkített. Az image modul két mechanizmussal támogatja ezt a munkát, amelyek egy műveletet a képpontok egy részhalmazára szűkítenek: téglalap alakú érdeklődési területekkel és bináris maszkokkal. Ezek szabadon kombinálhatók, és szinte minden képpontokat érintő metódus elfogadja az egyiket vagy a másikat – vagy mindkettőt – kulcsszó argumentumként.
5.5.1. Érdeklődési területek¶
Az érdeklődési terület képpontok téglalapja, amelyet a koordináták oldalon bemutatott (x, y, w, h) négyes nevez meg. A felületen körülbelül harminc metódus fogad el egy roi kulcsszó argumentumot; ha jelen van, a művelet csak az adott téglalapon belüli képpontokon fut le, a kép többi részét érintetlenül hagyja. Ha a roi értéke None vagy hiányzik, a művelet a teljes képen fut le – ugyanúgy, mintha roi=(0, 0, width, height) lett volna átadva.
A kódban a kulcsszó a művelet bármely más argumentuma mellett szerepel:
# Compute a histogram over a centred crop of the image.
h = img.get_histogram(roi=(64, 64, 128, 128))
Az ROI-k első előnye a téves találatok elleni védelem. Egy színkövető, amely csak az asztalt figyeli, soha nem fog kioldani az elsétáló ingre; egy éldetektor, amely csak a meghatározott munkaterületen belül fut, soha nem fogja jelenteni magának a kameratartónak az éleit. A keresési terület leszűkítése a jelenetnek arra a részére, amely az algoritmust valóban érdekli, a legolcsóbb fejlesztés, amelyet egy feldolgozási lánc a saját megbízhatóságán végezhet.
A második előny a durvától finomig haladó feldolgozási lánc. Az észlelési eredményobjektumok – egy blob, egy rect, egy apriltag és így tovább – ugyanazzal a (x, y, w, h) négyessel teszik elérhetővé a határoló dobozaikat, amelyet a roi is elfogad. Így egy durva első szakasz visszaadhat egy határoló dobozt, a doboz közvetlenül a következő szakasz roi paraméterébe kerül, és a második szakasz a szűkebb területen fut le. Minden fokozatos szűkítés egyszerre gyorsítja fel a következő szakaszt, és teszi megbízhatóbbá az eredményeit, mert a keresési teret már megszűrte.
5.5.2. Bináris maszkok¶
A téglalap a megfelelő forma, amikor az érdeklődési terület a tengelyekhez igazodik. Amikor nem – egy görbe vonalú terület, egy nem konvex alakzat, vagy azok a képpontok, amelyeket egy korábbi szakasz „találatként” osztályozott –, akkor a műveletnek meg kell mondani, hogy egy tetszőleges képpontmintázatra szűkítse magát. Ennek mechanizmusa a bináris maszk: egy külön Image, amely a forrással azonos méretű, és képpontonkénti be/ki kapcsolóként használatos. A maszk nem nulla képpontja azt jelenti, hogy „vedd figyelembe a megfelelő forrásképpontot”; a nulla képpont azt jelenti, hogy „hagyd békén a forrásképpontot”.
A maszk általában egy BINARY kép – a képpontonként egy bites formátum, amely pontosan erre a célra létezik –, de bármely egycsatornás kép működni fog, mert a felhasználó minden nem nulla értéket bekapcsoltként kezel.
A szűrő, küszöbölő és aritmetikai metódusok elfogadnak egy mask kulcsszó argumentumot. A forma mindegyiknél azonos: egy külön lefoglalt, a forrással azonos méretű bináris kép, amelyet átadunk.
Az ROI-k és a maszkok kombinálódnak. Add át mindkettőt, és a művelet csak azokon a képpontokon fut le, amelyek az ROI-n belül vannak és be vannak kapcsolva a maszkban. A két mechanizmus független vezérlőkart ad az alkalmazás kódjának – egyet a téglalap alakú érdeklődési területhez, egyet a benne lévő tetszőleges mintázathoz –, anélkül, hogy bármelyik forma örökölné a másik megkötéseit.
Egy ROI egy tengelyekhez igazodó téglalapra korlátozza a műveletet. Egy maszk tovább szűkíti azt egy tetszőleges képpontmintázatra. A kettő kombinálódik: csak az ROI-n belüli és a maszkban bekapcsolt képpontok módosulnak.¶
5.5.3. Maszkok építése¶
Három Image metódus épít fel gyakori maszkgeometriákat helyben azáltal, hogy a kiválasztott területen kívüli képpontokat nullázza:
A
mask_rectangle()megtart egy téglalapot.A
mask_circle()megtart egy kört.A
mask_ellipse()megtart egy ellipszist.
Mindegyik egy (x, y, w, h) (a téglalaphoz és az ellipszishez) vagy egy (x, y, radius) (a körhöz) értéket vesz át. Bármelyikük argumentumok nélküli meghívása középre helyezi a geometriát, és úgy méretezi, hogy kitöltse a képet; ezt a formát akkor használja egy alkalmazás, amikor a cél egy egyszerű, teljes képet kitöltő ovális vagy kör, amely csak a sarkokat takarja el.
mask = image.Image(img.width(), img.height(), image.BINARY)
mask.clear() # start from all zeros
mask.mask_ellipse() # centred, full-size oval
Az érdekes maszkok ritkán származnak önmagukban a mask_* metódusokból. A feldolgozási lánc korábbi szakaszaiból jönnek: egy küszöbölő menet egy olyan bináris képet állít elő, amelynek nem nulla képpontjai jelölik a találatokat, pontosan a megfelelő formát ahhoz, hogy a következő szakasz mask= argumentumába kerüljön. Egy morfológiai tisztító menet finomítja ezt a maszkot a formájának megváltoztatása nélkül. Bármi, ami egycsatornás képként végzi, önmagában érvényes maszk.
5.5.4. Hogyan módosítják a műveletek a képet¶
Az utóbbi néhány oldal minden kódrészletében látható mintázat – a művelet ugyanazt az img objektumot adja vissza a láncoláshoz – érdemes kifejezetten kiemelni, hogy ne kelljen újra meg újra megismételni, valahányszor egy új metódus kerül bemutatásra. Három metóduscsalád jelenik meg az Image felületén, amelyek mindegyike másképp kezeli a forrásképet:
A műveleti metódusok helyben módosítják a forrás képpontjait, és ugyanazt a képet adják vissza a láncoláshoz. A rajzolási, aritmetikai, küszöbölő és szűrő családok mind így viselkednek. Az
img.gaussian(1)elmosja azimgképet, és ugyanazt azimgobjektumot adja vissza; az újraértékadás –img = img.gaussian(1)– ártalmatlan, de szükségtelen.A konverziós metódusok alapértelmezés szerint ugyanúgy helyben működnek, mint a műveleti metódusok, de elfogadják a
copy=Trueéscopy_to_fb=Trueparamétereket, hogy külön eredményképet foglaljanak le, amikor a forrást meg kell őrizni. A formátumkonverziók és a geometriai másolatok ennek a családnak a fő tagjai.A vizsgálati metódusok beolvassák a képpontokat, és egy eredményobjektumot adnak vissza – egy észlelt jellemzők listáját, egy hisztogramot, egy statisztikahalmazt – anélkül, hogy egyáltalán módosítanák a forrásképet.
Ez a hármas felosztás az egész felületen következetes. Annak ismerete, hogy egy metódus melyik családhoz tartozik, megmondja az alkalmazásnak, mire számíthat egy hívástól: vajon a forrás képpontjai épségben maradnak-e, vajon külön eredménykép kerül-e lefoglalásra, és vajon a visszatérési érték maga a forrás vagy valami más.