Godot(Python脚本):如何快速将相机视口截图转为NumPy数组
优化Godot Python视口截图转NumPy数组的实时处理方案
原方案的核心瓶颈在于磁盘IO操作(存读PNG文件),这会占用大量时间。直接在内存中完成Godot Image到NumPy数组的转换,能把耗时降到毫秒级,满足近实时需求。
核心优化代码
替换原代码中存读PNG的部分,直接在内存中完成格式转换:
# 原代码保留到获取并翻转图像 old_clear_mode = self.viewport.get_clear_mode() self.viewport.set_clear_mode(Viewport.CLEAR_MODE_ONLY_NEXT_FRAME) img = self.viewport.get_texture().get_data() self.viewport.set_clear_mode(old_clear_mode) img.flip_y() # -------------------------- # 替换存读PNG的核心代码 # -------------------------- import numpy as np # 获取图像基本参数 width = img.get_width() height = img.get_height() # 提取Godot Image的原始像素字节数据(默认格式为RGBA8,4字节/像素) pixel_bytes = img.get_data() # 直接转成NumPy数组(零拷贝/低拷贝,效率极高) # 格式为 (高度, 宽度, 4),对应RGBA通道 np_img = np.frombuffer(pixel_bytes, dtype=np.uint8).reshape((height, width, 4)) # 转换为RGB格式(去掉Alpha通道,根据需求可选) rgb_img = np_img[..., :3] # 执行你的边缘锐化处理(直接传入NumPy数组) sharpened_img = self.sharpen_edges(rgb_img) # 若需保存结果,直接用NumPy/PyPlot写入(跳过中间文件) plt.imsave('temp2.png', sharpened_img) # -------------------------- # 可选:将处理后的数组转回Godot Image用于场景显示 # -------------------------- # 补全Alpha通道(255表示不透明) rgba_processed = np.concatenate([sharpened_img, np.full((height, width, 1), 255, dtype=np.uint8)], axis=-1) # 转回字节数据 processed_bytes = rgba_processed.tobytes() # 创建Godot Image并赋值 new_godot_img = Image.create(width, height, False, Image.FORMAT_RGBA8) new_godot_img.set_data(processed_bytes) # 可将该图像赋值给TextureRect等控件实时显示处理结果
关键优化点说明
- 跳过磁盘IO:完全去掉PNG文件的存读操作,所有转换在内存中完成,这是速度提升的核心。
- 高效格式转换:利用
np.frombuffer直接读取Godot Image的原始字节缓冲区,避免额外的数据拷贝。 - 格式匹配:Godot默认图像格式为
RGBA8,所以数组形状为(height, width, 4);如果你的场景使用其他格式(如RGB8),需要对应调整通道数和Image.FORMAT_*常量。
额外优化建议
- 复用数组空间:如果在
_process中持续处理,可预先分配NumPy数组,避免每次创建新数组的开销。 - 替换PIL为NumPy/OpenCV:如果你的
sharpen_edges函数基于PIL实现,改成直接用NumPy或OpenCV操作,进一步消除格式转换的耗时。 - 视口设置优化:如果不需要完整分辨率的截图,可降低视口的缩放比例(通过
Viewport.set_size()),减少处理的数据量。
内容的提问来源于stack exchange,提问作者Mechanic
相关产品推荐
相关产品推荐

