如何精准检测边界框/目标旁的微倾斜文本?
需求与问题
- 目标:提取选中选项(检测到的边界框)旁的文本,需处理因文档折叠或拍摄角度导致的文本上下倾斜问题。
- 当前方法:基于边界框(x,y,w,h)裁剪原始图片后执行OCR,多数场景有效,但某示例中出现文本被裁切的情况。
- 具体需求:提取第7题(C)的完整文本,预期输出:
Provides facilities for disk checking, error logging,
- 当前使用代码:
import cv2 import pytesseract bbx=([[144, 1965, 47, 43]]) #list of bounding boxes thresh = 255 - cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] for i in range(len(bbx)): x,y,w,h = bbx[i][:4] x,y,w,h = x+w+4,y,1000,h ROI = thresh[y:y+h,x:x+w] text = pytesseract.image_to_string(ROI, lang='eng',config='--oem 3 --psm 6') print(text) cv2.imshow(ROI)
解决方案
- 解决文本裁切问题:当前代码固定ROI宽度为1000,若文本超出该范围就会被裁切。需扩大裁剪区域,或根据实际文本动态调整范围。
- 处理文本倾斜:先对包含目标区域的图像做倾斜校正,再执行OCR,具体步骤如下:
- 从原始图中裁剪包含边界框及周边文本的扩大区域
- 通过轮廓检测计算文本倾斜角度,旋转校正图像
- 校正后再提取文本区域做OCR
优化后的代码示例:
import cv2 import pytesseract import numpy as np def correct_skew(image): # 转灰度图并二值化 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] # 获取文本像素坐标,计算倾斜角度 coords = np.column_stack(np.where(thresh > 0)) angle = cv2.minAreaRect(coords)[-1] # 调整角度至合理范围 if angle < -45: angle = -(90 + angle) else: angle = -angle # 旋转图像校正倾斜 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("original_image.jpg") bbx = [[144, 1965, 47, 43]] # 选中选项的边界框 for x, y, w, h in bbx: # 扩大裁剪范围,避免文本被裁切(可根据实际情况调整偏移量) expand_right = 1500 expand_top = 20 expand_bottom = 20 # 确保裁剪区域不超出图片边界 crop_x = x + w + 4 crop_y = max(0, y - expand_top) crop_w = min(image.shape[1] - crop_x, expand_right) crop_h = min(image.shape[0] - crop_y, h + expand_top + expand_bottom) # 裁剪目标区域 roi = image[crop_y:crop_y+crop_h, crop_x:crop_x+crop_w] # 倾斜校正 corrected_roi = correct_skew(roi) # 二值化处理 thresh_roi = 255 - cv2.threshold(cv2.cvtColor(corrected_roi, cv2.COLOR_BGR2GRAY), 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] # OCR提取文本,使用PSM 7适配单行文本 text = pytesseract.image_to_string(thresh_roi, lang='eng', config='--oem 3 --psm 7') print("提取到的文本:", text.strip()) # 显示结果 cv2.imshow("Corrected ROI", corrected_roi) cv2.waitKey(0) cv2.destroyAllWindows()
- 关键优化说明:
- 取消固定宽度的ROI设置,改为按需扩大裁剪范围,避免文本裁切
- 新增倾斜校正函数,解决文档折叠或拍摄角度导致的文本倾斜问题
- 调整OCR的PSM参数为7,针对单行文本优化识别准确率
内容的提问来源于stack exchange,提问作者saikat
相关产品推荐
相关产品推荐

