HOOOS

Python低清晰度图片文字识别:预处理与OCR引擎选择指南

0 2 图像处理小能手 PythonOCR图像识别
Apple

各位小伙伴,大家好!最近有朋友问我,想用Python写个脚本自动识别图片里的文字,但是图片质量不太好,清晰度不高,导致识别效果很差,问我有什么办法。

这个问题啊,其实挺常见的。很多时候我们遇到的图片,要么是扫描件,要么是手机拍的,受光线、角度、设备等因素影响,清晰度难免会打折扣。直接用OCR引擎识别,效果肯定不理想。所以,想要提高识别率,预处理和OCR引擎的选择就显得尤为重要了。

一、预处理:让图片“改头换面”

预处理就像是给图片做个“美容”,通过一系列操作,让文字更清晰,更容易被OCR引擎识别。下面介绍几种常用的预处理方法:

1. 灰度化

彩色图片信息量太大,会干扰OCR引擎的识别。将图片转换为灰度图,可以有效减少信息量,突出文字的轮廓。

from PIL import Image

img = Image.open('image.png')
img = img.convert('L') # 转换为灰度图
img.save('gray_image.png')

2. 二值化

二值化就是将灰度图转换为黑白图,进一步简化图片信息,让文字和背景对比更鲜明。常用的二值化方法有阈值法和自适应阈值法。

  • 阈值法: 设定一个阈值,像素值大于阈值的设为白色,小于阈值的设为黑色。

    threshold = 127 # 阈值
    table = []
    for i in range(256):
        if i < threshold:
            table.append(0)
        else:
            table.append(1)
    img = img.point(table, '1') # 二值化
    img.save('threshold_image.png')
    
  • 自适应阈值法: 根据像素周围的灰度值动态计算阈值,更适合光照不均匀的图片。

    from PIL import ImageFilter
    
    img = img.filter(ImageFilter.MedianFilter(size=3))
    bw = img.convert('L').point(lambda x: 0 if x < 100 else 255, '1')
    bw.save('adaptive_threshold_image.png')
    

3. 去噪

图片中可能存在一些噪点,会影响OCR引擎的识别。可以使用一些去噪算法来消除噪点,常用的有中值滤波和高斯滤波。

  • 中值滤波: 用像素周围像素的中值代替该像素的值,可以有效去除椒盐噪声。

    img = img.filter(ImageFilter.MedianFilter(size=3)) # 中值滤波
    img.save('median_filter_image.png')
    
  • 高斯滤波: 用高斯核对图像进行卷积,可以平滑图像,去除高斯噪声。

    img = img.filter(ImageFilter.GaussianBlur(radius=2)) # 高斯滤波
    img.save('gaussian_filter_image.png')
    

4. 倾斜校正

如果图片中的文字倾斜了,会影响OCR引擎的识别。可以使用一些倾斜校正算法来将文字摆正。

import cv2
import numpy as np

def correct_skew(image):
    # 将图像转换为灰度图
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # 使用Canny边缘检测
    edges = cv2.Canny(gray, 50, 150, apertureSize=3)

    # 使用Hough变换检测直线
    lines = cv2.HoughLines(edges, 1, np.pi / 180, 200)

    angle = 0
    if lines is not None:
        for line in lines:
            for rho, theta in line:
                a = np.cos(theta)
                b = np.sin(theta)
                x0 = a * rho
                y0 = b * rho
                x1 = int(x0 + 1000 * (-b))
                y1 = int(y0 + 1000 * (a))
                x2 = int(x0 - 1000 * (-b))
                y2 = int(y0 - 1000 * (a))
                angle = np.degrees(np.arctan2(y2 - y1, x2 - x1))
                break
            break

    # 计算旋转中心
    (h, w) = image.shape[:2]
    center = (w // 2, h // 2)

    # 构建旋转矩阵
    M = cv2.getRotationMatrix2D(center, angle, 1.0)

    # 执行旋转
    rotated = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)

    return rotated

# 读取图像
image = cv2.imread('skewed_image.png')

# 校正倾斜
corrected_image = correct_skew(image)

# 保存结果
cv2.imwrite('corrected_image.png', corrected_image)

5. 调整对比度和亮度

如果图片的对比度和亮度不合适,也会影响OCR引擎的识别。可以通过调整对比度和亮度来改善图片质量。

from PIL import ImageEnhance

# 调整对比度
enhancer = ImageEnhance.Contrast(img)
img = enhancer.enhance(2) # 增强对比度

# 调整亮度
enhancer = ImageEnhance.Brightness(img)
img = enhancer.enhance(1.5) # 增强亮度

img.save('enhanced_image.png')

二、OCR引擎:选择适合自己的“大脑”

OCR引擎就像是识别文字的“大脑”,不同的引擎识别能力不同,对图片质量的要求也不同。下面介绍几种常用的OCR引擎:

1. Tesseract OCR

Tesseract OCR是一款开源的OCR引擎,支持多种语言,识别精度较高。但是,Tesseract OCR对图片质量要求较高,需要进行预处理才能达到较好的识别效果。

import pytesseract
from PIL import Image

# 设置Tesseract OCR的路径
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' # 根据实际安装路径修改

# 打开图片
img = Image.open('enhanced_image.png')

# 使用Tesseract OCR识别文字
text = pytesseract.image_to_string(img, lang='chi_sim') # lang参数指定语言

print(text)

2. Baidu AI OCR

百度AI OCR是百度提供的OCR服务,识别精度很高,支持多种语言,而且对图片质量要求不高。但是,使用百度AI OCR需要先注册百度AI开放平台账号,并获取API Key和Secret Key。

import requests
import base64

# 获取AccessToken
def get_access_token():
    url = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=【API Key】&client_secret=【Secret Key】"
    response = requests.get(url)
    if response:
        return response.json()['access_token']

# 图片转base64
def image_to_base64(image_path):
    with open(image_path, "rb") as f:
        image_data = f.read()
        base64_data = base64.b64encode(image_data)
        return base64_data.decode('utf-8')

# OCR识别
def baidu_ocr(image_path, access_token):
    url = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token=" + access_token
    headers = {"Content-Type": "application/x-www-form-urlencoded"}
    image_data = image_to_base64(image_path)
    data = {"image": image_data}
    response = requests.post(url, headers=headers, data=data)
    if response:
        return response.json()

# 主函数
if __name__ == '__main__':
    access_token = get_access_token()
    image_path = 'image.png'
    result = baidu_ocr(image_path, access_token)
    print(result)

3. PaddleOCR

PaddleOCR是百度开源的OCR工具包,功能强大,支持多种模型,可以进行文本检测、文本识别和版面分析。PaddleOCR也对图片质量要求不高,但是需要安装PaddlePaddle框架。

from paddleocr import PaddleOCR, draw_ocr
from PIL import Image

# 初始化PaddleOCR
ocr = PaddleOCR(use_angle_cls=True, lang='ch') # need to run only once to download and load model into memory

# 打开图片
img_path = 'image.png'
result = ocr.ocr(img_path, cls=True)

# 打印识别结果
for line in result:
    print(line)

# 可视化结果
image = Image.open(img_path).convert('RGB')
boxes = [line[0] for line in result]
txts = [line[1][0] for line in result]
scores = [line[1][1] for line in result]

font_path = 'path/to/your/font.ttf' # 可选,设置字体路径

im = draw_ocr(image, boxes, txts, scores, font_path=font_path)
im.save('result.jpg')

三、案例分析:实战演练

为了更直观地了解预处理和OCR引擎的选择,我们来看一个实际案例。

案例: 识别一张模糊的手写文字图片。

步骤:

  1. 预处理: 首先对图片进行灰度化、二值化和去噪处理,增强文字的对比度,减少噪点干扰。
  2. OCR引擎选择: 由于是手写文字,且图片质量不高,可以选择百度AI OCR或PaddleOCR,它们的识别精度更高,对图片质量要求不高。
  3. 识别结果: 通过预处理和选择合适的OCR引擎,可以有效提高手写文字的识别率。

四、总结与建议

总而言之,对于低清晰度图片的文字识别,预处理和OCR引擎的选择至关重要。预处理可以改善图片质量,让文字更清晰,更容易被OCR引擎识别。选择合适的OCR引擎,可以充分发挥其识别能力,提高识别率。

建议:

  • 根据图片质量选择合适的预处理方法,可以尝试多种预处理方法的组合,找到最佳方案。
  • 根据实际需求选择合适的OCR引擎,可以对比不同引擎的识别效果,选择最适合自己的。
  • 不断尝试和优化,积累经验,提高文字识别的准确率。

希望这篇文章对你有所帮助!如果有什么问题,欢迎留言交流。

点评评价

captcha
健康