Я пытаюсь реализовать сглаживание Флойда-Стейнберга для изображения, измененного с помощью KMeans:
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) Как я могу отобразить изображение, не раздражая imshow и не меняя цвета?
3) Является ли это правильным дизерингом вообще?У меня нет таких проблем с изображениями уменьшенных цветов без размывания.Когда я использую:
Image.fromarray((img*255).astype('uint8')).save('Image.png')
Я не замечаю какого-либо изменения цвета в сохраненных изображениях.Кроме того, меня не устраивает уровень диффузии на размытом изображении.