Floyd-Steinberg实现Python

时间:2019-04-26 21:02:23

标签: python-3.x image-processing k-means quantization dithering

我使用Floyd-Steinberg抖动技术来扩散从scipy用KMeans处理的图像后的量化误差。给定的数据是RGB文件-用于灰度和彩色。问题是可视化-我没有抖动。

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

im = Image.open('file.png').convert('RGB')
pic = np.array(im, dtype = np.float)/255
im.close()

我想省略KMeans部分,而只关注Floyd-Steinberg:

"""pic - as above, original array; image - processed image"""

def dither(pic, image):
    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] #Quantization error
            Floyd[i][j + 1] = quan * (np.float(7 / 16)) + Floyd[i][j + 1]
            Floyd[i + 1][j - 1] = quan * (np.float(3 / 16)) + Floyd[i + 1][j - 1]
            Floyd[i + 1][j] = quan * (np.float(5 / 16)) + Floyd[i + 1][j]
            Floyd[i + 1][j + 1] = quan * (np.float(1 / 16)) + Floyd[i + 1][j + 1]
    return Floyd

Floyd = dither(pic, image)

plt.imshow(Floyd)
plt.show()

当我用图片(即Floyd[i + 1][j] = quan * (np.float(5 / 16)) + pic[i + 1][j])替换Floyd时,我会感到些许抖动。但是,这是不正确的代码!另外,我必须处理聚类中的颜色,因此我再次评估聚类中的新像素。我该如何运作?这个关键错误在哪里?

1 个答案:

答案 0 :(得分:0)

from PIL import Image
import cv2
import numpy as np

##################################################### Solution 1 ##############################################################

#PIL.Image.convert parametrs :
#https://pillow.readthedocs.io/en/4.2.x/reference/Image.html?highlight=image.convert#PIL.Image.Image.convert


#PIL.Image.convert Modes :
#https://pillow.readthedocs.io/en/4.2.x/handbook/concepts.html#concept-modes


#image convert to 1-bit pixels, black and white, stored with one pixel per byte and Dithering
imageConvert = Image.open('Image.PNG').convert(mode='1',dither=Image.FLOYDSTEINBERG)
imageConvert.save('DitheringWithPIL.png')


##################################################### Solution 2 ##############################################################


Image = cv2.imread('Image.PNG')

GrayImage = cv2.cvtColor(Image, cv2.COLOR_BGR2GRAY)
cv2.imwrite('GracyImage.PNG', GrayImage)

Height = GrayImage.shape[0]
Width = GrayImage.shape[1]

for y in range(0, Height):
    for x in range(0, Width):

        old_value = GrayImage[y, x]
        new_value = 0
        if (old_value > 128) :
            new_value = 255

        GrayImage[y, x] = new_value

        Error = old_value - new_value

        if (x<Width-1):
            NewNumber = GrayImage[y, x+1] + Error * 7 / 16
            if (NewNumber>255) : NewNumber=255
            elif (NewNumber<0) : NewNumber=0
            GrayImage[y, x+1] = NewNumber

        if (x>0 and y<Height-1):
            NewNumber = GrayImage[y+1, x-1] + Error * 3 / 16
            if (NewNumber>255) : NewNumber=255
            elif (NewNumber<0) : NewNumber=0
            GrayImage[y+1, x-1] = NewNumber

        if (y<Height-1):
            NewNumber= GrayImage[y+1, x] + Error * 5 / 16
            if (NewNumber>255) : NewNumber=255
            elif (NewNumber<0) : NewNumber=0
            GrayImage[y+1, x] = NewNumber

        if (y<Height-1 and x<Width-1):
            NewNumber = GrayImage[y+1, x+1] + Error * 1 / 16
            if (NewNumber>255) : NewNumber=255
            elif (NewNumber<0) : NewNumber=0
            GrayImage[y+1, x+1] = NewNumber

cv2.imwrite('DitheringWithAlgorithm.PNG', GrayImage)