Пиксели превышающие палитру цветов - PullRequest
0 голосов
/ 25 апреля 2019

Я пытаюсь реализовать сглаживание Флойда-Стейнберга для изображения, измененного с помощью 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')

Я не замечаю какого-либо изменения цвета в сохраненных изображениях.Кроме того, меня не устраивает уровень диффузии на размытом изображении.

...