0

I am trying to implement floyd-steinberg dithering algorithm in python but I have problems with the final output and I cant find out what is wrong because it's based on the pseudo-code on wikipedia.

Input

Output

The function to find closest value:

def closest(val): 
    legit = np.array([0, 255])
    vals = np.array([val for i in range(len(legit))])
    diffs = np.abs(vals - legit)
    return legit[np.argmin(diffs)]

And here is the floyd-steinberg implementation:

def floyd(img): 
    img = img.copy()
    height, width = img.shape
    for i in range(height):
        for j in range(width): 
            oldpixel = img[i, j]
            newpixel = closest(oldpixel)
            img[i, j] = newpixel
            quant_error = oldpixel - newpixel

            neighbors_and_weights = [
                (i, j+1, 7.0/16), # right
                (i+1, j-1, 3.0/16), # bottom left
                (i+1, j, 5.0/16), # bottom
                (i+1, j+1, 1.0/16) # bottom right
            ]

            for nw in neighbors_and_weights: 
                x, y, w = nw
                if (0 <= x < height) and (0 <= y < width):
                    img[x][y] += quant_error * w
    return img
SOFUser
  • 89
  • 6
  • 1
    This type of pattern is a known problem with error diffusion dithering. It is not meant to be used on images with such large uniform areas. Adding noise to the input might improve the results. But you’re better off using a patterned dithering. See [here](https://www.crisluengo.net/archives/355) under halftoning and ordered dithering. – Cris Luengo Nov 22 '19 at 15:12
  • @CrisLuengo I have to implement some dithering algorithms and report the differences so I'm not looking for better-performing algorithms. So it's considered normal? And another question: is my `closest()` function valid?? It occurred to me that if I divide by 128 and then multiply with 255, in some cases some invalid outputs may be generated (such as 310=2*255) – SOFUser Nov 22 '19 at 15:22
  • 1
    In the link I gave above I discuss this type of artifacts in error diffusion. Yes, it’s a known problem. I don’t see any issues with your code, but haven’t examined it too carefully either. Make sure you accumulate errors in an array that won’t overflow. – Cris Luengo Nov 22 '19 at 15:27
  • @CrisLuengo GOD I CANNOT BELIEVE THIS. I had the exact same problem (overflow) last week and seems I haven't learnt! THANK YOU! – SOFUser Nov 22 '19 at 15:32

0 Answers0