python-3.x - 有没有办法将图像逐像素转换为黑白?
问题描述
image = image.convert("1")
在非常浅的灰色上使用时,它会添加一些黑色像素来“平均”它。我正在寻找仅查看每个单独像素并确定该像素是更接近黑色还是更接近白色的东西。
解决方案
请注意以下文档PIL.Image.convert
:
将灰度(“L”)或“RGB”图像转换为双电平(模式“1”)图像的默认方法使用 Floyd-Steinberg 抖动来近似原始图像亮度级别。如果抖动为 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()
文档也不精确:实际上,所有大于 OR EQUAL 128 的值都设置为白色,无论是 forconvert
还是 for point
- 这是有道理的,因为[0 ... 127]
是 128 个值,并且[128 ... 255]
是 128 个值。
希望有帮助!