首页 > 编程语言 >esXGray开发笔记:基于直线检测的文本倾斜自动校正算法实现(python+opencv)

esXGray开发笔记:基于直线检测的文本倾斜自动校正算法实现(python+opencv)

时间:2023-08-15 10:13:16浏览次数:42  
标签:angle val min python cv2 esXGray opencv np group

昨日采用最小面积矩形的方式实现文本倾斜自动校正,但后面的角度有点麻烦,于是改用基本直线检测的算法。

算法简介:

  1. 检测直线,自动调节参数,至少获取11条直线(直线条数调节)
  2. 计算每条直线与x轴夹角
  3. 从返回的角度中找到出现次数较多的直线角度平均值并返回作为图片倾斜角度
  4. 检测到角度后,就可以将图片进行校正了

结果:

 在esXGray中的应用演示:

 

主要代码:

  1 import cv2
  2 import numpy as np
  3 import math
  4 
  5 
  6 def group_data(data, num_groups):
  7     """返回一组数据中数据集中的范围上下限(无视少数派数据)"""
  8     # 将列表转换为浮点数数组
  9     data = np.array(data).astype(float)
 10     # 找到列表中的最小值和最大值
 11     min_val = np.min(data)
 12     max_val = np.max(data)
 13     # 计算每个组的范围
 14     if max_val == min_val:
 15         return min_val, max_val  # 如果最小值与最大值相等则直接返回
 16     else:
 17         group_range = (max_val - min_val) / num_groups
 18         # 创建一个数组来存储每个元素所属的组的索引
 19         group_indices = np.floor((data - min_val) / group_range).astype(int)
 20         # 统计每个组中的元素个数
 21         group_counts = np.bincount(group_indices)
 22         # 找到元素个数最多的组的索引
 23         most_common_group_index = np.argmax(group_counts)
 24         # 计算该组的最小值和最大值
 25         most_common_group_min = min_val + most_common_group_index * group_range
 26         most_common_group_max = min_val + (most_common_group_index + 1) * group_range
 27         return most_common_group_min, most_common_group_max
 28 
 29 
 30 def get_angle_auto(src):
 31     """自动获取图片文本行倾斜角度(与x轴夹角)"""
 32     def calc_angle(x1, y1, x2, y2):
 33         # 计算直线的斜率
 34         if x1 == x2:
 35             return 90
 36         slope = (y2 - y1) / (x2 - x1)
 37         # 计算与x轴的夹角(以弧度为单位)
 38         angle_rad = math.atan(slope)
 39         # 将弧度转换为角度(如果需要)
 40         angle_deg = math.degrees(angle_rad)
 41         return angle_deg
 42     # 将图像转换为灰度图像
 43     gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
 44     # 使用高斯模糊来减少图像中的噪声
 45     blur = cv2.GaussianBlur(gray, (5, 5), 0)
 46     # 使用自适应阈值化将图像转换为二值图像
 47     thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 15, 30)
 48     # 定义一个结构元素,用于图像的膨胀操作
 49     kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
 50     # 使用膨胀操作来连接断开的边缘
 51     dilate = cv2.dilate(thresh, kernel, iterations=6)
 52     # 使用Canny边缘检测
 53     edges = cv2.Canny(dilate, 200, 250, apertureSize=3)
 54     # 使用Hough变换检测直线
 55     lines: list = []  # 检测结果list
 56     length = 200  # 直线点数下限,考虑到存在文本行的图片尺寸不会太小,因此设为200
 57     # 下面逐步调节参数,需要至少检测到11条,根据不同图形参数需要调节一下
 58     # 条数过少,可能检测到的是非文本行,而是边界的直线;
 59     # 条数过多,可能出现一些无意义的错误直线
 60     while len(lines) < 11:
 61         lines = cv2.HoughLines(edges, 1, np.pi / 180, length)
 62         if lines is None:
 63             lines = []
 64         length -= 5  # 如果没有检测到直线,自动调节参数
 65         if length <= 5:
 66             break
 67 
 68     print('检测到直线条数:', len(lines))
 69     # 在图像上绘制检测到的直线
 70     angles = []
 71     if len(lines) > 0:
 72         for line in lines:
 73             rho, theta = line[0]
 74             a = np.cos(theta)
 75             b = np.sin(theta)
 76             x0 = a * rho
 77             y0 = b * rho
 78             x1 = int(x0 + 1000 * (-b))
 79             y1 = int(y0 + 1000 * a)
 80             x2 = int(x0 - 1000 * (-b))
 81             y2 = int(y0 - 1000 * a)
 82             # 此处可以画出图像查看结果
 83             cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
 84             angle = calc_angle(x1, y1, x2, y2)
 85             print(angle)
 86             angles.append(angle)
 87 
 88         # 下面从得到的角度中迭代获取角度集中区间
 89         dmin = 0
 90         dmax = 100
 91         while dmax - dmin > 1 and len(angles) >= 3:  # 如果数据区间>1且数据个数>=3则继续
 92             dmin, dmax = group_data(angles, 3)
 93             if dmin:
 94                 angles = [i for i in angles if dmin <= i <= dmax]  # 剔除少数派数据
 95             else:
 96                 break
 97         if len(angles) > 0:
 98             return -sum(angles) / len(angles)  # 返回剩余数据平均值
 99         else:
100             return None
101     else:
102         return None
103 
104 
105 img_src = r"c:/users/eerso/desktop/002.png"
106 # 读取图像
107 image = cv2.imread(img_src)
108 angle = get_angle_auto(image)
109 print(f'angle={angle}')
110 # 显示结果图像
111 cv2.imshow('image', image)
112 cv2.waitKey(0)
113 cv2.destroyAllWindows()
View Code

 

标签:angle,val,min,python,cv2,esXGray,opencv,np,group
From: https://www.cnblogs.com/eersoft/p/17630575.html

相关文章

  • python代码中取消运行中的warning
    在Python中,可以使用warnings模块来管理和控制警告的显示。你可以通过设置警告过滤器来控制是否显示特定类型的警告。以下是一些常见的方法来处理警告:过滤警告: 可以使用warnings.filterwarnings()函数来设置警告过滤器,从而控制是否显示特定类型的警告。比如,可以使用warnings.fil......
  • python如何复现DES3加密
    importbase64fromCrypto.CipherimportDES3BS=8pad=lambdas:s+(BS-len(s)%BS)*chr(BS-len(s)%BS)#3DES的MODE_CBC模式下只有前24位有意义key=b'appapiche168comappapiche168comap'[0:24]iv=b'appapich'plaintext=pad("9f5......
  • Python写一个剪刀石头布小游戏
    #导入包importrandom#调用randint()函数,表示随机取其中的任意一个数,左闭右也毕#初始化变量n=0pc=0#表示电脑计分person=0#表示人计分whilen<3:a=random.randint(1,3)#a代表电脑b=int(input('请出拳(1.剪刀,2.石头,3.布):'))#改变变量n+=1#if判断,当电脑出剪刀时:......
  • opencv-python目标跟踪
    目标追踪(objecttracking)是指先给定视频的第一帧中的目标以及它的位置,之后不断的追踪目标,预测目标的轨迹。1目标跟踪的困难点形态变化:姿态变化是目标跟踪中常见的干扰问题。运动目标发生姿态变化时,会导致它的特征以及外观模型发生改变,容易导致跟踪失败。比如体育比赛中的运动......
  • java opencv创建 空图片
    javaopencv创建空图片  packageml;importorg.opencv.core.Core;importorg.opencv.core.CvType;importorg.opencv.core.Mat;importorg.opencv.core.Scalar;importorg.opencv.highgui.HighGui;publicclassTest2{publicstaticvoidmain(String[......
  • VS Code调试Python相关的问题
    VSCode启动Debug模式调试带参数的python文件:https://blog.csdn.net/weixin_39329055/article/details/119530587单步调试进入外部文件:launch.json中写入以下:{//使用IntelliSense了解相关属性。//悬停以查看现有属性的描述。//欲了解更多信息,请访问:......
  • linux安装python
    转载请注明出处:1.查看当前系统上已安装的Python版本:在终端中运行以下命令:python--version或者使用以下命令查看全部已安装的Python版本:ls/usr/bin/python* 2.下载并安装python包访问Python官方网站https://www.python.org/downloads/source/,找到并......
  • 如何使用Python调用常用的Linux命令
    本文将介绍如何使用Python调用Linux命令,包括常用命令的使用方法和示例代码。1.使用subprocess模块调用Linux命令Python内置了一个名为subprocess的模块,可以用于在Python程序中执行外部命令。subprocess模块提供了许多函数和方法,可以方便地启动新进程、连接到它们的输入/输出/错误......
  • 如何将Python代码转换为Goland
    本文将介绍如何将Python代码转换为Goland,包括转换工具、转换步骤和注意事项。1.转换工具目前市面上有很多Python到Go的转换工具,例如:Transcrypt:一个命令行工具,可以将Python代码转换为Go代码。PyGo:一个Python库,可以在Python代码中嵌入Go代码,从而实现Python到Go的转换。GoPy:一个Pytho......
  • 关于Python的学习记录(二十二_读写 CSV 文件)
    CSV文件介绍CSV(CommaSeparatedValues)全称逗号分隔值文件是一种简单、通用的文件格式,被广泛的应用于应用程序(数据库、电子表格等)数据的导入和导出以及异构系统之间的数据交换。因为CSV是纯文本文件,不管是什么操作系统和编程语言都是可以处理纯文本的,而且很多编程语言中都提供了......