Python实现对桌面进行实时捕捉画面的方法详解

 更新时间:2023年01月28日 09:49:00   作者:奥怪的小栈  
最近在研究目标检测方面的小东西,需要到对桌面进行实时捕捉画面。所以本文来用Python实现简单的对桌面进行实时捕捉画面,感兴趣的可以了解一下

介绍

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

代码

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 码相同:

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

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

描述
480 键
491 键
502 键
513 键
524 键
535 键
546 键
557 键
568 键
579 键

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

描述
0x600 键
0x611 键
0x622 键
0x633 键
0x644 键
0x655 键
0x666 键
0x677 键
0x688 键
0x699 键
0x6AMULTIPLICATION SIGN (*) 键
0x6BPLUS SIGN (+) 键
0x6CENTER 键
0x6DMINUS SIGN (–) 键
0x6EDECIMAL POINT (.) 键
0x6FDIVISION SIGN (/) 键

下列常数代表功能键:

描述
0x70F1 键
0x71F2 键
0x72F3 键
0x73F4 键
0x74F5 键
0x75F6 键
0x76F7 键
0x77F8 键
0x78F9 键
0x79F10 键
0x7AF11 键
0x7BF12 键
0x7CF13 键
0x7DF14 键
0x7EF15 键
0x7FF16 键

到此这篇关于Python实现对桌面进行实时捕捉画面的方法详解的文章就介绍到这了,更多相关Python桌面实时捕捉画面内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python Selenium 之关闭窗口close与quit的方法

    Python Selenium 之关闭窗口close与quit的方法

    今天小编就为大家分享一篇Python Selenium 之关闭窗口close与quit的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-02-02
  • Python中查找字符串之间差异位置

    Python中查找字符串之间差异位置

    本文主要介绍了Python中查找两个字符串之间的差异位置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • 使用Python操作MySQL的小技巧

    使用Python操作MySQL的小技巧

    这篇文章主要介绍了使用Python操作MySQL的小技巧,帮助大家更好的理解和使用python,感兴趣的朋友可以了解下
    2020-09-09
  • python获取全国最新省市区数据并存入表实例代码

    python获取全国最新省市区数据并存入表实例代码

    我们在开发中经常会遇到获取省市区等信息的时候,下面这篇这篇文章主要给大家介绍了关于python获取全国最新省市区数据并存入表的相关资料,需要的朋友可以参考下
    2021-08-08
  • 利用python实时刷新基金估值效果(摸鱼小工具)

    利用python实时刷新基金估值效果(摸鱼小工具)

    这篇文章主要介绍了利用python实时刷新基金估值(摸鱼小工具),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • Python、 Pycharm、Django安装详细教程(图文)

    Python、 Pycharm、Django安装详细教程(图文)

    这篇文章主要介绍了Python、 Pycharm、Django安装详细教程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Python中私有属性“_“下划线和“__“双下划线区别

    Python中私有属性“_“下划线和“__“双下划线区别

    本文主要介绍了Python中私有属性“_“下划线和“__“双下划线区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • python和JavaScript通信

    python和JavaScript通信

    这篇文章主要介绍了python和JavaScript通信,js和python是两种语言,js处理网页数据,python可作为服务端开发,两者通过websocket进行通信,下文具体操作内容需要的小伙伴可以参考一下
    2022-04-04
  • 详细总结Python类的多继承知识

    详细总结Python类的多继承知识

    Python类的多继承知识是非常易于新手理解的,如果你是刚刚入门Python的话,欢迎参考本篇文章,本文对Python类的多继承知识作出了非常详细的解释,还有相关代码参考哦。
    2021-05-05
  • Win 10下Anaconda虚拟环境的教程

    Win 10下Anaconda虚拟环境的教程

    这篇文章主要介绍了Win 10下Anaconda虚拟环境的相关知识,本文通过实例截图相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05

最新评论