简介:本文详细介绍如何使用Python与OpenCV实现文字识别,涵盖图像预处理、轮廓检测、字符分割及Tesseract OCR集成,并提供完整代码与优化建议。
OpenCV作为计算机视觉领域的开源库,其图像处理能力为文字识别提供了基础支撑。文字识别的核心流程包括:图像预处理(灰度化、二值化、去噪)、轮廓检测与字符分割、OCR(光学字符识别)引擎解析。相较于直接使用Tesseract OCR,结合OpenCV的预处理能显著提升复杂场景下的识别准确率。
cv2.findContours定位字符区域,结合面积阈值过滤非字符噪声。
pip install opencv-python numpy pytesseract# Windows需下载Tesseract安装包并配置PATH# Linux/macOS: sudo apt install tesseract-ocr # 或brew install tesseract
import cv2import numpy as npdef preprocess_image(img_path):# 读取图像并转为灰度图img = cv2.imread(img_path)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 自适应阈值二值化(优于固定阈值)thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]# 形态学操作:闭合运算修复字符内部空洞kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2)return img, closed
优化说明:
cv2.THRESH_OTSU)根据图像局部亮度自动计算阈值,适用于光照不均场景。MORPH_CLOSE)通过膨胀后腐蚀,连接断裂的字符笔画。
def extract_characters(img, binary_img):# 查找轮廓并筛选有效区域contours, _ = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)char_contours = []for cnt in contours:x,y,w,h = cv2.boundingRect(cnt)aspect_ratio = w / float(h)area = cv2.contourArea(cnt)# 过滤条件:宽高比0.2~1.0,面积>100像素if (0.2 < aspect_ratio < 1.0) and (area > 100):char_contours.append((x, y, w, h))# 按x坐标排序(从左到右)char_contours = sorted(char_contours, key=lambda x: x[0])# 提取ROI并调整大小(Tesseract推荐32x32以上)chars = []for (x,y,w,h) in char_contours:roi = binary_img[y:y+h, x:x+w]roi = cv2.resize(roi, (32,32), interpolation=cv2.INTER_AREA)chars.append((roi, (x,y,w,h)))return chars
关键逻辑:
import pytesseractdef recognize_text(chars, img_path):# 配置Tesseract参数(英文识别,仅识别字母数字)config = r'--oem 3 --psm 6 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'full_text = ""for i, (roi, _) in enumerate(chars):# 保存临时ROI图像(调试用)temp_path = f"temp_{i}.png"cv2.imwrite(temp_path, roi)# 识别单个字符text = pytesseract.image_to_string(roi, config=config)full_text += text.strip()# 识别整图(对比单独字符识别效果)img_text = pytesseract.image_to_string(cv2.imread(img_path),config=r'--oem 3 --psm 6')return full_text, img_text
参数说明:
--oem 3:使用默认OCR引擎模式。--psm 6:假设图像为统一文本块(适用于单行文字)。tessedit_char_whitelist:限制识别字符集,提升准确率。
def main():img_path = "test_text.png"original, binary = preprocess_image(img_path)chars = extract_characters(original, binary)# 可视化轮廓(调试用)debug_img = original.copy()for (x,y,w,h) in [c[1] for c in chars]:cv2.rectangle(debug_img, (x,y), (x+w,y+h), (0,255,0), 2)char_text, img_text = recognize_text(chars, img_path)print("单独字符识别结果:", char_text)print("整图识别结果:", img_text)cv2.imshow("Original", original)cv2.imshow("Binary", binary)cv2.imshow("Debug", debug_img)cv2.waitKey(0)if __name__ == "__main__":main()
chi_sim.traineddata)并放置于tessdata目录。
def pyramid_scale(img, scale=0.8):return cv2.resize(img, (int(img.shape[1]*scale), int(img.shape[0]*scale)))
--psm 7--psm 8--psm 11
# 示例:使用OpenCV的插值放大def super_resolve(img, scale=2):new_h, new_w = int(img.shape[0]*scale), int(img.shape[1]*scale)return cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_CUBIC)
本文通过OpenCV与Tesseract的协同工作,实现了从图像预处理到文字识别的完整流程。实际应用中需注意:
完整代码与测试图像已上传至GitHub(示例链接),读者可下载实践并进一步探索深度学习方案(如CRNN模型)的集成可能性。