使用 OpenCV 和 PaddleOCR 图像中的文本倾斜自动纠正
发布时间:2025-06-24 16:45:40 作者:北方职教升学中心 阅读量:206
前言 。
日常工作,我们经常需要从扫描的文档图片中提取文本数据,并将Excel和文本文件转换为标准格式。但是,因为有些图片来自扫描仪,它们往往有不同程度的倾斜,这严重影响了文本识别的准确性和后续处理的效率。虽然传统的图像处理方法有很多,但往往很难达到理想的矫正效果。
面对这个挑战,我的灵光一现想到了使用 PaddleOCR 识别图片中的文本位置,其返回结果包括文本的四个角,这使得计算文本的倾斜角度成为可能。有了这些角度信息我可以使用 OpenCV 准确的图像旋转,纠正文本的倾斜。实践证明这种方法不仅提高了文本识别的准确性,整个文件处理过程也得到了极大的优化。
完整代码。
import mathimport osimport cv2import numpy as npimport paddlehub as hubdef calculate_angle(point1, point2): """ 计算由两点组成的斜线和水平线之间的夹角。 参数: point1 (list): 坐标的第一点 [x1, y1] point2 (list): 坐标的第二点 [x2, y2] 返回: float: 两点之间的角度,第二点表示第一点上方,负值表示在下面。 """ # 计算水平和垂直距离 dx = point2[0] - point1[0] dy = point2[1] - point1[1] # 使用atan2计算角度(返回值为弧度) angle_rad = math.atan2(dy, dx) # 将弧度转换为度 angle_deg = math.degrees(angle_rad) # 根据y坐标判断是返回正角还是负角 if dy < 0: # 第二点低于第一点 return -abs(angle_deg) else: # 第二点在第一点或同一水平线上方 return abs(angle_deg)def rotate_image_without_cropping(img, angle, scale=1.0): (h, w) = img.shape[:2] center = (w // 2, h // 2) # xff08计算旋转矩阵;考虑不裁剪) M = cv2.getrotationMatrix2D(center, angle, scale) # 计算旋转后图像的新边界 cos = np.abs(M[0, 0]) sin = np.abs(M[0, 1]) # 新的边界尺寸 nW = int((h * sin) + (w * cos)) nH = int((h * cos) + (w * sin)) # 考虑平移旋转矩阵的调整 M[0, 2] += (nW / 2) - center[0] M[1, 2] += (nH / 2) - center[1] # 旋转整个图像 rotated = cv2.warpAffine(img, M, (nW, nH)) return rotateddef rotate_image(img, angle): # 获取图像维度和中心点 (h, w) = img.shape[:2] center = (w // 2, h // 2) # 计算旋转矩阵 M = cv2.getrotationMatrix2D(center, angle, 1.0) # 旋转中心旋转角度缩放因子 # 执行旋转 rotated_img = cv2.warpAffine(img, M, (w, h)) return rotated_imgif __name__=="__main__": # 图片所在文件夹的路径 folder_path = r'.\img' # Mkldnn加速仅在CPU下有效 引入ocr深度学习模型 ocr = hub.Module(name="ch_pp-ocrv3", enable_mkldnn=True) offset = 0 # 遍历文件夹中的所有文件 for filename in os.listdir(folder_path): if filename.endswith('.jpg') or filename.endswith('.png'): # 打开图片文件 image_path = os.path.join(folder_path, filename) img = cv2.imread(image_path) # 获取图片宽度和高度 height, width, = img.shape[:2] #识别文字 results = ocr.recognize_text(images=[img]) angleTotal=0 angleNum = 0 # img_rect=img for result in results: data = result['data'] angleNum=len(data) for infomation in data: # img_rect=cv2.rectangle(img_rect,infomation['text_box_position'][0],infomation['text_box_position'](255,0,0),2) angleTotal+=calculate_angle(infomation['text_box_position'][0],infomation['text_box_position'][1]) # angleTotal+=calculate_angle(infomation['text_box_position'][2],infomation['text_box_position'][3]) # print(infomation['text_box_position'][0][0],infomation['text_box_position'][1][0]) angle=angleTotal/(angleNum) img=rotate_image(img,angle) # cv2.imwrite(r"./rect/" +filename, img_rect) cv2.imwrite(r"./rotate/" +filename, img) print(angle) print(image_path)。
效果。
效果。
以下是旋转前后对比,效果我还是很满意的。
总结。
通过结合 PaddleOCR 高效文本检测功能及 OpenCV 图像处理能力强,该方法有效地解决了扫描图像文本倾斜的问题。这不仅使从图像到文本的转换更加高效准确,它还大大提高了后续数据处理的流畅性。在实际应用中c;该技术具有优异的性能和广泛的适用性,它为类似的图像处理任务提供了可靠的解决方案。
希望这个博客能激励更多的同行面对图像处理挑战,采用创新的解决方案。对于想要深入了解和应用这些技术的朋友,我建议亲自实验不同类型的图像样本,为了获得更全面的经验和理解,转载请附明出处。