使用 OpenCV 和 PaddleOCR 自动纠正图像中的文本倾斜

前言              

        在日常工作中,我们经常需要从扫描的文档图片中提取文本数据,并转换成规范格式的Excel和文本文件。然而,由于部分图片来源于扫描仪,它们往往带有不同程度的倾斜,这严重影响了文本识别的准确性和后续处理的效率。传统的图像处理方法虽多,但常常难以达到理想的矫正效果。

        面对这一挑战,我灵光一现,想到了使用 PaddleOCR 来识别图片中的文本位置,其返回结果包括文本的四个角点,这让计算文本的倾斜角度成为可能。有了这些角度信息,我可以使用 OpenCV 进行精确的图像旋转,以矫正文本的倾斜。实践证明,这种方法不仅提高了文本识别的准确性,也极大地优化了整个文件处理流程。

完整代码

import math
import os
import cv2
import numpy as np
import paddlehub as hub


def 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)
    # 计算旋转矩阵(考虑不裁剪的情况)
    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 rotated

def 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_img

if __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'][2],(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 的强大图像处理能力,本方法有效解决了扫描图像文本倾斜的问题。这不仅使得从图像到文本的转换更加高效、准确,还大大提升了后续数据处理的流畅性。实际应用中,该技术表现出了优越的性能和广泛的适用性,为类似的图像处理任务提供了一个可靠的解决方案。

        希望这篇博客能激发更多同行在面对图像处理挑战时,采用创新的解决方案。对于想要深入了解和应用这些技术的朋友,我建议亲自动手实验不同类型的图像样本,以获得更全面的经验和理解,转载请附明出处。

<think>好的,用户的问题是如何使用Python OCR读取扫描图片中的表格数据,特别是用TesseractPandas。我需要先理清楚整个流程,然后一步步给出解决方案。首先,用户提到了扫描图片中的表格,所以可能涉及图像预处理、OCR识别、表格结构处理导出到Excel这些步骤。 首先,安装必要的库。用户可能已经安装了pytesseractPandas,但还是要提醒安装这些库,以及Pillow来处理图像。另外,Tesseract OCR引擎本身需要单独安装,这点很重要,否则代码会报错。需要告诉用户去下载并安装,并且可能需要添加到系统路径或者指定路径。 接下来是图像预处理。扫描的图片可能有倾斜、噪点或者对比度不足的问题,这些都会影响OCR的准确性。常见的预处理步骤包括灰度转换、二值化、降噪、调整对比度旋转校正。例如,使用PIL的ImageOps来调整对比度,或者用OpenCV进行高斯模糊边缘检测来纠正倾斜。不过如果用户不熟悉OpenCV,可能需要简化步骤,或者给出两种方案:基础预处理高级预处理。 然后是OCR识别部分。使用pytesseract的image_to_string或者image_to_data函数。但表格数据需要识别出文字的位置信息,这样才能还原表格结构。image_to_data可以获取每个识别到的单词的坐标、块、行等信息,这样后续可以分析这些数据来重建表格。这里需要注意lang参数设置为'chi_sim'来识别中文,如果图片中有中英文混合,可能需要添加多个语言包。 接下来处理识别后的数据。将OCR输出的数据转换为DataFrame,然后根据坐标信息将文本分配到对应的单元格中。这一步可能需要计算每个单元格的边界,比如通过聚类确定行列的划分。例如,将所有单词的y坐标进行聚类,确定行高,x坐标聚类确定列宽。然后将每个单词分配到对应的行列中,合并同一单元格内的文本。 导出到Excel就比较简单了,使用Pandas的to_excel方法即可。但需要注意合并单元格的情况,可能需要更复杂的处理,比如使用openpyxl库来调整格式,但用户的需求可能先以提取数据为主,格式调整可以后续处理。 最后,用户可能需要优化识别效果的建议,比如提高图片质量、调整Tesseract参数、使用更高级的布局分析工具如OCRTable等。同时,提醒用户OCR的局限性,特别是在复杂表格或低质量图片上可能需要人工校对。 在回答中需要引用用户提供的参考内容,即引用[1]中的示例代码。同时,确保代码正确,比如检查image_to_string的调用是否有空格,函数名是否正确,路径是否正确使用原始字符串等。可能用户提供的示例代码中有一些小错误,比如image_to_string后面有个空格,需要修正。 另外,用户可能对如何处理表格的结构有疑问,比如如何从OCR输出的文本块重建表格的行列结构。需要详细说明如何利用坐标信息进行聚类分析,或者使用pandas的数据处理功能来组织数据。这部分可能需要分步骤讲解,或者给出示例代码片段。 还要注意,用户的问题是关于表格数据,而不仅仅是文字识别,所以重点在于如何将识别的内容结构化,而不仅仅是提取文本。这可能需要额外的处理步骤,比如检测表格线(如果扫描图片中有明显的线条),或者根据文本的排列推断表格结构。不过Tesseract本身对表格的支持有限,可能需要结合其他方法。 最后生成的相关问题需要与主题相关,比如预处理方法、处理复杂表格、提升准确率、中英文混合识别以及OCR的替代方案等。这样用户可以根据需要进一步探索。</think>以下是使用Python通过Tesseract OCR提取扫描图片表格数据的完整解决方案: ### 一、环境准备 1. 安装依赖库 ```bash pip install pytesseract pandas pillow openpyxl ``` 2. 下载安装[Tesseract OCR引擎](https://github.com/tesseract-ocr/tesseract),安装时勾选中文数据包[^1] ### 二、基础实现步骤 ```python import pandas as pd import pytesseract from PIL import Image # 预处理增强识别效果 def preprocess_image(image_path): img = Image.open(image_path) # 基础处理(可根据需要扩展) img = img.convert('L') # 灰度转换 return img # OCR识别核心代码 def extract_table(image_path): img = preprocess_image(image_path) custom_config = r'--oem 3 --psm 6' # 优化表格识别模式 data = pytesseract.image_to_data( img, lang='chi_sim+eng', # 中英文混合识别 config=custom_config, output_type=pytesseract.Output.DATAFRAME ) return data # 转换数据结构 def build_dataframe(ocr_data): # 过滤有效数据(置信度>60) filtered = ocr_data[ocr_data.conf > 60] # 按坐标排序 sorted_df = filtered.sort_values(by=['top', 'left']) return sorted_df[['text', 'left', 'top', 'width', 'height']] # 主程序 image_path = r"D:\table_scan.png" output_path = r"D:\output.xlsx" ocr_data = extract_table(image_path) structured_df = build_dataframe(ocr_data) structured_df.to_excel(output_path, index=False) ``` ### 三、表格结构处理进阶 1. **坐标聚类算法**(自动检测行列) ```python from sklearn.cluster import KMeans def detect_grid(df): # 垂直方向聚类(检测列) x_coords = df[['left']].values kmeans_x = KMeans(n_clusters=5).fit(x_coords) # 假设5列 df['column'] = kmeans_x.labels_ # 水平方向聚类(检测行) y_coords = df[['top']].values kmeans_y = KMeans(n_clusters=10).fit(y_coords) # 假设10行 df['row'] = kmeans_y.labels_ return df.pivot_table(index='row', columns='column', values='text', aggfunc=' '.join) ``` 2. **可视化调试**(可选) ```python import matplotlib.pyplot as plt def plot_ocr_results(df): plt.figure(figsize=(15,10)) for i, row in df.iterrows(): plt.text(row['left'], row['top'], row['text'], bbox=dict(facecolor='red', alpha=0.5)) plt.gca().invert_yaxis() plt.show() ``` ### 四、优化建议 1. **图像预处理增强** ```python from PIL import ImageEnhance, ImageFilter def advanced_preprocess(image_path): img = Image.open(image_path) img = img.convert('L') # 灰度转换 img = img.filter(ImageFilter.SHARPEN) # 锐化 enhancer = ImageEnhance.Contrast(img) img = enhancer.enhance(2.0) # 提高对比度 return img ``` 2. **使用深度学习方案**(需GPU支持) ```python # 可选方案:paddleOCR识别表格 # pip install paddleocr from paddleocr import PaddleOCR ocr = PaddleOCR(use_angle_cls=True, lang='ch') result = ocr.ocr(image_path, cls=True) ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值