【问题标题】:Floyd-Steinberg implementation PythonFloyd-Steinberg 实现 Python
【发布时间】:2019-09-16 09:33:28
【问题描述】:

我使用 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]。但是,这是不正确的代码!此外,我必须处理簇外的颜色,因此我再次将新像素评估为簇。我怎样才能让它工作?这个重大错误在哪里?

【问题讨论】:

  • 什么是image?你是怎么处理的?你对这个过程有一个根本性的误解。您应该只有一个图像:您修改输入灰度值图像,将每个像素设置为 0 或 1,并将与原始值的差异传播到仍要处理的下一个像素。这意味着您的算法应该只从Floyd 读取,而不是从imagepic 读取。而Floyd 应该是原始图像pic 的副本。
  • 感谢您的回答。我设法改进了代码,并希望将其发布为 aswer。但是,由于某些情况,我只能在星期一坐下来。尽管在阅读您的提示之前我已经纠正了错误,但我认为您的评论非常有用。我希望我在三天前读到那些基本的误解,当时我开始与代码进行斗争......

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


【解决方案1】:
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)

【讨论】:

  • 请始终将您的答案放在上下文中,而不仅仅是粘贴代码。有关详细信息,请参阅here
猜你喜欢
  • 2014-10-13
  • 2014-06-01
  • 2021-11-13
  • 1970-01-01
  • 2021-02-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 2011-08-21
相关资源
最近更新 更多