python - 如何消除文本图像的倾斜并检索该图像的新边界框 Python OpenCV?

标签 python opencv image-processing ocr scikit-image

这是我得到的收据图像,我使用 matplotlib 绘制了它,如果您看到该图像,则其中的文本不直。如何消除倾斜并修复它?

from skimage import io
import cv2

# x1, y1, x2, y2, x3, y3, x4, y4
bbox_coords = [[20, 68], [336, 68], [336, 100], [20, 100]]

image = io.imread('https://i.ibb.co/3WCsVBc/test.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)

fig, ax = plt.subplots(figsize=(20, 20))
ax.imshow(gray, cmap='Greys_r')

# for plotting bounding box uncomment the two lines below
#rect = Polygon(bbox_coords, fill=False, linewidth=1, edgecolor='r')
#ax.add_patch(rect)
plt.show()

print(gray.shape)
(847, 486)

receipt image

我认为如果我们想要首先去歪斜,我们必须找到边缘,所以我尝试使用canny算法找到边缘,然后得到如下所示的轮廓。

from skimage import filters, feature, measure

def edge_detector(image):
    image = filters.gaussian(image, 2, mode='reflect')
    edges = feature.canny(image)
    contours = measure.find_contours(edges, 0.8)
    return edges, contours

fig, ax = plt.subplots(figsize=(20, 20))

ax.imshow(gray, cmap='Greys_r'); 
gray_image, contours = edge_detector(gray)

for n, contour in enumerate(contours):
    ax.plot(contour[:, 1], contour[:, 0], linewidth=2)

我从上面的代码中得到的边缘是每个文本的边缘,但这不是我需要的。我需要获取收据边缘吗?

我还需要一种方法来在消除图像倾斜(即拉直图像)后获取新的边界框坐标?

如果有人解决过类似的问题,请帮助我?谢谢。

最佳答案

这是投影轮廓方法的修改实现,用于纠正倾斜图像,如 Projection profile based skew estimation algorithm for JBIG compressed images 中所述。 。获得二值图像后,想法是以各种角度旋转图像并在每次迭代中生成像素直方图。为了确定倾斜角度,我们比较峰值之间的最大差异,并使用该倾斜角度旋转图像以校正倾斜。要确定的峰值数量可以通过 delta 进行调整。值,增量越低,检查的峰值就越多,但过程会花费更长的时间。

<小时/>

之前->之后

Skew angle: -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.jpg')
    angle, corrected = correct_skew(image)
    print('Skew angle:', angle)
    cv2.imshow('corrected', corrected)
    cv2.waitKey()

注意:您可能需要调整 deltalimit值取决于图像。 delta value 控制迭代步长,它将迭代直到 limit它控制最大角度。这种方法很简单,通过迭代检查每个角度 + delta目前仅适用于纠正 +/- 5 度范围内的倾斜。如果需要更大角度校正,调整limit值(value)。对于处理偏差的另一种方法,take a look at rotate skewed image to upright position for an alternative method .

关于python - 如何消除文本图像的倾斜并检索该图像的新边界框 Python OpenCV?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59660933/

相关文章:

android - Ubuntu 13.04 上的 repo init UnicodeDecodeError

python - 如何使用 python 从 S3 存储桶读取 .txt 文件并查看内容?

c++ - 如何在 OpenCV 中调用 cv::updateMotionHistory()

c++ - OpenCV 图像拼接 - 使用 ExposureCompensator 和 MultiabandBlender 类

opencv - 显示直方图图openCV

python - 全局变量 Python 类

python - Pandas Dataframe 检查列值是否在列列表中

opencv - Canny Edge 的自适应参数

php - 如何阻止上传裸照?

python - 带有 color_mode 的 keras ImageDataGenerator.flow