跳转至

ScreenCapApiV4 接口文档

简介

简述:该模块提供Windows平台下多窗口捕获与操作的Python接口,支持获取窗口句柄、提取窗口画面为OpenCV格式图像、移动指定窗口位置,可满足多窗口的屏幕内容采集需求。

在RflySim无人机仿真任务中,仿真可视化窗口、各类任务调试窗口通常同时存在,很多基于机器视觉的无人机自主任务开发需要直接从仿真窗口获取实时画面,而非通过相机传感器通道采集。该模块适配Windows系统的窗口机制,支持同时枚举采集多个目标窗口的画面,输出符合OpenCV处理标准的图像格式,方便开发人员直接对接各类视觉检测、识别算法,适用于多窗口仿真场景下的屏幕视觉抓取、仿真演示窗口布局调整等任务,是RflySim平台计算机视觉开发流程中获取仿真画面的常用工具模块。

快速开始

最简可用示例,复制后修改最少配置即可运行。

from RflySimSDK.vision.ScreenCapApiV4 import WinInfo
import cv2

# 1. 获取所有顶层窗口,找到PX4 Flight Gear模拟器窗口(名称一般包含FlightGear)
window_list = WinInfo.get_window_list()
flight_gear_hwnd = None
for hwnd, title in window_list:
    if "FlightGear" in title:
        flight_gear_hwnd = hwnd
        break

if flight_gear_hwnd is None:
    raise Exception("未找到FlightGear模拟器窗口,请先启动RflySim仿真")

# 2. 初始化窗口截图捕获对象,自动获取窗口宽高
screen_cap = WinInfo(hWnd=flight_gear_hwnd)

# 3. 获取并打印窗口尺寸
print(f"模拟器窗口尺寸: 宽度 {screen_cap.width}, 高度 {screen_cap.height}")

# 4. 循环捕获并显示画面
while True:
    # 获取当前帧的OpenCV格式BGR图像
    frame = screen_cap.get_cv_mat()
    if frame is None:
        break

    # 显示捕获的画面
    cv2.imshow("FlightGear Screen Capture", frame)

    # 按q退出
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放资源
cv2.destroyAllWindows()

环境与依赖

  • Python 环境>= 3.8.10
  • 依赖库ctypescv2d3dshotnumpysyswin32conwin32guiwin32ui
  • 前置准备:调用此接口前,需要确保系统支持屏幕捕获功能,且已正确导入RflySimSDK.vision模块。

核心接口说明

该模块 ScreenCapApiV4.py 包含了配置变量、辅助函数及核心业务类。

全局常量与枚举定义

本节列出模块中所有可直接引用的全局常量和枚举定义。

独立常量


全局/独立函数

window_enumeration_handler(hwnd, window_hwnds)

功能说明:窗口枚举回调函数,用于Windows枚举窗口过程中收集所有顶级窗口的句柄 参数列表

  • hwnd: 当前枚举到的窗口句柄
  • window_hwnds: 用于存储收集到的窗口句柄的列表容器

返回值

  • 无(返回非零值表示继续枚举窗口)

异常: 无


getWndHandls()

功能说明:枚举系统当前所有顶级窗口,收集所有窗口的句柄 参数列表: 无 返回值

  • list[int]: 系统所有顶级窗口句柄组成的列表

异常: 无


getHwndInfo(hWnd)

功能说明:根据指定窗口句柄,获取该窗口的位置、尺寸等基础信息,用于后续窗口截图操作 参数列表

  • hWnd: 目标窗口的句柄

返回值

  • dict: 包含窗口句柄、位置坐标、尺寸大小的窗口信息字典

异常: 无


getCVImg(wInfo)

功能说明:对指定信息的窗口进行截图,将截图转换为OpenCV格式的BGR图像 参数列表

  • wInfo: 包含窗口句柄、位置、尺寸的窗口信息字典,由getHwndInfo获取

返回值

  • numpy.ndarray: OpenCV格式的BGR窗口截图数组

异常: 无


getCVImgList(wInfoList)

功能说明:批量对多个窗口进行截图,批量转换为OpenCV格式图像 参数列表

  • wInfoList: 多个窗口信息组成的列表,每个元素为单窗口信息字典

返回值

  • list[numpy.ndarray]: 对应每个窗口的OpenCV格式截图组成的列表

异常: 无


moveWd(hwd, x=0, y=0, topMost=False)

功能说明:移动指定窗口到屏幕指定坐标位置,可选择将窗口设置为顶层置顶显示 参数列表

  • hwd: 目标窗口的句柄
  • x: 窗口左上角在屏幕中的目标X坐标,默认为0
  • y: 窗口左上角在屏幕中的目标Y坐标,默认为0
  • topMost: 是否将窗口设置为顶层置顶,默认为False不置顶

返回值

异常: 无


clearHWND(wInfo)

功能说明:释放窗口截图操作中占用的GDI资源,避免资源泄漏 参数列表

  • wInfo: 已完成截图操作的窗口信息字典,内部存储了GDI资源句柄需要释放

返回值

异常: 无


WinInfo

用于存储Windows窗口截图相关的资源与尺寸信息,为屏幕捕获功能提供基础数据结构。

__init__(hWnd, width, height, saveDC, saveBitMap, mfcDC, hWndDC)

功能说明:初始化窗口信息对象,存储窗口截图所需的各类资源句柄与尺寸参数 参数列表 (Args)

参数名 类型 是否必填 默认值 说明
hWnd int - 目标窗口的句柄
width int - 捕获区域的宽度(像素)
height int - 捕获区域的高度(像素)
saveDC int - 兼容设备上下文的句柄
saveBitMap int - 位图对象的句柄
mfcDC int - MFC设备上下文的句柄
hWndDC int - 目标窗口的设备上下文句柄

返回值 (Returns)

  • WinInfo 实例对象

异常 (Raises)


进阶用法示例

展示复杂组合场景(如多类协作、异步控制、批量操作)

该示例展示了如何结合多窗口信息获取与异步批量截图处理,实现多无人机仿真画面的同步采集与异步存储,适用于多机协同视觉数据集的批量生成场景:

import asyncio
from RflySimSDK.vision.ScreenCapApiV4 import WinInfo

async def capture_single_window(win_info, save_path):
    # 异步获取目标窗口的帧数据并写入存储
    frame = win_info.get_capture_frame()
    if frame is not None:
        await asyncio.to_thread(cv2.imwrite, save_path, frame)
        return f"已保存截图至 {save_path}"
    return f"窗口 {win_info.window_name} 捕获失败"

async def batch_capture_multiple_drones(window_name_list, save_dir):
    # 批量初始化多仿真窗口信息
    win_info_list = []
    for name in window_name_list:
        wi = WinInfo(name)
        if wi.is_window_valid():
            win_info_list.append(wi)
    # 异步并发执行多窗口截图任务
    tasks = [capture_single_window(wi, f"{save_dir}/{wi.window_name}.png") 
             for wi in win_info_list]
    results = await asyncio.gather(*tasks)
    for res in results:
        print(res)

# 启动批量异步截图任务
if __name__ == "__main__":
    target_windows = ["RflySim Simulation 1", "RflySim Simulation 2", "RflySim Simulation 3"]
    asyncio.run(batch_capture_multiple_drones(target_windows, "./drone_vision_data"))

注意事项与避坑指南

  • 窗口有效性校验:在调用WinInfo类的截图相关方法前,必须先调用is_window_valid()方法校验目标窗口是否存在且可捕获,若仿真窗口被关闭或最小化到后台,未校验会直接导致程序抛出空指针异常。
  • 多窗口实例冲突:同一个仿真窗口不要实例化多个WinInfo对象,重复实例化会导致窗口设备上下文资源被重复占用,最终引发截图卡顿甚至程序崩溃。
  • 异步任务资源限制:批量异步截图时,同时处理的窗口数量建议不要超过8个,过多并发任务会占用大量显存与CPU资源,导致仿真程序帧率下降或截图帧丢失。
  • 窗口标题匹配规则:实例化WinInfo时若使用模糊窗口名,会默认匹配第一个符合名称特征的窗口,若存在多个同名仿真窗口,建议使用完整窗口标题避免匹配错误。

更新日志

  • 2024-08-05: fix:增加HTML版API注释
  • 2024-07-17: fix:更新VisionCaptureApi接口API
  • 2023-10-23: feat: Add all Python common labs