在一行(行)中从左到右排序轮廓,然后向下并在第二行从左到右排序

sort contours left to right in one line (row), then going down and sort left to right in second line

我正在尝试对轮廓进行排序以供 OCR 检测到它们,问题是我已尝试对轮廓进行从左到右和从上到下的排序,但这没有帮助。我在两行上有文本,我希望第一行的轮廓从左到右排序,然后第二行的轮廓相同。已经尝试了几种方法来解决这个问题,但我一直都失败了。下面是一个代码片段,显示了我试图实现的内容

def get_precedence(contour, cols):
  tolerance_factor = 10
  origin = cv2.boundingRect(contour)
  return ((origin[1] // tolerance_factor) * tolerance_factor) * cols + origin[0]

image = cv2.imread(file)
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)


edged = cv2.Canny(blurred, 30, 150)
cnts, h= cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts.sort(key=lambda x:get_precedence(x, edged.shape[1]))

我得到的结果顺序仍然是乱七八糟的。 我正在处理的图像是

第 1 步:我使用 cv2.boundingRect() 从轮廓中减少了数据。

第 2 步:我过滤了接触图像边缘的每个部分。

第 3 步:我从顶部排序剩余数据('y' 个值)。

第 4 步:我根据以下每个 'y' 的差异将数据分割成行,其中它大于字符高度的中值。

第 5 步:我从左开始对每一行进行排序。

代码:

import cv2
import numpy as np


def edge_filter(sgmts):
    x, y, w, h = sgmts[:, 0], sgmts[:, 1], sgmts[:, 2], sgmts[:, 3]
    res_y, res_x = image_shape
    return sgmts[((res_x - w - x) * (res_y - h - y) * x * y) != 0]


image = cv2.imread('sample.png')
image_shape = image.shape[:2]
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(blurred, 30, 150)
cnts = cv2.findContours(edged, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[0]

sgmts = np.array([cv2.boundingRect(i) for i in cnts])
filtered = edge_filter(sgmts)
sorted_top = filtered[np.argsort(filtered[:, 1])]

median_height = np.median(sorted_top[:, -1])
diff_y = np.diff(sorted_top[:,1])
new_line = np.where(diff_y > median_height)[0] + 1
lines = np.array_split(sorted_top, new_line)

sorted_left = [line[np.argsort(line[:, 0])] for line in lines]

for line, num in zip(sorted_left, range(len(sorted_left))):
    print(f'line {num + 1}:\n {line}\n')

这是我的输出: