用于 OCR 的 Python OpenCV 倾斜校正

2024-01-25

目前,我正在开发一个 OCR 项目,需要读取标签上的文本(请参见下面的示例图片)。我遇到了图像倾斜的问题,我需要帮助修复图像倾斜,以便文本是水平的而不是成角度的。目前,我正在使用的过程尝试从给定范围(下面包含代码)对不同角度进行评分,但这种方法不一致,有时会过度校正图像倾斜或完全无法识别倾斜并进行校正。需要注意的是,在进行倾斜校正之前,我将所有图像旋转 270 度以使文本直立,然后我将图像传递给下面的代码。传递给该函数的图像已经是二进制图像。

Code:


def findScore(img, angle):
    """
    Generates a score for the binary image recieved dependent on the determined angle.\n
    Vars:\n
    - array <- numpy array of the label\n
    - angle <- predicted angle at which the image is rotated by\n
    Returns:\n
    - histogram of the image
    - score of potential angle
    """
    data = inter.rotate(img, angle, reshape = False, order = 0)
    hist = np.sum(data, axis = 1)
    score = np.sum((hist[1:] - hist[:-1]) ** 2)
    return hist, score

def skewCorrect(img):
    """
    Takes in a nparray and determines the skew angle of the text, then corrects the skew and returns the corrected image.\n
    Vars:\n
    - img <- numpy array of the label\n
    Returns:\n
    - Corrected image as a numpy array\n
    """
    #Crops down the skewImg to determine the skew angle
    img = cv2.resize(img, (0, 0), fx = 0.75, fy = 0.75)

    delta = 1
    limit = 45
    angles = np.arange(-limit, limit+delta, delta)
    scores = []
    for angle in angles:
        hist, score = findScore(img, angle)
        scores.append(score)
    bestScore = max(scores)
    bestAngle = angles[scores.index(bestScore)]
    rotated = inter.rotate(img, bestAngle, reshape = False, order = 0)
    print("[INFO] angle: {:.3f}".format(bestAngle))
    #cv2.imshow("Original", img)
    #cv2.imshow("Rotated", rotated)
    #cv2.waitKey(0)
    
    #Return img
    return rotated

校正前和校正后的标签示例图像

修正前->修正后

如果有人能帮我解决这个问题,那将会有很大帮助。


这是一个实现用于斜角估计的投影轮廓法算法 http://www.cvc.uab.es/%7Ebagdanov/pubs/ijdar98.pdf。各个角度点被投影到累加器阵列中,其中倾斜角可以被定义为最大化对准的搜索间隔内的投影角度。这个想法是以不同角度旋转图像并为每次迭代生成像素直方图。为了确定倾斜角度,我们比较峰值之间的最大差异,并使用该倾斜角度旋转图像以校正倾斜。


原来的->已更正

倾斜角度:-2

import cv2
import numpy as np
from scipy.ndimage import interpolation as inter

def correct_skew(image, delta=1, limit=5):
    def determine_score(arr, angle):
        data = inter.rotate(arr, angle, reshape=False, order=0)
        histogram = np.sum(data, axis=1, dtype=float)
        score = np.sum((histogram[1:] - histogram[:-1]) ** 2, dtype=float)
        return histogram, score

    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] 

    scores = []
    angles = np.arange(-limit, limit + delta, delta)
    for angle in angles:
        histogram, score = determine_score(thresh, angle)
        scores.append(score)

    best_angle = angles[scores.index(max(scores))]

    (h, w) = image.shape[:2]
    center = (w // 2, h // 2)
    M = cv2.getRotationMatrix2D(center, best_angle, 1.0)
    corrected = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, \
            borderMode=cv2.BORDER_REPLICATE)

    return best_angle, corrected

if __name__ == '__main__':
    image = cv2.imread('1.png')
    angle, corrected = correct_skew(image)
    print('Skew angle:', angle)
    cv2.imshow('corrected', corrected)
    cv2.waitKey()

Note:您可能需要调整delta or limit值取决于图像。这deltavalue 控制迭代步长,它将迭代直到limit它控制最大角度。这种方法很简单,通过迭代检查每个角度 +delta目前仅适用于纠正 +/- 5 度范围内的倾斜。如果需要以更大的角度进行校正,请调整limit价值。对于处理倾斜的另一种方法,看看这个替代方法 https://stackoverflow.com/questions/57713358/how-to-rotate-skewed-fingerprint-image-to-vertical-upright-position.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用于 OCR 的 Python OpenCV 倾斜校正 的相关文章

随机推荐