我使用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时,我会感到些许抖动。但是,这是不正确的代码!另外,我必须处理聚类中的颜色,因此我再次评估聚类中的新像素。我该如何运作?这个关键错误在哪里?
答案 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)