【问题标题】:How to automatically adjust the threshold for template matching with opencv?如何使用opencv自动调整模板匹配的阈值?
【发布时间】:2020-05-12 08:28:15
【问题描述】:

所以我正在使用 opencv 进行模板匹配,如下所示。我经常需要摆弄#THRESHOLD 的视觉相似性,因为它有时无法发现匹配项,或者它返回的匹配项太多。这是一个反复试验,直到它与文档中某个位置的 1 个元素完全匹配。我想知道是否有任何方法可以以某种方式自动执行此操作。

image.png 文件是 pdf 文档的图片。 template.png 文件是段落的图片。我的目标是发现 pdf 文档中的所有段落,我想知道这里有什么神经网络有用。

import cv2
import numpy as np


img = cv2.imread("image.png");
gimg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
template = cv2.imread("template.png", cv2.IMREAD_GRAYSCALE);
w, h = template.shape[::-1]


result = cv2.matchTemplate(gimg, template, cv2.TM_CCOEFF_NORMED)

loc = np.where(result >= 0.36) #THRESHOLD
print(loc)

for pt in zip(*loc[::-1]):
        cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0,255,0), 3)

cv2.imwrite("output.png", img)

例如,它将搜索从01.0 的每个#THRESHOLD 值,并返回一个阈值,该阈值会返回图像中的单个矩形匹配项(在上方绘制绿色框)。

但是,我不禁觉得这很笼统,或者有没有更聪明的方法来找出阈值是多少?

【问题讨论】:

标签: python opencv template-matching


【解决方案1】:

由于cmet很多,几乎没有任何回应,我将答案总结给未来的读者。

首先,您的问题几乎与 How to detect paragraphs in a text document image for a non-consistent text structure in Python 相同。此线程似乎也解决了您正在解决的问题:Easy ways to detect and crop blocks (paragraphs) of text out of image?

其次,检测 PDF 中的段落不应使用模板匹配,而应使用以下方法之一:

  1. 使用canny edge detector in combination with dilation and F1 Score optimization. 这通常用于 OCR,如 fmw42 建议的那样。
  2. 或者,您可以使用Stroke Width Transform (SWT) 来识别文本,然后将其分组为行,最后是块,即段落。对于 OCR,然后可以将这些块传递给 Tesseract(按照 fmw42 的建议)

任何 OCR 任务的关键是通过根据需要更改图像来消除图像的破坏性特征,从而尽可能简化文本检测问题。您事先处理的图像信息越多越好:change colors, binarize, threshold, dilate, apply filters, etc.

回答您的问题:在模板匹配中寻找最佳匹配: 结帐nathancy's answer on template matching。本质上,它归结为使用 minMaxLoc 找到最大相关值。请参阅 Nathancy 的回答摘录:

    # Threshold resized image and apply template matching
    thresh = cv2.threshold(resized, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
    detected = cv2.matchTemplate(thresh, template, cv2.TM_CCOEFF)
    (_, max_val, _, max_loc) = cv2.minMaxLoc(detected) ```

此外,在nathancy's answer in this thread 中可以找到从图像中提取文本块(不使用模板匹配)的综合指南。

【讨论】:

    【解决方案2】:

    我会改变的

    loc = np.where(result == np.max(result))
    

    这给了我最好的匹配位置,然后我可以只选择一个,如果我想......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多