我使用matchtemplate在后台检测67x45 sqaure。我认为我的代码工作正常,没有任何问题,但问题是我必须为它设置高阈值才能成功检测,否则它会给予这么多的错误检测。所以我尝试将方法改为cv2.TM_CCOEFF_NORMED,但它没有很好地工作。我也试着寻找opencv文档来了解所有这些方法是如何工作的,但对我来说真的很难理解,因为它们只提供数学公式。所以我的问题是我对我的代码没问题吗?或者有没有更好的方法来完成我想做的事情?(我也不确定我是否以正确的方式在matchtemplate中使用“template”参数)
import cv2
import numpy as np
import win32gui, win32ui, win32con
def imagesearch(per):
filename = 'target.png'
img = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
img1 = cv2.imread(filename)
template = cv2.imread('./map/6745.png', cv2.IMREAD_GRAYSCALE)
w, h = template.shape[::-1]
meth = [cv2.TM_CCOEFF, cv2.TM_CCOEFF_NORMED, cv2.TM_CCORR, cv2.TM_CCORR_NORMED, cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]
res = cv2.matchTemplate(img, template, meth[3], None, template)
threshold = per
loc = np.where(res>=threshold)
if loc[0].any():
for pt in zip(*loc[::-1]):
cv2.rectangle(img1, pt, (pt[0] + w, pt[1] + h), (0,0,255), 1)
cv2.imshow("dst", img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
imagesearch(0.99)
影像
样板
阈值= 0.99的结果
阈值= 0.95的结果
正如“克里斯托弗·拉克维茨”所说,
import cv2
import numpy as np
import win32gui, win32ui, win32con
def imagesearch():
filename = 'target.png'
img = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
img1 = cv2.imread(filename)
template = cv2.imread('./map/6745.png', cv2.IMREAD_GRAYSCALE)
w, h = template.shape[::-1]
meth = [cv2.TM_CCOEFF, cv2.TM_CCOEFF_NORMED, cv2.TM_CCORR, cv2.TM_CCORR_NORMED, cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]
method = meth[5]
res = cv2.matchTemplate(img, template, meth[5], None, template)
if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
min_val,max_val,min_loc, max_loc = cv2.minMaxLoc(res)
top_left = min_loc
bottom_right = (top_left[0]+w,top_left[1]+h)
cv2.rectangle(img1,top_left,bottom_right,255,1)
cv2.imshow("dst", img1)
cv2.waitKey(0)
cv2.destroyAllWindows()
imagesearch()
这个也不行。
指令集
1条答案
按热度按时间cyvaqqii1#
在边界盒状矩形的特殊情况下,使用自己的方法直接在numpy图像阵列上工作来检测它是有意义的,而不是使用OpenCV匹配函数与模板图像以及应对不同的匹配算法和阈值。
下面的代码可以检测任意数量的矩形,这些矩形的边长为模板图像中给定形状的一个像素宽。它适用于任何矩形的线条颜色,因此无论它是黑色背景上的白色矩形还是明亮背景上的黑色矩形,或者矩形的灰度值是否等于背景的灰度值,都没有关系,因为它使用了全色信息。
为了简化搜索条件,图像的BGR元组被转换为表示RGB颜色的单个整数值,因此用于搜索算法的图像阵列是纯2D阵列(就像使用灰度时一样)。
为了确保不检测单色背景中的矩形,检查矩形左上角的一个内部像素,并且必须具有另一种颜色作为矩形。这种情况可能导致未检测到矩形,并且随后需要检查多个像素。但是如果需要的话,可以容易地将检查扩展到多于一个像素,并将其实现到所检查的条件的序列中。并且如果背景图像不具有矩形大小的单色的大区域,则像素检查可以从检查的条件的序列中完全去除。
提供的代码中的Python循环可能会被矢量化的numpy方法所取代,因此欢迎对如何实现这一点发表评论。
程式码会在提供的影像中找到一个矩形:
在[(89,13)]处。