首页 > 解决方案 > python - OpenCV 误报

问题描述

我在 python 中使用 OpenCV,当我把阈值调低时,我得到了大量的误报,但是当我把它调高时,我不再得到我正在寻找的图像或任何东西。我必须把它调低到 0.4 才能得到任何东西。有没有人有任何想法?下面是我截取的截图,我在截图中寻找的模板图像,以及结果。

screen = (0, 0, 1920, 1080)
ImageGrab.grab(screen).save("screenshots/screenshot.jpg")
time.sleep(2)

# Read the main image
img_rgb = cv2.imread('screenshots/screenshot.jpg')

# Convert to grayscale
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)

# Read the template
template = cv2.imread('monsters/knight.jpg', 0)

# Store width and height of template in w and h
w, h = template.shape[::-1]

res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.4
loc = np.where(res >= threshold)

for pt in zip(*loc[::-1]):
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 255, 255), 2)

cv2.imshow('Detected', img_rgb)
cv2.waitKey(0)

误报

'骑士.jpg'

'截图/screenshot.jpg'

标签: pythonopencv

解决方案


您的模板与搜索空间的比例不同。

模板和搜索图像的比较

由于matchTemplate仅检查单个比例,因此您不会得到良好的检测。您需要更正比例或搜索各种比例。

这是一些(快速)代码,可以在各种范围内搜索:

overall_score = np.zeros_like(img_gray)
# search scales 1.0, 1.1, 1.2...
scales = np.arange(1.0, 2.0, 0.1)
for scale in scales:
    # resize the template to that scale
    t_w = int(w * scale)
    t_h = int(h * scale)
    scaled_template = cv2.resize(template, (t_w, t_h))
    res = cv2.matchTemplate(img_gray, scaled_template, cv2.TM_CCOEFF_NORMED)
    # pad the results so that we can combine them across each scale
    res = cv2.copyMakeBorder(
        res, t_h // 2, (t_h - 1) // 2, t_w // 2, (t_w - 1) // 2, cv2.BORDER_CONSTANT
    )
    # combine the results
    overall_score = np.maximum(res, overall_score)
# we can use a much higher threshold
threshold = 0.9
loc = np.where(overall_score >= threshold)

# since we padded the images, coordinates are centers rather than top-left
for pt in zip(*loc[::-1]):
    cv2.rectangle(
        img_rgb,
        (pt[0] - w // 2, pt[1] - h // 2),
        (pt[0] + w // 2, pt[1] + h // 2),
        (0, 255, 255),
        2,
    )
cv2.imwrite("detections.png", img_rgb)

使用此代码可以得到预期的结果:

在此处输入图像描述


推荐阅读