opencv如何自动调整模板匹配的阈值?

How to automatically adjust the threshold for template matching with opencv?

所以我正在使用 opencv 进行模板匹配,如下所示。我经常需要 fiddle 与视觉相似度 #THRESHOLD,因为它有时无法发现匹配或者 return 太多匹配。这是一个反复试验,直到它与文档中某个位置的 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 值和 return 一个阈值 return 是一个矩形在图像中匹配(在上方绘制绿色框)。

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

我会改变

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

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

评论多,回复少,我总结一下答案给以后的读者。

首先,您的问题几乎与 . Also this thread seems to address the problem you are tackling:

相同

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

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

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

回答您关于在模板匹配中寻找最佳匹配的问题: 签出 。本质上,它归结为使用 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 中找到从图像中提取文本块(不使用模板匹配)的综合指南。