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
相关产品推荐
相关产品推荐

