如何用 cv2 隔离条形图?

How to isolate the bars with cv2?

如何隔离下图中代表条形图的没有白色填充的条形?

我正在寻找适用于此图像的任何变体的解决方案。您可以假设格式相同,但 gridlines/axis 行中的间隙等某些功能可能位于不同的位置。

我已经尝试检测条形的各种特征,例如条形的 26x3px 末端,或左上角和右下角。例如,对左上角使用如下掩码:

bar_top_kernel: Numpy = np.array([
    [1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 0, 0, 0, 0, 0, 0, 0],
], dtype='uint8')

bar_top_kernel: Numpy = np.array([
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
], dtype='uint8')

但根据我的尝试,由于条形的末端与网格线的相互作用,我可能会漏掉角落或误报。

我试过先删除网格线。但是由于条形末端和网格线的相互作用,我往往会留下一些干扰特征检测的碎片。

我开始认为如果没有某种 ML 方法这可能是不可能的,但我希望有人会发现一个聪明的技巧来实现这一点。

(请点击查看大图)

我最终想出了一个简单的技巧:

  1. 反转颜色。
  2. 查找并填充任何轮廓:边界框宽度 > 条形宽度。这基本上隔离了酒吧。
  3. 再找等高线,找到质心靠得很近的成对等高线。这给出了由刻度线分成 2 的小条。
  4. 填充包含每对的矩形以修复拆分。