Blogs/Image Dithering

Image Dithering

mesakarghm Oct 15 2021 1 min read 197 views
Computer Vision
Image Dithering.jpeg

Image Dithering is a process of adding some noise to an image. This noise can be used to randomize the quantization error. Dithering is an image processing technique which can be used to create the illusion of color depth on systems with a limited color palette. It introduces noise or a pattern into an image, and often these patterns are visible. 

Error diffusion dithering is a process of image dithering using error diffusion, in which the quantization error of the current pixel is added to the pixel on the right and below according to a predefined formula. The error diffusion dithering algorithm can be written as: 

  1. For each point in image, find the closest color available (for grayscale images, this is just a thresholding operation).
  2. Calculate the difference between the value in the image and the color you have.
  3. Now divide up these error values and distribute them over the neighboring pixels which you have not visited yet. 
  4. When you get to these later pixels, just add the errors distributed from the earlier pixels, clip the values to the allowed range if needed, and then repeat.

Here, I provide an implementation for the Jarvis Judice Ninke dithering algorithm in a grayscale image. The figures provided show the effect on image before and after applying the dithering algorithm. 

Before dithering:

Image Dithering

After dithering:

Image Dithering

 

Learn and practice this concept here: 

https://mlpro.io/problems/error-diffusion-dithering-jarvis/

def error_diffusion_dithering(image):
    h,w = image.shape 
    ni = []
    while len(ni)<h: 
        ni.append([])
        while(len(ni[-1]) < w): 
            ni[-1].append(0)
    diff_map = (
        (1, 0, 7 / 48),
        (2, 0, 5 / 48),
        (-2, 1, 3 / 48),
        (-1, 1, 5 / 48),
        (0, 1, 7 / 48),
        (1, 1, 5 / 48),
        (2, 1, 3 / 48),
        (-2, 2, 1 / 48),
        (-1, 2, 3 / 48),
        (0, 2, 5 / 48),
        (1, 2, 3 / 48),
        (2, 2, 1 / 48),
    )

    for y in range(len(ni[0])):
        for x in range(len(ni)):
            old_pixel = image[y][x]
            if old_pixel < 0 : 
                old_pixel = 0 
            elif old_pixel > 255: 
                old_pixel = 255

            if old_pixel<127:
                new_pixel=0
            else:
                new_pixel=255            
            quantization_error = old_pixel - new_pixel
            ni[y][x] = new_pixel
            for dx, dy, diffusion_coefficient in diff_map:
                xn, yn = x + dx, y + dy
                if (0 <= xn < h) and (0 <= yn < w):
                    ni[yn][xn] += quantization_error * diffusion_coefficient
    return np.array(ni, "uint8")