Python实现对桌面进行实时捕捉画面的方法详解
作者:奥怪的小栈 发布时间:2022-09-06 19:12:59
介绍
最近在研究目标检测方面的小东西,需要到对桌面进行实时捕捉画面,获取画面后再检测,达到实时桌面目标检测的目的,所以写了一段小代码来实现该功能,实测速度很快,符合我的需求。特此记录一下。
代码
import argparse
import time
import cv2
import keyboard
import mss
import numpy as np
import win32com.client
import win32con
import win32gui
class 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
self.img = None
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 update_img(self, img):
self.img = img
def get_img(self):
return self.img
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
if self.img is None:
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 键 |
来源:https://segmentfault.com/a/1190000043353770
猜你喜欢
- Python中有一个有趣的语法,只要定义类型的时候,实现__call__函数,这个类型就成为可调用的。换句话说,我们可以把这个类型的对象当作
- PyCharm IDE 窗口布局PyCharm 调试代码实例(这里我以自己的代码为例)__author__ =&nbs
- 整理了一些JS的常用方法,包括验证啊,全选反选啊,ajax请求啊之类的,因为就是自己用的,写的都比较简单,就算抛砖引玉吧,喜欢的就拿去,不喜
- 使用 types 增强vscode中javascript代码提示功能微软的vscode编辑器是开发typescript项目的不二首选,其本身
- 用Python画一个平面的太阳系得到一些朋友的欣赏,然后有同学提出了绘制三维太阳系的要求。从Python画图的角度来说,三维太阳系其实并不难
- 这篇文章主要介绍了pyftplib中文乱码问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋
- Django自带有个强大的后天管理系统,接下来我就给大家介绍一下x的admin一些强大的操作及后台美化。首先给大家介绍一些xadmin的注册
- 本文实例讲述了PHP登录验证功能。分享给大家供大家参考,具体如下:登录界面具体实现方法如下:login.html<!DOCTYPE h
- jQuery是最近比较火的一个JavaScript库,从del.icio.us/上相关的收藏可见一斑。到目前为之jQuery已经发布到1.2
- readline()方法从文件中读取一整行。尾部的换行符保持在字符串中。如果大小参数且非负,那么一个最大字节数,包括结尾的换行和
- python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误。你可以使用该功能来调试python程序。异常处理: 本站
- Python实现新版正方系统滑动验证码识别算法和方案步骤一:点击数据分析点击滑动按钮,将发送一个请求到 /zfcaptchaLogin请求内
- 阅读上一章:Chapter 13 为文字指定样式Chapter 14 图片替换随着更多设计师与开发者开始使用标准(特别是CSS),每天都会有
- InstrRev描述:返回某字符串在另一个字符串中出现的从结尾计起的位置。语法:InstrRev(string1, string2
- 本文实例分析了python删除指定类型(或非指定)的文件用法。分享给大家供大家参考。具体如下:如下,删除目录下非源码文件import os
- turtle库是一个很经典的绘图库,其最初来自于1967年创造的logo编程语言,之后被Python编写放到了Python的内置模块中。网络
- 本文实例讲述了Python简单实现两个任意字符串乘积的方法。分享给大家供大家参考,具体如下:题目:给定两个任意数字组成的字符串,求乘积,字符
- 啥是依赖规范可以以各种形式指定项目的依赖项,取决于依赖项的类型以及安装项目可能需要的可选约束版本约束^ 约束编写规范允许的版本范围^1.2.
- TensorFlow™是一个基于数据流编程(dataflow programming)的符号数学系统,被广泛应用于各类机器学习(machin
- 目录一、Python GUI 编程简介二、流行GUI框架总结三、代码演示四、界面一、Python GUI 编程简介Tkinter 模块(Tk