在非常浅的灰色上使用image = image.convert("1")
时,它将添加少量黑色像素以将其“平均化”。我正在寻找一种只看每个像素并确定该像素接近黑色还是白色的东西。
答案 0 :(得分:1)
请注意PIL.Image.convert
上的文档:
将灰度(“ L”)或“ RGB”图像转换为双级(模式“ 1”)图像的默认方法是使用Floyd-Steinberg抖动来近似原始图像的亮度水平。如果dither为NONE,则将所有大于128的值设置为255(白色),将所有其他值设置为0(黑色)。要使用其他阈值,请使用
point()
方法。
因此,您实际上不希望抖动,并且在转换时必须显式设置此选项:
from matplotlib import pyplot as plt
import numpy as np
from PIL import Image
# Grayscale image as NumPy array with values from [0 ... 255]
image = np.reshape(np.tile(np.arange(256, dtype=np.uint8), 256), (256, 256))
# PIL grayscale image with values from [0 ... 255]
image_pil = Image.fromarray(image, mode='L')
# PIL grayscale image converted to mode '1' without dithering
image_pil_conv = image_pil.convert('1', dither=Image.NONE)
# Threshold PIL grayscale image using point with threshold 128 (for comparison)
threshold = 128
image_pil_thr = image_pil.point(lambda p: p > threshold and 255)
# Result visualization
plt.figure(1, figsize=(9, 8))
plt.subplot(2, 2, 1), plt.imshow(image, cmap=plt.gray()), plt.ylabel('NumPy array')
plt.subplot(2, 2, 2), plt.imshow(image_pil, cmap=plt.gray()), plt.ylabel('PIL image')
plt.subplot(2, 2, 3), plt.imshow(image_pil_conv, cmap=plt.gray()), plt.ylabel('PIL image converted, no dithering')
plt.subplot(2, 2, 4), plt.imshow(image_pil_thr, cmap=plt.gray()), plt.ylabel('PIL image thresholded')
plt.tight_layout()
plt.show()
文档也不够精确:实际上,convert
和point
的所有大于OR EQUAL 128的值都都设置为白色–这很有意义,因为[0 ... 127]
是128个值,而[128 ... 255]
是128个值。
希望有帮助!