修复了从PIL图像到OpenCV垫的图像转换效率低下的问题



我正在一个大小为 800x600 的屏幕截图实时流上运行神经网络。由于我只有大约 3fps,我做了一些故障排除,并找出了每一步大约花费了多少时间:

  • 截图:12ms
  • 图像处理:280ms
  • 物体检测和盒子可视化:16ms
  • 显示图像:0.5ms

我正在使用mss来截取屏幕截图(文档(。

下面是没有对象检测部分的代码:

import numpy as np
import cv2
from PIL import Image
import mss
monitor = {"top": 40, "left": 0, "width": 800, "height": 600}
with mss.mss() as sct:
while True:
# # Screenshot:
image = sct.grab(monitor)
# # Image processing:
image = Image.frombytes("RGB", image.size, image.bgra, "raw", "RGBX")
(im_width, im_height) = image.size
image_np = np.array(image.getdata()).reshape((im_height, im_width, 3)).astype(np.uint8)
# # Object detection and box visualisation:
# ...
# # Displaying image:
cv2.imshow("Object Detection", image_np)

关于如何使它更快的任何想法?

问题是您的方法从 BGRA 图像格式开始。这是很多数据,可能没有必要。可能有更有效的方法来抓取屏幕截图并将其转换为 OpenCV 图像。在我的慢速机器上,这是一种大约需要56 毫秒的方法:

import ctypes
import datetime
import cv2
import numpy as np
from PIL import ImageGrab

# workaround to allow ImageGrab to capture the whole screen
user32 = ctypes.windll.user32
user32.SetProcessDPIAware()
# measure running time
start_time = datetime.datetime.now()
# take a full screenshot of the desktop
image = np.array(ImageGrab.grab( bbox= (40, 0, 800, 600) ))
# convert from RGB to BGR order so that colors are displayed correctly
mat = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
# compute elapsed time
delta = datetime.datetime.now() - start_time
elapsed_time_ms = int(delta.total_seconds() * 1000)
print('* Elapsed time:', elapsed_time_ms, 'ms')
cv2.imshow('mat', mat)
cv2.waitKey()

每帧处理 280 毫秒,您将获得 3-4 帧/秒。你几乎只有2个选择。

要么分享你的代码,希望我们能改进它。

或者,使用多处理,比如说 4 个 CPU 内核,将第一帧提供给第一个内核,将第二帧提供给第二个内核,依此类推,循环,您可能每 70 毫秒输出一帧,导致 14 fps。

使用这些行而不是"图像处理:" 我第一篇文章中的行解决了我的问题:

image = sct.grab(monitor)
image_np = np.array(image)
image_np = cv2.cvtColor(image_np, cv2.COLOR_RGBA2RGB)

我之前已经尝试只使用前 2 行,但我收到此错误:

ValueError: Cannot feed value of shape (1, 600, 800, 4) for Tensor 'image_tensor:0', which has shape '(?, ?, ?, 3)'

我没有想到将图像从 rgba 转换为 rgb 会解决这个问题。我现在得到大约 30fps。

最新更新