This post is about ordered dithering in Octave. What’s is dithering? You can find a very good explanation here in wikipedia. But briefly, the idea of dithering is to create the illusion of color depth in images with (in our case) only two color quantization. This technique is used in printers, scanners, etc. We print small dots black and leave white spaces and our eyes will do the rest of the job. For those who doesn’t know, our eyes has a low pass filter as frequency response.
The image on the left was generated by using the threshold algorithm. This is the direct way we normally would do, but as we can see the results are not that good. The main problem is that we can’t have a gray scale effect and we lose most of the details of the image. We can barely see the apple in the left corner. The algorithm used is called Ordered dithering and we used a Bayer matrix. Read more about it also here in wikipedia.
The second method we will show is Error Diffusion. The algorithm used is Floyd–Steinberg dithering. The idea is quite simple. We scan the image from top-left to right-bottom. Imagine that we set a gray pixel to white (once we have only two values). We add an error in the new image. We can spread this error to the four pixels which are connected to this pixel (right, bottom-left, bottom, bottom-right). In this way, we try to accumulate the error in order to be able to maintain the average of the brightness of the image. Floyd-Steinberg spreads the error in this way:
right: 7/16
bottom-left: 3/16
bottom: 5/16
bottom-right: 1/16
They chose this distribution because it gave them the most even distribution of textures in the output image with the fewest artifacts. We can notice that this algorithm brings better results.
Below, I put a gray tone scale image with the three methods to compare them closer.
We can notice that in the threshold method we would have to blocks black-white. The small white line was a noise in the original file (which I stole from internet LOL). In ordered dithering we see that we can’t represent high frequency (changes of pixel level by space). Using Floyd-Steinberg give us the best of the three. You can find several others methods, these three are the basic of digital image processing.
Here the source code for both algorithm.
function [image] = bayer(N, img)
bayer4 = [0 8 2 10; 12 4 14 6; 3 11 1 9; 15 7 13 5];
bayer8 = [1 49 13 61 4 52 16 64; 33 17 45 29 36 20 48 32; 9 57 5 53 12 60 8 56; 41 25 37 21 44 28 40 24;
3 51 15 63 2 50 14 62; 35 19 47 31 34 18 46 30; 11 59 7 55 10 58 6 54; 43 27 39 23 42 26 38 22];
if N == 4
bayer_matrix = bayer8;
else
bayer_matrix = bayer8;
end
img_size = size(img);
x_max = img_size(1);
y_max = img_size(2);
for x = 1:x_max,
for y = 1:y_max,
if (img(x,y) + bayer_matrix(mod(x,N) + 1, mod(y,N) + 1)) > 128
image_bayer(x,y) = 255;
else
image_bayer(x,y) = 0;
end
end
end
image = double(image_bayer);
end
function [image] = floyd(img)
img_size = size(img);
x_max = img_size(1);
y_max = img_size(2);
img = double(img);
for x = 1:x_max,
for y = 1:y_max,
% Read pixel value
oldpixel = img(x,y);
% check if more than 50%
if(oldpixel > 128)
newpixel = 255;
else
newpixel = 0;
end
% set pixel value into new image
image_floyd(x,y) = newpixel;
%calculate error
quant_error = double(oldpixel - newpixel);
% check boundaries and accumulate error
if(x + 1 <= x_max)
img(x+1,y) = double((img(x+1,y) + 7/16 * quant_error));
end
if ((x-1 > 0) && (y+1 < y_max))
img(x-1,y+1) = double((img(x-1,y+1) + 3/16 * quant_error));
end
if(y + 1 <= y_max)
img(x,y+1) = double((img(x,y+1) + 5/16 * quant_error));
end
if((x + 1 <= x_max) && (y + 1 <= y_max))
img(x+1,y+1) = double((img(x+1,y+1) + 1/16 * quant_error));
end
end
end
image = image_floyd;
end
Bye
Marcelo





I'm an electronics engineer with 10+ years of experience in embedded system, hardware and firmware development for several 8/16/32 bits microcontrollers like 8051, Microchip, MSP430, Freescale, ARM, etc. I'm a passionate in electronics and embedded systems, but not a nerds! =P


how to get value bayer4, bayer8 ?
Hello,
Actually you could use any matrix. These were defined by Bayer himself.