所以我不知道标题是否容易理解,但是我的问题与OpenCV模板匹配有关,以及程序何时可以说出“找到模板”并为while循环返回布尔值。 附言:我知道一直保存并删除图像效率很低,但是可以正常工作
import cv2
import numpy as np
from PIL import ImageGrab
import os
原始图像功能只是将Pil图像转换为opencv可以使用的图像的一种方法
def originalImages():
screenPart = ImageGrab.grab(bbox=(900,40,1030,105))
screenPart.save('CurrentFrame.jpg','JPEG')
screen = cv2.imread('CurrentFrame.jpg', 0)
cv2.imshow('screen',screen)
os.remove('CurrentFrame.jpg')
return screen
screen = originalImages()
res = cv2.matchTemplate(screen, template_img, cv2.TM_CCOEFF_NORMED)
loc = np.where(res>=0.8) #0.8 is the threshold
那么zip位置中的点就是绘制匹配的位置。
for pt in zip(*loc[::-1]):
cv2.rectangle(screen, pt, (pt[0] + w, pt[1] + h),(0,255,0) , 2)
所以我的问题是,在什么时候可以使用if语句确定在那时确实匹配某项并执行在找到某项之后应该出现的程序。
!编辑! 为了消除误解,我不需要检测到的物体的位置或图形,我只需要一个布尔值即可告诉是否找到了东西
答案 0 :(得分:2)
如果要获取图像中最突出的匹配项,可以使用cv2.minMaxLoc()
函数获取显示最大匹配项的位置:
res = cv2.matchTemplate(screen, template_img, cv2.TM_CCOEFF_NORMED)
_, max_val, _, max_loc = cv2.minMaxLoc(res)
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.rectangle(screen, top_left, bottom_right, (0, 255, 0), 2)
cv2.imshow('Result', screen)
所需结果将是具有最高匹配度的区域周围的边界框,如下所示:
基于查询,其想法是获得布尔结果,以确定是否找到匹配项。您可以设置阈值并设置标志,如果结果中的任何值都超过阈值。
对于上述情况,我将阈值设置为0.8:
threshold = 0.8
flag = False
for i in res:
if i.any() > threshold:
flag = True
答案 1 :(得分:1)
Jeru Luke的代码对我不起作用(如评论中所指出)。我的轻微修改将其修复:
threshold = 0.8
flag = False
if np.amax(res) > threshold:
flag = True
答案 2 :(得分:0)
在我看来,在“ pt”中第一个巧合的坐标。尝试测试该变量,无论它是否为空。
flag = False
for pt in zip(*loc[::-1]):
if pt is not None:
flag = True
cv2.rectangle(screen, pt, (pt[0] + w, pt[1] + h),(0,255,0) , 2)
答案 3 :(得分:0)
所以我认为您需要一种统计方法。如果您有很多图像(N> 30)和一个模板,则matchTemplate + minMaxLoc将平均给您一个(也许是正数)数字。您需要定义一个匹配为“真”匹配的阈值。
一种选择是从统计意义上检查匹配是否为异常值。为此,我将遵循以下过程:
1)将模板与每个图像匹配,并恢复每个图像的最佳匹配(minMaxloc)。收集所有列表。 2)计算该列表的平均值和标准偏差(np.mean()和np.std())。 3)计算标准化的“得分”:如果N> 120,则z =(rho-均值(rho))/ std(rho),或者t-stat =(rho-mean(rho))/(std(rho)/如果N <120,则sqrt(N-1))。 4)在期望的显着性水平上与适当的临界值进行比较。
这样,您将检测到哪些匹配项是异常值。
干杯, 尼古拉斯(Nicolás)