最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

世界视点!python简单实现对桌面进行实时捕捉画面

来源:博客园

介绍

最近在研究目标检测方面的小东西,需要到对桌面进行实时捕捉画面,获取画面后再检测,达到实时桌面目标检测的目的,所以写了一段小代码来实现该功能,实测速度很快,符合我的需求。特此记录一下。

代码

import argparseimport timeimport cv2import keyboardimport mssimport numpy as npimport win32com.clientimport win32conimport win32guiclass ScreenCapture:    """    parameters    ----------        screen_frame : Tuple[int, int]            屏幕宽高,分别为x,y        region : Tuple[float, float]            实际截图范围,分别为x,y,(1.0, 1.0)表示全屏检测,越低检测范围越小(始终保持屏幕中心为中心)        window_name : str            显示窗口名        exit_key : int            结束窗口的退出键值,为键盘各键对应的ASCII码值,默认是ESC键    """    def __init__(self, screen_frame=(1920, 1080), region=(0.5, 0.5), window_name="test", exit_key=0x1B):        self.parser = argparse.ArgumentParser()        self.parser.add_argument("--region", type=tuple, default=region,                                 help="截图范围;分别为x,y,(1.0, 1.0)表示全屏检测,越低检测范围越小(始终保持屏幕中心为中心)")        self.parser_args = self.parser.parse_args()        self.cap = mss.mss(mon=-1, optimize=True)  # 实例化mss,并使用高效模式        self.screen_width = screen_frame[0]  # 屏幕的宽        self.screen_height = screen_frame[1]  # 屏幕的高        self.mouse_x, self.mouse_y = self.screen_width // 2, self.screen_height // 2  # 屏幕中心点坐标        # 截图区域        self.GAME_WIDTH, self.GAME_HEIGHT = int(self.screen_width * self.parser_args.region[0]), int(            self.screen_height * self.parser_args.region[1])  # 宽高        self.GAME_LEFT, self.GAME_TOP = int(0 + self.screen_width // 2 * (1. - self.parser_args.region[0])), int(            0 + 1080 // 2 * (1. - self.parser_args.region[1]))  # 原点        self.RESZIE_WIN_WIDTH, self.RESIZE_WIN_HEIGHT = self.screen_width // 4, self.screen_height // 4  # 显示窗口大小        self.mointor = {            "left": self.GAME_LEFT,            "top": self.GAME_TOP,            "width": self.GAME_WIDTH,            "height": self.GAME_HEIGHT        }        self.window_name = window_name        self.Exit_key = exit_key    def grab_screen_mss(self, monitor):        # cap.grab截取图片,np.array将图片转为数组,cvtColor将BRGA转为BRG,去掉了透明通道        return cv2.cvtColor(np.array(self.cap.grab(monitor)), cv2.COLOR_BGRA2BGR)    def run(self):        SetForegroundWindow_f = 0  # 判断是否需要置顶窗口        while True:            # 判断是否按下 ctrl+U 窗口始终置顶            if keyboard.is_pressed("ctrl+U"):                while keyboard.is_pressed("ctrl+U"):                    continue                if SetForegroundWindow_f == 0:                    SetForegroundWindow_f = 1                    time.sleep(1)                    continue                else:                    SetForegroundWindow_f = 0            img = self.grab_screen_mss(self.mointor)            cv2.namedWindow(self.window_name, cv2.WINDOW_NORMAL)  # cv2.WINDOW_NORMAL 根据窗口大小设置图片大小            cv2.resizeWindow(self.window_name, self.RESZIE_WIN_WIDTH, self.RESIZE_WIN_HEIGHT)            cv2.imshow(self.window_name, img)            if SetForegroundWindow_f == 1:                shell = win32com.client.Dispatch("WScript.Shell")                shell.SendKeys("%")                win32gui.SetForegroundWindow(win32gui.FindWindow(None, self.window_name))                win32gui.ShowWindow(win32gui.FindWindow(None, self.window_name), win32con.SW_SHOW)            if cv2.waitKey(1) & 0XFF == self.Exit_key:  # 默认:ESC                cv2.destroyAllWindows()                exit("结束")

代码讲解

功能实现思路主要是使用 mss 库进行截图,并使用 opencv 库进行图像显示和处理。

首先,使用 argparse 库解析传入的参数,设置检测范围的大小。


(资料图片)

然后,使用 mss 库实例化一个截图对象 cap 。

接着,设置屏幕的宽和高,并计算屏幕中心点的坐标。

之后,根据传入的参数计算游戏内截图区域的宽高和原点坐标,并将其保存在变量 mointor 中。

定义了一个函数 grab_screen_mss ,使用 cap.grab 截取图片,并用 np.array 将图片转为数组,然后用 cvtColor 将 BRGA 转为 BRG ,去掉了透明通道。

定义了一个 run 函数,在其中不断循环,判断是否按下 ctrl+U ,若按下,则窗口始终置顶。

然后调用 grab_screen_mss 函数获取截图,使用 cv2 库进行图像显示,并设置显示窗口的大小。

如果窗口需要置顶,则使用 win32com 库和 win32gui 库置顶窗口。

最后,使用 cv2 库的 waitKey 函数等待用户操作,按下 ESC 键退出程序。

调用示例

sc = ScreenCapture()    sc.run()

参数解释:

screen_frame : Tuple[int, int]
屏幕宽高,分别为x,y    region : Tuple[float, float]        实际截图范围,分别为x,y,(1.0, 1.0)表示全屏检测,越低检测范围越小(始终保持屏幕中心为中心)    window_name : str        显示窗口名    exit_key : int        结束窗口的退出键值,为键盘各键对应的ASCII码值,默认是ESC键

其他

键盘各键对应的ASCII码值 (0x指16进制,delete键的ascii码值是0x2e,也即十进制的46)

0x1 鼠标左键0x2 鼠标右键0x3 CANCEL 键0x4 鼠标中键0x8 BACKSPACE 键0x9 TAB 键0xC CLEAR 键0xD ENTER 键0x10 SHIFT 键0x11 CTRL 键0x12 MENU 键0x13 PAUSE 键0x14 CAPS LOCK 键0x1B ESC 键0x20 SPACEBAR 键0x21 PAGE UP 键0x22 PAGE DOWN 键0x23 END 键0x24 HOME 键0x25 LEFT ARROW 键0x26 UP ARROW 键0x27 RIGHT ARROW 键0x28 DOWN ARROW 键0x29 SELECT 键0x2A PRINT SCREEN 键0x2B EXECUTE 键0x2C SNAPSHOT 键0x2D INSERT 键0x2E DELETE 键0x2F HELP 键0x90 NUM LOCK 键

A 至 Z 键与 A – Z 字母的 ASCII 码相同:

值 描述65 A 键66 B 键67 C 键68 D 键69 E 键70 F 键71 G 键72 H 键73 I 键74 J 键75 K 键76 L 键77 M 键78 N 键79 O 键80 P 键81 Q 键82 R 键83 S 键84 T 键85 U 键86 V 键87 W 键88 X 键89 Y 键90 Z 键

0 至 9 键与数字 0 – 9 的 ASCII 码相同:

值 描述48 0 键49 1 键50 2 键51 3 键52 4 键53 5 键54 6 键55 7 键56 8 键57 9 键

下列常数代表数字键盘上的键:

值 描述0x60 0 键0x61 1 键0x62 2 键0x63 3 键0x64 4 键0x65 5 键0x66 6 键0x67 7 键0x68 8 键0x69 9 键0x6A MULTIPLICATION SIGN (*) 键0x6B PLUS SIGN (+) 键0x6C ENTER 键0x6D MINUS SIGN (–) 键0x6E DECIMAL POINT (.) 键0x6F DIVISION SIGN (/) 键

下列常数代表功能键:

值 描述0x70 F1 键0x71 F2 键0x72 F3 键0x73 F4 键0x74 F5 键0x75 F6 键0x76 F7 键0x77 F8 键0x78 F9 键0x79 F10 键0x7A F11 键0x7B F12 键0x7C F13 键0x7D F14 键0x7E F15 键0x7F F16 键

关键词: 显示窗口 检测范围 屏幕中心