【问题标题】:template matching with multiple objects opencv python模板匹配多个对象opencv python
【发布时间】:2020-04-10 03:07:31
【问题描述】:

我有一个这样的扫描图像文档:

该图像是使用普通扫描引擎扫描的,因此文档可能会倾斜。图像已经进行了二值化处理,所以还是有一点点噪点。我想知道这个模板在图片中的位置。 这是模板:

我的预期结果是模板在图像文档中的位置坐标,数组形式如下:

[[35,1532], [1923,20], [1923,1532]]

如果结果正确,我需要线索,例如在匹配的模板周围添加框 我试过这段代码:

img = cv2.imread('image_document.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
template = cv2.imread('template.jpg',0)

# run template matching, get minimum val
res = cv2.matchTemplate(gray, template, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

# create threshold from min val, find where sqdiff is less than thresh
min_thresh = (min_val) * 1.5
match_locations = np.argwhere(res<=min_thresh)

# draw template match boxes
w, h = template.shape[::-1]
for (x, y) in zip(match_locations[1], match_locations[0]):
    cv2.rectangle(img, (x, y), (x+w, y+h), [0,255,255], 2)

# display result
cv2.imwrite('result.jpg', img)

但实际结果是矩形太大,与模板不匹配

【问题讨论】:

  • 我相信你想要 np.argwhere() 而不是 np.where。后者返回像素值。前者返回坐标。
  • @fmw42 对,我已经更改了它,并且在 result.jpg 中得到了一个矩形。但矩形太大,与模板不匹配
  • Numpy 将坐标返回为 y,x。所以你想交换它们以便在 OpenCV 中使用它们,它需要坐标为 x,y。 shape 也将值返回为 h,w 而不是 w,h。所以要小心你如何使用 Numpy 和 OpenCV
  • @fmw42 好吧。但盒子仍然在左上角,当我交换 x,y 和 w,h 时大小没有改变
  • 你的模板图像比输入图像中对应标记的尺寸大很多。编码后的模板匹配需要使模板图标的大小与输入图像中的大小相同。或者您将需要使用多尺度模板匹配。搜索谷歌。参见例如pyimagesearch.com/2015/01/26/…

标签: python opencv image-processing template-matching


【解决方案1】:

我也遇到过类似的问题,我就是这样解决的。

import numpy as np
import cv2

#Reading the image that we want to find the match
img = cv2.imread('image_document.jpg')
#Reading what we want to match with
template = cv2.imread('template.jpg',0)

#Identifying the location of the divisions we are seeking
#I'm using TM_CCOEFF_NORMED because it is the best for my problem
#But you could test different algorithms 
result = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED) 

#Expressing those locations in variables
#This will give you the best match, not all matches.
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)                                                           

#You have to find the right threshold to your problem
#Mine was 0.95, which has to be really similar, but you could need 0.6, 0.4 other value for yours.
#If the threshold is equal to 1, then you'll have to have a 100% match
threshold = 0.95

#This will give you the X and Y locations of the images you are seeking.
#If you have too many locations that means your threshold isn't quite right
yloc, xloc = np.where(result >= threshold)
w, h = template.shape[::-1]

#This will give you the location of the rectangles you are seeking
#We should expect 3 lists inside according to your problem
rectangles = []
# draw template match boxes
for (x, y) in zip(yloc, xloc):
    cv2.rectangle(img, (x, y), (x+w, y+h), [0,255,255], 2)
    rectangles.append([x,y,w,h])

# display result
cv2.imwrite('result.jpg', img)
print(rectangles)

希望这会有所帮助,它确实对我的问题有所帮助。 还有别的东西。您应该从原始图像中剪切您试图找到的图像,这将有助于匹配。 对于阈值,我不认为从 min_val 获取它是最佳选择,您可以尝试为您找到最佳选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多