5.10. Operacje bitowe

Operacje arytmetyczne z poprzedniej strony działają na wartościach pikseli – całkowitych jasnościach lub upakowanych słowach koloru. Operacje bitowe działają o jeden poziom niżej, na poszczególnych bitach wewnątrz tych wartości. Dla obrazów binarnych, gdzie każdy piksel to tylko jeden bit, operacje bitowe są naturalną arytmetyką.

5.10.1. Rodzina operacji bitowych

Klasa Image udostępnia pełny zestaw dwuwejściowych operacji bitowych:

Każda działa bit po bicie na każdym bajcie buforów obu obrazów. Na obrazie binarnym, gdzie każdy bajt przechowuje osiem pikseli, operacja wykonuje się na ośmiu pikselach na każdy przetwarzany bajt. Na obrazie w skali szarości lub kolorowym działa na każdym bicie każdego kanału.

Trzy tablice prawdy dla operacji AND, OR oraz XOR obok siebie. Każda tablica ma cztery wiersze dla kombinacji wejściowych 0-0, 0-1, 1-0, 1-1 oraz kolumny oznaczone A, B i wynik. Poniżej tablic prawdy dwa małe obrazy binarne A i B narysowane jako siatki czarnych i białych komórek, z wynikiem ich operacji AND pokazanym po prawej jako siatka, która zachowuje tylko te komórki, które były białe w obu.

Góra: tablice prawdy AND, OR i XOR – semantyka każdej operacji na poziomie bitów. Dół: dwa obrazy binarne A i B oraz wynik A.b_and(B), gdzie wynik zachowuje tylko te pozycje, które były włączone w obu danych wejściowych.

5.10.2. Łączenie masek

Najczęstszym pojedynczym zastosowaniem tych operacji jest łączenie masek. Maska to obraz binarny, który mówi, pozycja po pozycji, czy spełniony jest pewien warunek. Dwie maski opisujące różne warunki łączą się w pojedynczą maskę opisującą warunek złożony za pomocą jednej z operacji bitowych:

b_and() tworzy maskę, której pozycje są włączone tylko wtedy, gdy obie maski wejściowe były włączone na danej pozycji – naturalne „i” dwóch warunków. Połączenie maski pierwszego planu z wyjściem przebiegu progowania przez b_and ogranicza dopasowania progu do pierwszego planu.

b_or() tworzy maskę, której pozycje są włączone, ilekroć którakolwiek z masek wejściowych była włączona – naturalne „lub”. Operacja OR na dwóch progowanych wyjściach tworzy pojedynczą maskę obejmującą wszystko, co pasowało do któregokolwiek z dwóch zakresów koloru.

b_xor() tworzy maskę, której pozycje są włączone, ilekroć dokładnie jedna maska wejściowa była włączona. Przydatne do wykrywania pozycji, gdzie dwie maski się różnią – pozycji, gdzie wyjście progowania zmieniło się między dwiema ramkami, różnicy symetrycznej między dwiema maskami referencyjnymi, tego rodzaju rzeczy.

Warianty zanegowane – b_nand(), b_nor(), b_xnor() – tworzą dopełnienie swoich niezanegowanych odpowiedników. Są przydatne, gdy naturalnym sposobem opisania warunku jest „żadne z tych” lub „nie oba” – niezbyt często, ale warto wiedzieć, że istnieją, aby negacji nie trzeba było składać przez następujący po AND osobny invert().

5.10.3. Operacje bitowe na obrazach niebinarnych

Operacje bitowe działają również na obrazach w skali szarości i kolorowych. Są tam najbardziej przydatne, gdy obraz przechowuje treść przypominającą binarną – ramkę w skali szarości, której piksele są wszystkie 0 lub 255, ramkę RGB565 z wyłącznie całkowicie czarnymi i całkowicie białymi pikselami – gdzie AND, OR i XOR dają te same kombinacje, jakie dałyby na prawdziwym obrazie binarnym. Dla obrazów obejmujących pełny zakres wartości operacje arytmetyczne z poprzedniej strony zwykle pasują lepiej.