You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python PIL基于像素颜色提取图像清晰文字 适配OCR识别需求

带波动白字的图像文字提取优化方案

问题背景

  • 核心需求:移除图像内非文字内容,保留清晰完整的文字,输出结果可被任意OCR程序正常识别
  • 现存难点:目标文字为白色,但文字像素RGB值不固定为(255,255,255),单像素数值存在波动,固定RGB阈值无法精准筛选全部文字像素;尝试过RGB转其他色彩空间、百分比阈值等方案,暂未得到可行实现
  • 原有实现缺陷:基于固定RGB上下限的逐像素判断逻辑处理效果不达标,存在文字边缘像素漏判、背景像素误判问题,输出结果无法满足OCR识别要求。原有实现代码如下:
RGB_min=[180,180,180]
RGB_max=[245,245,245]

def level(img):
    copy = img.copy()
    for x in range(img.size[0]):
        for y in range(img.size[1]):
            pxl = list(copy.getpixel((x, y)))
            # if pxl[0] < 220 and pxl[1] < 220: 
            if (pxl[0] < RGB_min[0] and pxl[1] < RGB_min[1]  ) or (pxl[0] > RGB_max[0] or pxl[1] >RGB_max[1]) : 
                pxl[0] = 255
                pxl[1] = 255
                pxl[2] = 255
            else:
                pxl[0] = 0
                pxl[1] = 0
                pxl[2] = 0
                
            copy.putpixel((x, y), tuple(pxl))
    return copy

image = Image.open('1.png')
leveled = level(image)
leveled.save('2.png')

原有代码的核心问题

  • 逐像素遍历效率极低,大尺寸图像处理耗时是OpenCV向量化操作的数十倍
  • 固定RGB区间判断逻辑未考虑白字抗锯齿、半透明叠加的像素特征,既会漏掉边缘的浅灰色文字像素,也会误判背景中接近白色的噪点
  • 没有后处理逻辑,零散噪点、文字边缘缺口会大幅降低OCR识别准确率
  • 输出为白字黑底格式,不符合绝大多数OCR模型的输入偏好,识别率会受影响

优化实现方案

整套逻辑基于HSV色彩空间筛选+自适应二值化+形态学后处理实现,不受RGB数值波动影响,能完整保留文字(包括抗锯齿边缘),输出标准黑字白底的OCR友好格式。

实现步骤

  • 第一步:将图像从RGB空间转换到HSV空间,白色在HSV空间的特征为饱和度极低、明度极高,特征区间非常稳定,不受RGB单通道数值波动影响,可一次性筛出所有白字像素(包括抗锯齿的浅灰边缘)
  • 第二步:使用自适应高斯阈值做二值化,修正图像局部亮度差带来的误判
  • 第三步:通过形态学闭运算修补文字边缘缺口,开运算去除零散的背景噪点
  • 第四步:反转颜色得到黑字白底的标准输出格式

可直接运行的代码

依赖安装:pip install opencv-python pillow numpy

import cv2
import numpy as np
from PIL import Image

def extract_text(input_path, output_path):
    # 读取原始图像
    img = cv2.imread(input_path)
    # 转换到HSV色彩空间
    hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    # 定义白色的HSV区间:覆盖纯白、浅灰白等所有白字相关像素
    lower_white = np.array([0, 0, 170])
    upper_white = np.array([180, 35, 255])
    # 初筛得到文字掩码
    text_mask = cv2.inRange(hsv_img, lower_white, upper_white)
    # 自适应阈值二值化,适配局部亮度差异
    binary_img = cv2.adaptiveThreshold(
        text_mask,
        255,
        cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
        cv2.THRESH_BINARY,
        11,
        2
    )
    # 形态学操作:补文字缺口+去背景噪点
    kernel = np.ones((2, 2), np.uint8)
    binary_img = cv2.morphologyEx(binary_img, cv2.MORPH_CLOSE, kernel)
    binary_img = cv2.morphologyEx(binary_img, cv2.MORPH_OPEN, kernel)
    # 反转得到黑字白底的标准OCR输入格式
    result = 255 - binary_img
    # 保存结果
    Image.fromarray(result).save(output_path)

# 调用示例
extract_text("1.png", "2.png")

参数调整说明

  • 若存在文字漏检、笔画残缺:将lower_white中的明度值(第三个参数)从170逐步下调,最低可到140
  • 若存在背景噪点残留:将upper_white中的饱和度值(第二个参数)从35逐步下调,最低可到15
  • 若文字边缘缺口明显:将形态学卷积核尺寸从(2,2)调整为(3,3)
  • 若需要提取其他颜色的文字,只需要修改HSV区间的上下限即可,整套逻辑通用

内容的提问来源于stack exchange,提问作者art

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 20:33:07