【问题标题】:Getting contours in an Order在订单中获取轮廓
【发布时间】:2025-12-01 05:30:01
【问题描述】:

对于手写数字识别,我已经使用 MNIST 数据库训练了我的 CNN。

现在,我必须将输入图像处理为 MNIST 格式以检测数字。

对于以下图像:

我正在使用轮廓来分隔 3 和 8,为了检测和写入“38”,我需要先发送 3,然后再发送 8 到 CNN。

但来自 cv2.findContours() 的轮廓顺序令人困惑,有时会先检测到 8,然后检测到 3,使其变为“83”。

我怎样才能让轮廓从左到下书写,类似地从上到下?

【问题讨论】:

  • 你可以做的是围绕你的两个黑色数字创建边界矩形,然后从最左边的矩形开始迭代并将该矩形中的所有轮廓发送到你的 CNN。如果你以this 为例,从上到下,你会有两个独立的矩形
  • 是的,完成了边界矩形,我如何从左到右迭代?我知道我可以查看起始像素坐标,但还有比这更简单的方法吗?
  • 不是真的,只取 Rect 开头的 X,Y 并从 image.cols = 0 迭代。 - 这可能令人困惑,例如 this

标签: python opencv


【解决方案1】:

您可以做的是围绕您的两个黑色数字创建边界矩形,然后从最左边的矩形开始迭代并将该矩形中的所有轮廓发送到您的 CNN。如果你以this 为例,从上到下,你会得到两个独立的矩形:

来自该链接的示例代码:

contours, hier = cv2.findContours(gray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
    if 200<cv2.contourArea(cnt)<5000:
        cv2.drawContours(img,[cnt],0,(0,255,0),2)
        cv2.drawContours(mask,[cnt],0,255,-1)

然后,当你有一组轮廓时,你可以按顺序对它们进行排序:

import numpy as np

c = np.load(r"rect.npy")
contours = list(c)

# Example - contours = [(287, 117, 13, 46), (102, 117, 34, 47), (513, 116, 36, 49), (454, 116, 32, 49), (395, 116, 28, 48), (334, 116, 31, 49), (168, 116, 26, 49), (43, 116, 30, 48), (224, 115, 33, 50), (211, 33, 34, 47), ( 45, 33, 13, 46), (514, 32, 32, 49), (455, 32, 31, 49), (396, 32, 29, 48), (275, 32, 28, 48), (156, 32, 26, 49), (91, 32, 30, 48), (333, 31, 33, 50)] 

max_width = np.sum(c[::, (0, 2)], axis=1).max()
max_height = np.max(c[::, 3])
nearest = max_height * 1.4

contours.sort(key=lambda r: (int(nearest * round(float(r[1])/nearest)) * max_width + r[0]))

for x, y, w, h in contours:
    print "{:4} {:4} {:4} {:4}".format(x, y, w, h) 

取自 - here

【讨论】:

  • 想知道为什么它在创建我的问题时没有向我显示那个问题...无论如何非常感谢!