OpenCV模板匹配真/假

7gcisfzg  于 2022-11-15  发布在  其他
关注(0)|答案(4)|浏览(177)

所以我不知道从标题上看是否容易理解,但我的问题与OpenCV模板匹配有关,当程序可以说“Template found”并为while循环返回布尔值时。P.S我知道一直保存和删除图像是非常低效的,但它是有效的

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语句来确定某个东西在那个点确实匹配,并执行应该在找到某个东西之后出现的程序。
!EDIT!为了消除误解,我不需要检测到的对象的位置或绘图,我只需要一个布尔值,告诉是否找到了什么

wa7juj8i

wa7juj8i1#

如果要获得图像中最突出的匹配,可以使用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
knsnq2tg

knsnq2tg2#

Jeru Luke的代码对我不起作用(正如评论中指出的)。我稍微修改了一下就修复了它:

threshold = 0.8
flag = False
if np.amax(res) > threshold:
    flag = True
c3frrgcw

c3frrgcw3#

所以我认为你需要一个统计方法。如果你有很多图像(N〉30)和一个模板,matchTemplate + minMaxLoc会给予你一个平均数(也许是正数)。你需要定义一个阈值,超过这个阈值的匹配是真匹配。
另一种方法是从统计学的Angular 检查匹配是否是异常值,为此,我将遵循以下步骤:
1)将模板与每个图像匹配,并恢复每个图像的最佳匹配(minMaxloc)。将所有图像收集在一个列表中。2)计算该列表的平均值和标准差(np.mean()和np.std())。3)计算标准化“得分”:如果N〉120,则z =(rho -平均值(rho))/标准差(rho),或者如果N〈120,则t-stat =(rho-平均值(rho))/(标准差(rho)/sqrt(N-1))。4)在期望的显著性水平上与适当的临界值进行比较。
通过这种方式,您可以检测哪些匹配项是离群值。
干杯尼古拉斯

k7fdbhmy

k7fdbhmy4#

我想现在已经很晚了,但是我面临着和你一样的问题。问题是在你的情况下,cv2总是会找到多个匹配,即使你把阈值设置为100%也没关系,原因是你想找到的图像不是很独特,所以opencv会错过匹配。尝试使用hsv掩码和一些其他的过滤器来缩小可能性,也许你会发现一个匹配在您的阈值举行。我希望我的想法是明确的。一个简单的旁路是使用pyautogui的locatescreen函数来点is,因为它会返回一个找到的对象的坐标或null。祝你好运。

相关问题