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

365bet登录地址 📅 2025-10-08 20:35:55 ✍️ admin 👀 8228 ❤️ 761
使用 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 的强大图像处理能力,本方法有效解决了扫描图像文本倾斜的问题。这不仅使得从图像到文本的转换更加高效、准确,还大大提升了后续数据处理的流畅性。实际应用中,该技术表现出了优越的性能和广泛的适用性,为类似的图像处理任务提供了一个可靠的解决方案。

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

相关推荐

注册365bet要什么条件 烟雨江湖资源多久刷新

烟雨江湖资源多久刷新

📅 07-17 👀 5941
sportcar365 腋下淋巴在哪个位置图片

腋下淋巴在哪个位置图片

📅 07-07 👀 5797
365bet登录地址 京剧《金玉奴》(全剧)俞振飞 童芷苓
365bet登录地址 同样是干鱿鱼,挑“大的”还是“小的”?弄懂以后再买不吃亏
注册365bet要什么条件 御龙在天职业推荐(御龙在天各职业利弊分析)
sportcar365 新网的云服务器怎么样

新网的云服务器怎么样

📅 10-08 👀 5214
注册365bet要什么条件 韩国媒体嘲讽中国男足!言辞犀利不留情面,网友:国足不要再忍了
365bet登录地址 手机app银行转账怎么操作,手机App银行转账操作指南
注册365bet要什么条件 奥迪a4和a4l有什么区别

奥迪a4和a4l有什么区别

📅 09-29 👀 5482

友情伙伴