如何用PyTesseract精准提取图片中每张卡牌的文本?
卡牌OCR文本提取优化方案
问题说明
当前使用基础OpenCV+Tesseract代码仅能提取图片中少量卡牌文本(如“Spirit of Fire i Suzumebochity”“Momomo”),需通过图像预处理与单卡牌分割优化识别效果。
一、OCR前图像预处理优化
预处理是提升识别率的核心,针对卡牌图像的共性问题,可依次执行以下步骤:
- 灰度化:消除色彩干扰,简化后续处理
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) - 自适应阈值二值化:根据局部区域调整阈值,增强文本与背景对比度,适合明暗不均的卡牌
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) - 降噪处理:用高斯模糊或中值滤波去除图像噪声
blur = cv2.GaussianBlur(thresh, (3,3), 0) - 文本放大:针对小字号文本,通过插值放大提升识别精度
enlarged = cv2.resize(blur, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC) - 倾斜校正:若卡牌存在倾斜,可通过轮廓检测计算旋转角度后校正(需根据实际图像调整逻辑)
二、单张卡牌分割与提取流程
直接识别整张图片会因文本分散导致漏识别,需先分割出每张卡牌再单独处理:
- 边缘检测与轮廓提取:定位卡牌的矩形轮廓
edges = cv2.Canny(gray, 50, 150) contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) - 筛选有效卡牌轮廓:通过面积、宽高比过滤非卡牌轮廓(阈值需根据实际图像调整)
cards = [] for contour in contours: area = cv2.contourArea(contour) if 10000 < area < 100000: # 过滤过小/过大区域 x, y, w, h = cv2.boundingRect(contour) aspect_ratio = w / h if 1.2 < aspect_ratio < 1.8: # 匹配卡牌宽高比 cards.append(im[y:y+h, x:x+w]) - 单卡牌OCR识别:对每张分割后的卡牌单独做预处理,再调用Tesseract识别(需安装对应语言包,如日文包)
for idx, card in enumerate(cards): processed = preprocess_image(card) # 支持英日双语识别,调整psm参数适配文本布局 text = pytesseract.image_to_string(processed, lang='eng+jpn', config='--psm 6') print(f"卡牌 {idx+1} 识别结果:\n{text}\n{'='*50}")
额外优化建议
- 安装Tesseract多语言包(如日文包),覆盖卡牌中的非英文文本
- 调整Tesseract的
--psm参数:比如--psm 6假设文本为单个块,--psm 7适用于单行文本,根据卡牌布局选择 - 对模糊严重的卡牌,尝试形态学膨胀操作增强文本边缘:
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,2)) dilated = cv2.dilate(thresh, kernel, iterations=1)
内容的提问来源于stack exchange,提问作者Andreas Neumaier
相关产品推荐
相关产品推荐

