如何使用Pillow按照指定阈值对图像进行二值化处理?
基于Pillow的PNG图像二值化实现方案
你找到的第二种方法的逻辑说明
你贴的代码是Pillow针对单通道灰度图的二值化实现,各部分含义如下:
Image.point()是Pillow提供的批量像素处理方法,会将传入的函数作用在图像的每一个像素值上,运行效率远高于手动遍历像素threshold = 100是你设定的灰度阈值,取值范围0-255,数值越高,二值化后被判定为白色的区域越少- 匿名函数
lambda p: p > threshold and 255利用了Python的短路求值特性:
当像素值p大于阈值时,p > threshold为真,就会返回and后面的255(对应白色);
当像素值p小于等于阈值时,p > threshold为假,直接返回假值对应的数值0(对应黑色),等价于更易读的写法lambda p: 255 if p > threshold else 0
注意:该方法仅对灰度图的单通道值做判断,如果直接用于RGB彩图,会分别处理三个通道,无法满足你「RGB任意通道小于阈值就转为黑色」的需求。
符合你的规则的高效实现方案
你的需求是只要RGB三个通道的任意一个值≤阈值t,就将像素设为黑色,否则设为白色,以下两种方案都可以高效实现,不需要手动遍历像素:
方案1:搭配numpy实现(效率最高)
from PIL import Image import numpy as np # 可根据实际效果调整阈值 threshold = 100 # 读取图像并转为RGB模式,自动丢弃透明通道 img = Image.open("convert_image.png").convert("RGB") # 转为numpy数组做批量向量运算 img_arr = np.array(img) # 标记三个通道值都大于阈值的位置 all_channel_over_threshold = (img_arr > threshold).all(axis=-1) # 赋值:不满足条件的设为黑色,满足的设为白色 img_arr[~all_channel_over_threshold] = [0, 0, 0] img_arr[all_channel_over_threshold] = [255, 255, 255] # 转回PIL图像并保存 binary_img = Image.fromarray(img_arr) binary_img.save("binary_output.png")
方案2:仅用Pillow原生接口实现(无需额外依赖)
from PIL import Image, ImageChops threshold = 100 img = Image.open("convert_image.png").convert("RGB") # 拆分RGB三个通道 r, g, b = img.split() # 分别对三个通道做二值化判断 mask_r = r.point(lambda x: 255 if x > threshold else 0) mask_g = g.point(lambda x: 255 if x > threshold else 0) mask_b = b.point(lambda x: 255 if x > threshold else 0) # 取三个通道的交集:只有三个通道都大于阈值的位置才保留为白色 final_mask = ImageChops.logical_and(ImageChops.logical_and(mask_r, mask_g), mask_b) # 生成最终二值图 binary_img = Image.new("1", img.size, 0) binary_img.paste(255, mask=final_mask) binary_img.save("binary_output.png")
两种方案都可以处理浅黄色这类浅色区域,不会出现第一种convert('1')方法的抖动问题,完全匹配你要求的判断规则。
内容的提问来源于stack exchange,提问作者Neil
相关产品推荐
相关产品推荐

