Python實(shí)現(xiàn)對(duì)桌面進(jìn)行實(shí)時(shí)捕捉畫面的方法詳解
介紹
最近在研究目標(biāo)檢測方面的小東西,需要到對(duì)桌面進(jìn)行實(shí)時(shí)捕捉畫面,獲取畫面后再檢測,達(dá)到實(shí)時(shí)桌面目標(biāo)檢測的目的,所以寫了一段小代碼來實(shí)現(xiàn)該功能,實(shí)測速度很快,符合我的需求。特此記錄一下。
代碼
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]
實(shí)際截圖范圍,分別為x,y,(1.0, 1.0)表示全屏檢測,越低檢測范圍越小(始終保持屏幕中心為中心)
window_name : str
顯示窗口名
exit_key : int
結(jié)束窗口的退出鍵值,為鍵盤各鍵對(duì)應(yīng)的ASCII碼值,默認(rèn)是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) # 實(shí)例化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 # 屏幕中心點(diǎn)坐標(biāo)
# 截圖區(qū)域
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])) # 原點(diǎn)
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將圖片轉(zhuǎn)為數(shù)組,cvtColor將BRGA轉(zhuǎn)為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 根據(jù)窗口大小設(shè)置圖片大小
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: # 默認(rèn):ESC
cv2.destroyAllWindows()
exit("結(jié)束")代碼講解
功能實(shí)現(xiàn)思路主要是使用 mss 庫進(jìn)行截圖,并使用 opencv 庫進(jìn)行圖像顯示和處理。
首先,使用 argparse 庫解析傳入的參數(shù),設(shè)置檢測范圍的大小。
然后,使用 mss 庫實(shí)例化一個(gè)截圖對(duì)象 cap 。
接著,設(shè)置屏幕的寬和高,并計(jì)算屏幕中心點(diǎn)的坐標(biāo)。
之后,根據(jù)傳入的參數(shù)計(jì)算游戲內(nèi)截圖區(qū)域的寬高和原點(diǎn)坐標(biāo),并將其保存在變量 mointor 中。
定義了一個(gè)函數(shù) grab_screen_mss ,使用 cap.grab 截取圖片,并用 np.array 將圖片轉(zhuǎn)為數(shù)組,然后用 cvtColor 將 BRGA 轉(zhuǎn)為 BRG ,去掉了透明通道。
定義了一個(gè) run 函數(shù),在其中不斷循環(huán),判斷是否按下 ctrl+U ,若按下,則窗口始終置頂。
然后調(diào)用 grab_screen_mss 函數(shù)獲取截圖,使用 cv2 庫進(jìn)行圖像顯示,并設(shè)置顯示窗口的大小。
如果窗口需要置頂,則使用 win32com 庫和 win32gui 庫置頂窗口。
最后,使用 cv2 庫的 waitKey 函數(shù)等待用戶操作,按下 ESC 鍵退出程序。
調(diào)用示例
sc = ScreenCapture()
sc.run()參數(shù)解釋:
screen_frame : Tuple[int, int]
屏幕寬高,分別為x,y
region : Tuple[float, float]
實(shí)際截圖范圍,分別為x,y,(1.0, 1.0)表示全屏檢測,越低檢測范圍越小(始終保持屏幕中心為中心)
window_name : str
顯示窗口名
exit_key : int
結(jié)束窗口的退出鍵值,為鍵盤各鍵對(duì)應(yīng)的ASCII碼值,默認(rèn)是ESC鍵
其他
鍵盤各鍵對(duì)應(yīng)的ASCII碼值 (0x指16進(jìn)制,delete鍵的ascii碼值是0x2e,也即十進(jìn)制的46)
- 0x1 鼠標(biāo)左鍵
- 0x2 鼠標(biāo)右鍵
- 0x3 CANCEL 鍵
- 0x4 鼠標(biāo)中鍵
- 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 鍵與數(shù)字 0 – 9 的 ASCII 碼相同:
| 值 | 描述 |
|---|---|
| 48 | 0 鍵 |
| 49 | 1 鍵 |
| 50 | 2 鍵 |
| 51 | 3 鍵 |
| 52 | 4 鍵 |
| 53 | 5 鍵 |
| 54 | 6 鍵 |
| 55 | 7 鍵 |
| 56 | 8 鍵 |
| 57 | 9 鍵 |
下列常數(shù)代表數(shù)字鍵盤上的鍵:
| 值 | 描述 |
|---|---|
| 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 (/) 鍵 |
下列常數(shù)代表功能鍵:
| 值 | 描述 |
|---|---|
| 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 鍵 |
到此這篇關(guān)于Python實(shí)現(xiàn)對(duì)桌面進(jìn)行實(shí)時(shí)捕捉畫面的方法詳解的文章就介紹到這了,更多相關(guān)Python桌面實(shí)時(shí)捕捉畫面內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實(shí)戰(zhàn)之夢(mèng)幻鋼琴小游戲的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了如何利用Python語言編寫一款界面化的(Tkinter)電子鋼琴小程序,文中的示例代碼講解詳細(xì),感興趣的可以了解一下2023-02-02
python使用OpenCV模塊實(shí)現(xiàn)圖像的融合示例代碼
這篇文章主要介紹了python使用OpenCV模塊實(shí)現(xiàn)圖像的融合示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
python生成并處理uuid的實(shí)現(xiàn)方式
這篇文章主要介紹了python生成并處理uuid的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03
Python實(shí)現(xiàn)的十進(jìn)制小數(shù)與二進(jìn)制小數(shù)相互轉(zhuǎn)換功能
這篇文章主要介紹了Python實(shí)現(xiàn)的十進(jìn)制小數(shù)與二進(jìn)制小數(shù)相互轉(zhuǎn)換功能,結(jié)合具體實(shí)例形式詳細(xì)分析了二進(jìn)制與十進(jìn)制相互轉(zhuǎn)換的原理及Python相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-10-10
Pandas提高數(shù)據(jù)分析效率的13個(gè)技巧匯總
這篇文章主要是為大家歸納整理了13個(gè)工作中常用到的pandas使用技巧,方便更高效地實(shí)現(xiàn)數(shù)據(jù)分析,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-05-05
python獲取異常信息exc_info和print_exc的使用
python通過sys.exc_info獲取異常信息,通過traceback.print_exc打印堆棧信息,包括錯(cuò)誤類型和錯(cuò)誤位置等信息,本文就來介紹一下具體用法,感興趣的可以了解一下2023-12-12

