python - 根据文本方向检测图像方向角

标签 python image opencv image-processing computer-vision

我正在执行一项 OCR 任务,以从多个身份证明文件中提取信息。一个挑战是扫描图像的方向。需要固定 PAN、Aadhaar、驾驶执照或任何身份证明的扫描图像的方向。

已经在 Stackoverflow 和其他论坛上尝试了所有建议的方法,例如 OpenCV minAreaRect、Hough Lines Transforms、FFT、homography、tesseract osd with psm 0。均无效。

逻辑应返回文本方向的角度 - 0、90 和 270 度。附上0、90、270度的图片。这与确定偏度无关。 enter image description here

最佳答案

这是一种基于大部分文本偏向一侧的假设的方法。这个想法是我们可以根据主要文本区域所在的位置来确定角度


转换为灰度和高斯模糊后,自适应阈值得到二值图像

enter image description here

从这里我们找到轮廓并使用轮廓区域进行过滤以去除小噪声粒子和大边界。我们将通过此过滤器的任何轮廓绘制到蒙版上

enter image description here

为了确定角度,我们根据图像的尺寸将图像分成两半。如果 width > height 则它必须是水平图像,所以我们垂直分成两半。如果 height > width 那么它必须是垂直图像所以我们水平分成两半

enter image description here enter image description here

现在我们有两半,我们可以使用 cv2.countNonZero() 来确定每一半的白色像素数量。这是确定角度的逻辑:

if horizontal
    if left >= right 
        degree -> 0
    else 
        degree -> 180
if vertical
    if top >= bottom
        degree -> 270
    else
        degree -> 90

left 9703

right 3975

因此图像为0度。这是其他方向的结果

enter image description here enter image description here enter image description here enter image description here

left 3975

right 9703

我们可以得出结论,图像翻转了 180 度

这是垂直图像的结果。请注意,由于它是垂直图像,我们水平分割

enter image description here enter image description here enter image description here enter image description here

enter image description here

top 3947

bottom 9550

因此结果是90度

import cv2
import numpy as np

def detect_angle(image):
    mask = np.zeros(image.shape, dtype=np.uint8)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (3,3), 0)
    adaptive = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,15,4)

    cnts = cv2.findContours(adaptive, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]

    for c in cnts:
        area = cv2.contourArea(c)
        if area < 45000 and area > 20:
            cv2.drawContours(mask, [c], -1, (255,255,255), -1)

    mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
    h, w = mask.shape
    
    # Horizontal
    if w > h:
        left = mask[0:h, 0:0+w//2]
        right = mask[0:h, w//2:]
        left_pixels = cv2.countNonZero(left)
        right_pixels = cv2.countNonZero(right)
        return 0 if left_pixels >= right_pixels else 180
    # Vertical
    else:
        top = mask[0:h//2, 0:w]
        bottom = mask[h//2:, 0:w]
        top_pixels = cv2.countNonZero(top)
        bottom_pixels = cv2.countNonZero(bottom)
        return 90 if bottom_pixels >= top_pixels else 270

if __name__ == '__main__':
    image = cv2.imread('1.png')
    angle = detect_angle(image)
    print(angle)

关于python - 根据文本方向检测图像方向角,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58010660/

相关文章:

android - 如何在运行时将图像从 Android 设备的图库映射到 Unity 应用程序中的纹理?

ios - 动态改变图形资源颜色的策略

xml - 如何在 XML 文件中的同一元素名称中写入多个 Mats?

android - 无法连接到 OpenCV 管理器

Javascript - 除非我警告(),否则更改图像将不起作用

c++ - 使用opencv cap无法使用While循环调用函数两次

python - 在 DataFrame 中使用正则表达式 - 最后 5 个字符

python - 验证 Excel 单元格值并插入 SQL 错误 HY000 Python

python - 从列表中删除符合条件的第一个匹配项

python - 向 pandas 中的日期列增量添加时间