我正在尝试对用KMeans修改的图片实施Floyd-Steinberg抖动:
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
k = 16 #Number of clusters
im = Image.open(sss).convert('RGB')
pic = np.array(im, dtype = np.float)/255 #Validating the image for imshow()
im.close()
def kmeans(pic): #Creates the image with reduced colors
v, c, s = pic.shape
repic = np.resize(pic, (c*v, 3))
kme = KMeans(n_clusters = k).fit(repic) #Runs the algorithm
cl = kme.cluster_centers_ #Centroids
pred = kme.predict(repic) #The vector with the number of clusters to which are assigned the following pixels
img = np.ones((v, c, 3))
ind = 0
for i in range(v): #Creates the processed image
for j in range(c):
img[i][j] = cl[pred[ind]]
ind+=1
return img
img = image(pic) #The processed image
def dithering(pic, img): #Floyd-Steinberg dithering
v, c, s = pic.shape
Floyd = np.copy(img)
for i in range(1, v-1):
for j in range(1, c-1):
quan = img[i][j] - pic[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
Floyd = dithering(pic, img) #The dithered image
plt.imshow(Floyd)
plt.show()
但是,当我们走向plt.imshow()时,尽管PyCharm指示了错误,但仍显示了图片:
Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
实际上,可能会回答以下问题:
plt.imshow((Floyd*255).astype(np.uint8))
plt.show()
但是,在图片中,我可以看到一些意想不到的颜色,这些颜色似乎使聚类的工作变得混乱。
1)如何检查像素是否属于调色板?我在想:
Steinberg = Floyd*255
def to_be(St, img):
v, c, s = img.shape
for i in range(v):
for j in range(c):
if St[i][j] in palette: #Can be assigned to a cluster, does not exceed the palette
continue #Doesn't change if the pixel belongs to the palette
else:
St[i][j] = img[i][j] #Swaps the pixel with the pixel of the KMean-processed image
proper = to_be(Steinberg, img)
plt.imshow(proper)
plt.show()
2)如何显示图像而不刺激显示和改变颜色?
3)抖动是否正确?对于没有抖动的色彩减少的图像,我没有这样的问题。当我使用时:
Image.fromarray((img*255).astype('uint8')).save('Image.png')
我在保存的图片中没有发现颜色变化。此外,我对抖动图片中的扩散程度不满意。