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)
例如,它将搜索从 0
到 1.0
的每个 #THRESHOLD
值和 return 一个阈值 return 是一个矩形在图像中匹配(在上方绘制绿色框)。
但是,我不禁觉得这很穷,或者有更聪明的方法来找出阈值是多少?
我会改变
loc = np.where(result == np.max(result))
这给了我最匹配的位置,然后我可以只选择一个...
评论多,回复少,我总结一下答案给以后的读者。
首先,您的问题几乎与 . Also this thread seems to address the problem you are tackling:
相同
其次,检测 PDF 中的段落不应使用模板匹配,而应使用以下方法之一:
- 使用 canny edge detector in combination with dilation and F1 Score optimization. 按照 fmw42 的建议,这通常用于 OCR。
- 或者,您可以使用 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 中找到从图像中提取文本块(不使用模板匹配)的综合指南。
所以我正在使用 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)
例如,它将搜索从 0
到 1.0
的每个 #THRESHOLD
值和 return 一个阈值 return 是一个矩形在图像中匹配(在上方绘制绿色框)。
但是,我不禁觉得这很穷,或者有更聪明的方法来找出阈值是多少?
我会改变
loc = np.where(result == np.max(result))
这给了我最匹配的位置,然后我可以只选择一个...
评论多,回复少,我总结一下答案给以后的读者。
首先,您的问题几乎与
其次,检测 PDF 中的段落不应使用模板匹配,而应使用以下方法之一:
- 使用 canny edge detector in combination with dilation and F1 Score optimization. 按照 fmw42 的建议,这通常用于 OCR。
- 或者,您可以使用 Stroke Width Transform (SWT) 来识别文本,然后将其分组为行,最后分组,即段落。对于 OCR,这些块然后可以传递给 Tesseract(如 fmw42 所建议)
任何 OCR 任务的关键是通过根据需要更改图像来消除图像的破坏性特征,从而尽可能简化文本检测问题。预先处理的图像信息越多越好:change colors, binarize, threshold, dilate, apply filters, etc.
回答您关于在模板匹配中寻找最佳匹配的问题:
签出
# 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 中找到从图像中提取文本块(不使用模板匹配)的综合指南。