Dithering zorganizowany wprowadza uporządkowane przesunięcia kolorów, wykorzystując do tego mapami progowania (Threshold map), zwane również macierze indeksowanymi lub macierzami Bayera. Macierze te można w dowolny sposób obracać i odbijać lustrzenie bez zmniejszania skuteczności algorytmu. Poniżej zaprezentowano mapy dla dwóch najmniejszych rozmiarów (współczynniki z przodu są również wyliczane w dalszych wzorach na podstawie rzędu wielkości macierzy \(n\), czyli liczby w oznaczeniu \(M_n\)).

\[ M_1=\begin{bmatrix} 0 & 2 \\ 3 & 1 \end{bmatrix} \]

STOSOWAĆ DOMYŚLNIE M_2

\[ M_2=\begin{bmatrix} 0 & 8 & 2 & 10 \\ 12 & 4 & 14 & 6 \\ 3 & 11 & 1 & 9 \\ 15 & 7 & 13 & 5 \end{bmatrix} \]

\[ M_4=\begin{bmatrix} 0 & 32 & 8 & 40 & 2 & 34 & 10 & 42 \\ 48 & 16 & 56 & 24 & 50 & 18 & 58 & 26 \\ 12 & 44 & 4 & 36 & 14 & 46 & 6 & 38 \\60 & 28 & 52 & 20 & 62 & 30 & 54 & 22 \\ 3 & 35 & 11 & 43 & 1 & 33 & 9 & 41 \\ 51 & 19 & 59 & 27 & 49 & 17 & 57 & 25 \\ 15 & 47 & 7 & 39 & 13 & 45 & 5 & 37 \\ 63 & 31 & 55 & 23 & 61 & 29 & 53 & 21 \end{bmatrix} \]

Mapa progowania będzie służyła nam do zmiany źródłowych właściwości koloru. Dużo łatwiej będzie nam się pracować, jeżeli będziemy operować na wartościach przesunięcia. Dlatego przekształcimy naszą mapę do przestrzeni \(<-0.5,0.5>\), która ułatwi nam dalszą pracę. Wykorzystamy do tego poniższy wzór:

Mpre = (M+1) / (2*n)**2 - 0.5

Przykład obliczeń dla macierzy \(M_1\):

\[ M_{1-pre}=\frac{1}{(2*1)^2} \times (\begin{bmatrix} 0 & 2 \\ 3 & 1 \end{bmatrix}+1) -0.5= \frac{1}{4} \times (\begin{bmatrix} 0 & 2 \\ 3 & 1 \end{bmatrix}+1) -0.5= \begin{bmatrix} -0.25 & 0.25 \\ 0.5 & 0 \end{bmatrix} \]

Teraz potrzebujemy jeszcze funkcję kwantyfikująca, która pozwoli nam dopasować wartości nowych pikseli do naszej palety kolorów colorFit, którą omawialiśmy wcześniej. Sama funkcja wyliczania wartości dla nowych pikseli wygląda tak:

\[ C_n = colorFit(C+r \times (M_{pre}\big[a \mod (2*n),b \mod (2*n)\big]) \]

\(C_n\) jest naszym nowym kolorem piksela, natomiast \(C\) jest kolorem piksela obrazu oryginalnego. Współczynnik \(r\) określa skalowanie koloru pomiędzy oryginalnymi wartościami pikseli a nową paletą. Mamy kilka możliwości, w jaki sposób wyliczyć parametr \(r\):

  1. Jeżeli obie palety są w tym samym zakresie pikseli, parametr będzie wynosił \(r=1\). Zakładamy, że właśnie w tym zakresie się poruszamy, gdy mamy zarówno paletę, jak i obraz w zakresie \(<0,1>\). STOSOWAĆ DOMYŚLNIE TĘ WARTOŚĆ
  2. Wyliczone na podstawie ilości wartości przed i po transformacji \(r\approx \dfrac{\text{ilość wartości przed}}{\text{ilość wartości po}}\) czy z przeliczenia 255 wartości przed i 32 wartości po kwantyzacji wzór będzie się prezentował się mniej więcej tak: \(r\approx\dfrac{255}{32}\approx8\). Nie do końca działa to dla obrazów na float, ale można z tym poeksperymentować.

Cały algorytm powinien składać się z poniższych kroków:

  1. Przygotowujemy tablicę Mpre z wartościami \(<-0.5,0.5>\).
  2. Dla każdego z pikseli naszego obrazu znajdujemy odpowiadający mu piksel w tablicy Mpre. Przykładowo zakładamy, że używamy macierzy M2 o rozmiarze \(4\times4\). Pikselowi obrazu o adresie \((10,13)\), będzie odpowiadała wartość z macierzy Mpre z adresu \((2,1)\), ponieważ \(10 \mod (2*2)=2\) i \(13 \mod (2*2)=1\).
  3. Obliczmy wartość tymczasową naszego piksela dodając do jego wartości wartość z macierzy Mpre pomnożoną przez \(r\).
  4. Na podstawie naszej wartości tymczasowych znajdujemy nowe wartości koloru przy wykorzystaniu funkcji ColorFit.

W jaki sposób generować większe mapy progowania?

Znając najmniejszą macierz \(M_1\) (lub pisząc kod w sposób pozwalający generować już od wartości równej 0) możemy generować większe macierze z założeniem, że każdy kolejny poziom będzie dwukrotnie większy niż poprzedni. Służy do tego poniższy wzór, który możemy wywoływać rekurencyjnie.

\[ M_{2*n}= \begin{bmatrix} (2n)^2 \times M_n & (2n)^2 \times M_n + 2 \\ (2n)^2 \times M_n + 3 & (2n)^2 \times M_n + 1 \end{bmatrix} \]