You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MSS屏幕捕获结合OpenCV无法实现目标检测的问题求助

实时屏幕捕获与目标检测问题求助

我是Python新手,为学习编写了一个实时屏幕捕获并做目标检测的简易程序:

  • 最初基于MSS和OpenCV写的脚本,怎么操作都没法实现目标检测;找到一个PyAutoGUI+OpenCV的同类可用代码,但帧率表现很差
  • 后来自己排查出两个问题:一是PNG文件名拼写错误,二是要把cv2.imshow语句放在判断逻辑之后,修正后程序能运行但效果不好
  • 尝试引入cv2.Canny()算子,修改后完全没有检测输出;按照建议更换不同OpenCV匹配方法后,不管怎么调整阈值,只要捕获区域里有物体就会持续触发检测,现在求这个问题的解决方案

相关代码

代码1(MSS+OpenCV基础版本)

import time
import cv2
import mss
import numpy


#template and dimensions
template = cv2.imread("m2.png")
template_gray = cv2.cvtColor(template, cv2.COLOR_BGRA2GRAY)
template_w, template_h = template_gray.shape[::-1]

with mss.mss() as sct:
    # Part of the screen to capture
    monitor = {"top": 523, "left": 247, "width": 875, "height": 679}

    while True:
        last_time = time.time()
        
        # Get raw pixels from the screen, save it to a Numpy array
        img = numpy.array(sct.grab(monitor))

        # Display the picture
        cv2.imshow("Normal", img)

        # Display the picture in grayscale
        img_gray = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)

        res = cv2.matchTemplate(
            image = img_gray,
            templ = template_gray, 
            method= cv2.TM_CCOEFF_NORMED
        )

        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

        #threshold
        if max_val >= 0.5:

            img = cv2.rectangle(
                img = img,
                pt1 = max_loc,
                pt2 = (
                    max_loc[0] + template_w, # = pt2 x 
                    max_loc[1] + template_h # = pt2 y
                ),
                color = (0,255,0),
                thickness = 3 #fill the rectangle
            )



        print("fps: {}".format(1 / (time.time() - last_time)))

        # Press "q" to quit
        if cv2.waitKey(25) & 0xFF == ord("q"):
            cv2.destroyAllWindows()
            break

代码2(PyAutoGUI+OpenCV版本)

#imports
from re import template
import cv2
import pyautogui
from time import sleep

#No cooldown time
pyautogui.PAUSE = 0

#template and dimensions
template = cv2.imread("b1.png")
template_gray = cv2.cvtColor(template, cv2.COLOR_RGB2GRAY)
template_w, template_h = template_gray.shape[::-1]

# game window dimensions
x, y, w, h = 523, 247, 875, 679

#wait
sleep(3)

#main

while True:

    #screenshot = img
    pyautogui.screenshot("image.png", (x, y, w, h))
    image = cv2.imread("image.png")

    while True:

        image_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)

        result = cv2.matchTemplate(
            image = image_gray,
            templ = template_gray,
            method = cv2.TM_CCOEFF_NORMED
        )

        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

        #threshold
        if max_val >= 0.1:
            #pyautogui.click(
            #    x = max_loc[0] + x, #screen x
            #    y = max_loc[1] + y  #screen y
            #)

            image = cv2.rectangle(
                img = image,
                pt1 = max_loc,
                pt2 = (
                    max_loc[0] + template_w, # = pt2 x 
                    max_loc[1] + template_h # = pt2 y
                ),
                color = (0,0,255),
                thickness = -1 #fill the rectangle
            )
        
        else:
            break

代码3(引入Canny算子的MSS版本)

import time
import Options.settings as set
import time
import pyautogui as pt
from time import sleep
import cv2
import mss
import numpy

x = 0

offset = set.offset
create_logs = set.create_logs

#template and dimensions
template = cv2.imread("m2.png")
template_gray = cv2.cvtColor(template, cv2.COLOR_BGRA2GRAY)
template_canny = cv2.Canny(template_gray, 79, 100)
template_w, template_h = template_canny.shape[::-1]

with mss.mss() as sct:
    # Part of the screen to capture
    monitor = {"top": 523, "left": 1600, "width": 230, "height": 359}

    while True:
        last_time = time.time()
        
        # Get raw pixels from the screen, save it to a Numpy array
        img = numpy.array(sct.grab(monitor))

        # Display the picture
        cv2.imshow("Normal", img)

        # Display the picture in grayscale
        img_gray = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)
        img_canny = cv2.Canny(img_gray, 100, 115)

        res = cv2.matchTemplate(
            image = img_canny,
            templ = template_canny, 
            method= cv2.TM_CCOEFF_NORMED
        )

        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

        #threshold
        if max_val >= 0.6:
            x = x + 1
            print(f'{x} is detected')
        
            img = cv2.rectangle(
                img = img,
                pt1 = max_loc,
                pt2 = (
                    max_loc[0] + template_w, # = pt2 x 
                    max_loc[1] + template_h # = pt2 y
                ),
                color = (0,255,0),
                thickness = 3 #fill the rectangle
            )
        # Display the picture
        cv2.imshow("Normal", img)



        #print("fps: {}".format(1 / (time.time() - last_time)))

        # Press "q" to quit
        if cv2.waitKey(25) & 0xFF == ord("q"):
            cv2.destroyAllWindows()
            break

模板图m2.png及屏幕捕获示例参考对应截图


内容的提问来源于stack exchange,提问作者Forseen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 05:25:21