各位小伙伴,大家好!最近有朋友问我,想用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引擎的选择,我们来看一个实际案例。
案例: 识别一张模糊的手写文字图片。
步骤:
- 预处理: 首先对图片进行灰度化、二值化和去噪处理,增强文字的对比度,减少噪点干扰。
- OCR引擎选择: 由于是手写文字,且图片质量不高,可以选择百度AI OCR或PaddleOCR,它们的识别精度更高,对图片质量要求不高。
- 识别结果: 通过预处理和选择合适的OCR引擎,可以有效提高手写文字的识别率。
四、总结与建议
总而言之,对于低清晰度图片的文字识别,预处理和OCR引擎的选择至关重要。预处理可以改善图片质量,让文字更清晰,更容易被OCR引擎识别。选择合适的OCR引擎,可以充分发挥其识别能力,提高识别率。
建议:
- 根据图片质量选择合适的预处理方法,可以尝试多种预处理方法的组合,找到最佳方案。
- 根据实际需求选择合适的OCR引擎,可以对比不同引擎的识别效果,选择最适合自己的。
- 不断尝试和优化,积累经验,提高文字识别的准确率。
希望这篇文章对你有所帮助!如果有什么问题,欢迎留言交流。