如何仅对图像白色背景添加dithering抖动噪声且保留文字清晰度
现有代码问题
- 处理顺序错误:先对全图做抖动再强制替换高亮像素为固定灰度值,最终输出的背景是无颗粒的纯灰色,完全丢失dithering效果
- 无前景保护逻辑:单阈值直接改像素会把文字边缘的抗锯齿浅灰像素误判为背景,导致文字边缘发糊、清晰度下降
- 缺少区域控制逻辑,无法实现半页区域单独替换背景的需求
可行实现方案
按以下流程处理即可在不损失文字清晰度的前提下得到目标效果:
- 前景背景分离:将原图转灰度后,通过阈值筛选出纯白背景区域生成二值遮罩(mask),遮罩覆盖区域为待替换的背景,其余区域全程保留原图像素不做修改
- 区域范围控制:如果需要半页替换,直接对遮罩做坐标裁剪,仅保留目标半页范围内的遮罩生效区即可
- 单独生成抖动背景:单独创建和原图尺寸一致的画布,填充目标灰度值后单独施加dithering效果,通过参数控制抖动颗粒的反差强度,避免颗粒过杂干扰文字
- 遮罩合成:以生成的遮罩为依据,仅在背景区域替换为提前生成的抖动背景层,文字、非背景区域完全保留原图内容
修正后代码
import os import numpy as np from PIL import Image # 路径配置,已修正原代码路径中混入的无效字符 ORIGIN_PATH = "/home/dithering/temp/" DESTIN_PATH = "/home/dithering/temp_try/" # 效果参数 BG_THRESHOLD = 250 # 灰度值高于该阈值判定为纯白背景 TARGET_BG_GRAY = 210 # 背景基础灰度值 DITHER_STRENGTH = 12 # 抖动颗粒强度,数值越大颗粒反差越明显 # 半页模式配置 ENABLE_HALF_PAGE = True # 是否开启仅半页替换 HALF_PAGE_SPLIT_RATIO = 0.5 # 横向分割线位置,0.5为页面正中间 HALF_PAGE_PROCESS_UPPER = True # True=处理上半页,False=处理下半页 os.makedirs(DESTIN_PATH, exist_ok=True) for filename in os.listdir(ORIGIN_PATH): # 过滤非图像/PDF文件 if not filename.lower().endswith(('.png', '.jpg', '.jpeg', '.pdf')): continue # 读取文件转灰度 img = Image.open(os.path.join(ORIGIN_PATH, filename)).convert("L") img_np = np.asarray(img).copy() h, w = img_np.shape # 生成背景遮罩 bg_mask = (img_np > BG_THRESHOLD).astype(np.uint8) # 半页模式下裁剪遮罩范围 if ENABLE_HALF_PAGE: split_y = int(h * HALF_PAGE_SPLIT_RATIO) if HALF_PAGE_PROCESS_UPPER: bg_mask[split_y:, :] = 0 else: bg_mask[:split_y, :] = 0 # 生成带Floyd-Steinberg抖动的背景层 base_bg = Image.new("L", (w, h), color=TARGET_BG_GRAY) dither_bg = base_bg.convert("1", dither=Image.Dither.FLOYDSTEINBERG).convert("L") dither_bg_np = np.asarray(dither_bg) # 映射抖动颗粒到目标灰度范围,控制强度 dither_bg_np = np.where( dither_bg_np > 128, TARGET_BG_GRAY + DITHER_STRENGTH, TARGET_BG_GRAY - DITHER_STRENGTH ).astype(np.uint8) # 按遮罩合成最终图像 final_np = np.where( bg_mask == 1, dither_bg_np, img_np ) final_img = Image.fromarray(final_np) # 需要三通道RGB格式可放开下行注释 # final_img = final_img.convert("RGB") final_img.save(os.path.join(DESTIN_PATH, filename))
调优提示
- 直接用PIL读取PDF默认会用72DPI低分辨率渲染,文字会发糊,建议先用
pdf2image库将PDF渲染为300DPI的图像后再走上述处理流程,文字锐度会明显提升 BG_THRESHOLD建议根据素材的白底纯净度在245-252区间调整,数值过高会漏判偏灰的背景,数值过低会误吞文字边缘的抗锯齿像素- 如果觉得Floyd-Steinberg抖动的颗粒太细碎,可以替换为Bayer有序抖动,生成的网点效果更规整,更接近印刷质感
- 抖动强度建议控制在8-15区间,过强的颗粒会干扰模型对文字特征的提取
内容的提问来源于stack exchange,提问作者aarya
相关产品推荐
相关产品推荐

