繁体   English   中英

如何检测两个盒子是否相互连接?

[英]How to detect whether two boxes are connected with each other or not?

我正在尝试检测是否与其他人相关的盒子信息。 并且,如果它们已连接,则连接到哪一个。 如下图所示:

示例图片

ABC 块连接到 DEF,DEF 块连接到 JKL,DEF 块连接到 MNO,依此类推。

我能够检测到框和框内的文本。

我将从我的解决方案的最终 output 开始,可以肯定的是,这是预期的结果:

GHI is connected with DEF.
MNO is connected with DEF.
MNO is connected with JKL.
DEF is connected with JKL.
DEF is connected with ABC.

我将大致思路概述一下,详细请看代码中的注释:

  1. 逆二进制阈值,用于在黑色背景上获取白色内容。
  2. 查找具有层次结构的轮廓。 在寻找当前外轮廓的孩子时,我们会得到“内”框。
  3. 获取每个框的二进制掩码。 在该掩码中,使用pytesseract获取文本。
  4. 扩大蒙版以包括边框。
  5. 迭代两个框的所有组合:
    • 复制阈值图像。 删除所有不属于当前对的框。

    • 裁剪图像 w.r.t。 到当前对的两个盒子:

      例子

    • 仅查找外部轮廓:如果只有一个轮廓,则两个框都是连接的。

那将是完整的代码:

import cv2
import itertools
import numpy as np
import pytesseract

# Read image
img = cv2.imread('hO0if.jpg', cv2.IMREAD_GRAYSCALE)

# Inverse binary threshold to get rid of JPG artifacts and inverse black/white
gray = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY_INV)[1]

# Find contours and hierarchy w.r.t. the OpenCV version
cnts = cv2.findContours(gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cnts, hier = cnts[0:] if len(cnts) == 2 else cnts[1:]

# Filter children of most outer contour; these are the "inner" boxes
boxes = [cnts[i] for i in np.argwhere(hier[..., 3].flatten() == 0).flatten()]

# Get masks of boxes
masks = [cv2.drawContours(np.zeros_like(img), [b], -1, 255, cv2.FILLED) for b in boxes]

# Get texts inside the boxes
rois = [cv2.boundingRect(cv2.bitwise_and(img, img, mask=m)) for m in masks]
texts = [pytesseract.image_to_string(img[r[1]:r[1]+r[3], r[0]:r[0]+r[2]]) for r in rois]
texts = [t.replace('\n', '').strip() for t in texts]

# Dilate masks
masks = [cv2.dilate(m, np.ones((11, 11))) for m in masks]

# Get all combinations of two boxes
combs = list(itertools.combinations(range(len(boxes)), 2))

# Iterate all combinations of two boxes
for c in combs:

    # Temporary image
    tmp = gray.copy()

    # Iterate all boxes not belonging to the current pair
    for i in (j for j in range(len(boxes)) if j not in c):

        # Remove those boxes
        r = cv2.boundingRect(cv2.bitwise_and(img, img, mask=masks[i]))
        tmp[r[1]:r[1]+r[3], r[0]:r[0]+r[2]] = 0

    # Crop image w.r.t. the boxes of the current pair
    r = cv2.boundingRect(cv2.bitwise_or(masks[c[0]], masks[c[1]]))
    tmp = tmp[r[1]:r[1]+r[3], r[0]:r[0]+r[2]]

    # Find outer contours w.r.t. the OpenCV version
    cnts = cv2.findContours(tmp, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]

    # If there's a single outer contour, both boxes are connected
    if len(cnts) == 1:
        print('{} is connected with {}.'.format(texts[c[0]], texts[c[1]]))

现在,我不确定检查len(cnts) == 1是否足够。 我可以想象,可能会有一些例子,排除其他框可能会导致死胡同,然后也将其视为轮廓。 也许,在这种情况下,还需要检查轮廓的大小。

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
NumPy:         1.20.1
OpenCV:        4.5.1
pytesseract:   4.00.00alpha
----------------------------------------

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM