【问题标题】:sort contours left to right in one line (row), then going down and sort left to right in second line在一行(行)中从左到右排序轮廓,然后在第二行从左到右排序
【发布时间】:2021-08-08 09:55:03
【问题描述】:

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

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]))

我得到的结果订单仍然一团糟。 我正在处理的图像是

【问题讨论】:

  • 查看this 的帖子。
  • 虽然这确实解决了排序的问题,但是链接中的代码排序并在图像上绘制轮廓线。我需要能够像使用这些行一样存储这些轮廓: cnts = cv2.findContours(edged.copy(),v2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts) 然后我希望能够迭代它们以输入我训练过的 OCR 模型。
  • 首先使用水平形态学开放核连接字母来分离单词。然后遍历单词并分离字母。

标签: python opencv contour opencv-contour


【解决方案1】:

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

第二步:我过滤了触及图像边缘的每个片段。

第三步:我从顶部('y'值)对剩余数据进行排序。

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

第五步:我从左到右对每一行进行排序。

代码:

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')

这是我的输出:

【讨论】:

    猜你喜欢
    • 2015-01-24
    • 2016-12-03
    • 2022-09-24
    • 2019-09-27
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    相关资源
    最近更新 更多