0

I am trying to implement Floyd-Steinberg dithering in Python after using KMeans. I realised, that after dithering I receive colours which are not included in the reduced palette, so I modify the image again with KMeans. However, when trying with this picture, I see no dithering at all. I got stucked, I got tired - please, help me. My ideas become almost extinct.

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

k = 16

im = Image.open('Image.png').convert('RGB') #Image converted to RGB
pic = np.array(im, dtype = np.float)/255 #Enables imshow()
im.close()

def kmeans(pic): #Prepares algorithmic data
    v, c, s = pic.shape
    repic = np.resize(pic, (c*v, 3))

    kme = KMeans(n_clusters = k).fit(repic)
    cl = kme.cluster_centers_

    return kme, cl, repic, v, c

kme, cl, repic, v, c = kmeans(pic)
pred = kme.predict(repic)

def picture(v, c, cl, pred): #Creates a picture with reduced colors
    image = np.ones((v, c, 3))
    ind = 0
    for i in range(v):
        for j in range(c):
            image[i][j] = cl[pred[ind]]
            ind+=1
    return image

image = picture(v, c, cl, pred)

def dither(pic, image): #Floyd-Steinberg dithering
    v, c, s = pic.shape
    Floyd = np.copy(image)
    for i in range(1, v-1):
        for j in range(1, c-1):
            quan = pic[i][j] - image[i][j]
            Floyd[i][j + 1] = quan * (np.float(7 / 16)) + pic[i][j + 1]
            Floyd[i + 1][j - 1] = quan * (np.float(5 / 16)) + pic[i + 1][j - 1]
            Floyd[i + 1][j] = quan * (np.float(3 / 16)) + pic[i + 1][j]
            Floyd[i + 1][j + 1] = quan * (np.float(1 / 16)) + pic[i + 1][j + 1]
    return Floyd

fld = dither(pic, image)
a1, a2, reim, a3, a4 = kmeans(fld)
lab = kme.predict(reim)
Floyd = picture(v, c, cl, lab)

plt.imshow(Floyd)
plt.show()
fgh
  • 169
  • 1
  • 3
  • 15
  • Maybe the KMeans reduces the dithering effect. Did the Floyd-Steinberg dithering with the additional colours look dithered? – NoDataDumpNoContribution Apr 26 '19 at 11:14
  • No characteristic spots for dithering - only sharp bands of color. – fgh Apr 26 '19 at 11:43
  • So maybe the Floyd-Steinberg did not work? – NoDataDumpNoContribution Apr 26 '19 at 11:45
  • I suppose so, however, I can't see the weak point of my implementation. – fgh Apr 26 '19 at 11:58
  • [https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering] _The diffusion coefficients have the property that if the original pixel values are exactly halfway in between the nearest available colors, the dithered result is a checkerboard pattern._ In K-Means the distances are not so obvious. How can we deal with them? Maybe that is the problem? Do we need to handle `KMeans.inertia_`? – fgh Apr 26 '19 at 12:41
  • There is also a problem in `Floyd[sth][sth] = quan*(sth)+pic[sth][sth] `. There should have been `Floyd[sth][sth] = quan*(sth)+**Floyd**[sth][sth] `, however, then I receive only reduced colors image. (** **only indicates the change). – fgh Apr 26 '19 at 19:09

0 Answers0