Some examples of dithering

In the following examples, c is the number of tones of gray allowed in dithering.

First of all, let us see the need of dithering. Consider for instance the following Matlab/Octave program that draws a spherical gradient and quantize it:
N = 400;
[X,Y]=meshgrid( linspace(-1,1.01,N), linspace(-1,1.01,N) );
Z = 0.99*sqrt( max(1-(X.^2+Y.^2),0) );
I = mat2gray(Z);
imwrite(I, 'gradient.png')

c = 14
A = floor( c*Z );
I = mat2gray(A);
imwrite(I, 'output.png')

The gradient is:
and the corresponding quantized images for c=6 and c=14 gray tones are quite deffective:
ndith6 ndith14
c = 6
c = 14

The most pedestrian way of performing dithering is to apply a random noise before quantization. These are the results with uniformly distributed noise at each pixel:
gdith2 gdith6
c = 2
c = 6

gdith10 gdith14
c = 10
c = 14

Now we consider the following photo (500x500) as input to appreciate finer details:
We work with the B/W version.

In ordered dithering, Bayer matrices are employed instead of random noise to assure the differences of near pixels in the middle tones. The Bayer matrices for dimension 2k, say Mk, follow a simple recurrence. Starting by M0=(0), the first block 2k-1x2k-1 is Mk-1, the second (to the right) is Mk-1 + 2·2-2k, the third is Mk-1 + 3·2-2k and the fourth Mk-1 + 2-2k.

These are examples with c=4 taking M2 and M4. The last one is very common in practice.
dim = 4, c = 4
dim = 16, c = 4

Finally, these are some examples with diffusion dithering, namely with Floyd-Steinberg algorithm. It distributes the quantization error among the neighboring pixels with a simple formula. The results are nevertheless impressive, especially taking into account how easy is to code it.

c = 2
c = 4

dif_dith2 dif_dith8
c = 6
c = 8

For more examples and theory on dithering see