5.12. Progowanie binarne¶
Wiele potoków przetwarzania obrazu sprowadza się do pytania o każdy piksel: czy ta jasność mieści się w zakresie oznaczającym „pierwszy plan”? Czy ten kolor jest na tyle bliski czerwieni, by być znacznikiem, który aplikacja śledzi? Czy ten piksel należy do zbioru kandydatów, na który powinien spojrzeć kolejny etap potoku? Progowanie to operacja, która zamienia te pytania w binarną odpowiedź w każdym położeniu – włączony, jeśli piksel pasuje, wyłączony, jeśli nie – i redukuje cały obraz do maski, na której może pracować reszta potoku.
5.12.1. Metoda binary¶
Metoda binary() przeprowadza tę klasyfikację dla każdego piksela w jednym wywołaniu. Przyjmuje listę zakresów progowych – warunków, które piksel może spełnić, by uznać go za „włączony” – i przepisuje obraz tak, że każdy piksel, który pasował do co najmniej jednego z zakresów, jest ustawiany na maksymalną wartość danego formatu, a każdy, który nie pasował, jest ustawiany na zero. Wynikiem jest maska binarna, której reszta potoku może użyć bezpośrednio.
W najprostszej postaci lista progów ma jeden zakres, a wywołanie zwraca maskę pikseli w tym zakresie:
img.binary([(120, 255)])
To właśnie postać listowa czyni binary potężnym narzędziem. Potok, który chce śledzić dwa kolorowe znaczniki lub zakres jasności wraz z odizolowanym szczytem nasycenia, przekazuje oba zakresy w tej samej liście i otrzymuje jedną maskę wyjściową obejmującą wszystkie dopasowania.
Progowanie zamienia obraz o wartościach ciągłych w maskę binarną: każdy piksel wewnątrz zakresu progowego przyjmuje maksymalną wartość formatu, a każdy poza nim staje się zerem.¶
5.12.2. Krotka dla skali szarości¶
Dla obrazu w skali szarości każdy element listy progów jest dwuelementową krotką (lo, hi) opisującą domknięty zakres jasności. Piksele o wartościach pomiędzy lo a hi (włącznie) pasują; wszystko poza tym zakresem nie pasuje. Naturalne wzorce są proste:
(0, 60)pasuje do ciemnych pikseli – wszystkiego od czerni aż po głęboką szarość.(180, 255)pasuje do jasnych pikseli – wszystkiego od jasnej szarości aż po biel.(100, 160)pasuje do pikseli średnioszarych – pasma w środku zakresu jasności.
Kolejność dwóch wartości wewnątrz krotki nie ma znaczenia; metoda zamienia je wewnętrznie, jeśli lo jest większe niż hi, więc (60, 0) działa tak samo jak (0, 60).
5.12.3. Krotka LAB dla koloru¶
Dla obrazu RGB565 każdy element jest sześcioelementową krotką (l_lo, l_hi, a_lo, a_hi, b_lo, b_hi) opisującą domknięty zakres w przestrzeni kolorów LAB, a nie bezpośrednio w czerwieni, zieleni i niebieskim. Progi to L (jasność), A (oś chromatyczna od zieleni do czerwieni) i B (oś chromatyczna od niebieskiego do żółtego), każdy porównywany z wartością piksela w danym kanale.
Powodem przechodzenia przez LAB zamiast progowania bezpośrednio w RGB jest właściwość, wokół której zaprojektowano przestrzeń kolorów LAB: LAB oddziela jasność od chromy. Dwa piksele pokazujące ten sam kolor, ale o różnych jasnościach, mają różne wartości L, ale w przybliżeniu te same wartości A i B. To rozdzielenie pozwala zakresom progowym opisać kolor przez jego położenie na osiach A i B i pozostawić zakres L szeroko otwarty, aby akceptować ten kolor przy każdej jasności od cienia po podświetlenie. Próg oparty na RGB nie potrafi tego zrobić – każda zmiana oświetlenia przesuwa naraz wszystkie trzy wartości R, G, B, a tracker zbudowany na progach RGB załamuje się przy pierwszym przejściu chmury przed słońcem.
Praktyczny wzorzec: wybierz zakresy A i B opisujące kolor, który aplikacja śledzi, i pozostaw zakres L szeroki – często (0, 100), aby akceptować dowolną jasność – chyba że aplikacja celowo chce progować zarówno jasność, jak i kolor.
W przypadku krotek z mniej niż sześcioma wartościami brakujące składowe domyślnie przyjmują maksymalny zakres (brak ograniczenia na tej osi). Dwuelementowa krotka (l_lo, l_hi) w liście progów RGB565 progowana jest zatem wyłącznie według jasności i pasuje do każdego koloru.
Informacja
Naprawdę szeroko otwarty zakres L ma pewien haczyk na dolnym końcu. Gdy jasność spada w stronę zera, każdy kolor zbiega się do czerni, a wartości A i B zapadają się ku zeru i zaczyna nad nimi dominować szum – przez co ciemne piksele mogą wpłynąć w zakresy A i B i zostać śledzone jako kolor docelowy. Jeśli czarne obszary sceny zaczynają być uznawane za dopasowania, podnoś l_lo, aż wypadną z zakresu.
5.12.4. Flagi¶
Trzy argumenty nazwane kontrolują wynik:
invert=Trueodwraca wynik. Każdy piksel, który by pasował, staje się zerem, a każdy piksel, który by był zerem, przyjmuje maksymalną wartość. Przydatne, gdy naturalnym sposobem opisania pierwszego planu jest to, czym nie jest.zero=Truezmienia tryb działania: pasujące piksele są zerowane, a niepasujące zachowują swoje pierwotne wartości. Użyj tego, gdy celem jest wymazanie pasujących pikseli z obrazu, a nie zredukowanie obrazu do ich maski binarnej.to_bitmap=Truezwraca wynik jako obrazBINARYzamiast nadpisywać istniejący format źródła. Wynik jednobitowy na piksel jest tym, co późniejsze argumenty maski przyjmują bezpośrednio, a konwersja często oszczędza obciążenie pamięci wynikające z noszenia ze sobą maski w pełnym formacie.
Maska i ROI stosują się do tej samej konwencji co reszta interfejsu: prostokąt roi zawęża operację do podobszaru, a obraz mask zawęża ją do dowolnego wzorca położeń.
5.12.5. Domyślnie w miejscu¶
Podobnie jak operacje arytmetyczne, binary domyślnie działa w miejscu: piksele obrazu źródłowego są nadpisywane wynikiem binarnym, a po wywołaniu pierwotne wartości przepadają. Postać to_bitmap=True jest alternatywą, gdy źródło musi zostać zachowane, a wynikiem ma być świeżo przydzielony obraz BINARY. Postać copy=True jest również akceptowana, aby uzyskać wynik w tym samym formacie w nowym buforze.