用Python从屏幕捕获视频数据

Ada*_*ile 15 python opencv screenshot numpy

有没有办法使用Python(可能使用OpenCV或PIL)连续抓取全部或部分屏幕的帧,至少15 fps或更高?我已经看到它用其他语言完成,所以理论上它应该是可能的.

我不需要将图像数据保存到文件中.我实际上只是希望它输出一个包含原始RGB数据的数组(比如在一个numpy数组或其他东西),因为我只是把它拿到并发送到一个大的LED显示器(可能在重新调整它之后).

Nea*_*bfi 20

mss还有另一种解决方案可以提供更好的帧速率.(使用MacOS Sierra在Macbook Pro上测试过)

import numpy as np
import cv2
from mss import mss
from PIL import Image

mon = {'top': 160, 'left': 160, 'width': 200, 'height': 200}

sct = mss()

while 1:
    sct.get_pixels(mon)
    img = Image.frombytes('RGB', (sct.width, sct.height), sct.image)
    cv2.imshow('test', np.array(img))
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break
Run Code Online (Sandbox Code Playgroud)

  • 截至 2019 年 7 月,此代码将触发以下错误:“AttributeError:‘MSS’对象没有属性‘get_pixels’”。 (6认同)
  • 另一种解决方法是使用 `mss().grab(window)` 代码看起来类似于: `screenshot = mss.mss().grab(window)` `img = Image.frombytes("RGB", (screenshot .宽度、屏幕截图.高度)、屏幕截图.rgb)` (4认同)
  • @YakovK要规避此问题,请安装旧版本的mss:`pip uninstall mss`,`pip install mss==2.0.22` (2认同)

mlz*_*lz7 18

使用上述所有解决方案,我无法获得可用的帧速率,直到我按以下方式修改我的代码:

import numpy as np
import cv2
from mss import mss
from PIL import Image

bounding_box = {'top': 100, 'left': 0, 'width': 400, 'height': 300}

sct = mss()

while True:
    sct_img = sct.grab(bounding_box)
    cv2.imshow('screen', np.array(sct_img))

    if (cv2.waitKey(1) & 0xFF) == ord('q'):
        cv2.destroyAllWindows()
        break
Run Code Online (Sandbox Code Playgroud)

使用此解决方案,我可以轻松获得 20+ 帧/秒。

作为参考,请查看此链接:OpenCV/Numpy example with mss

  • Mac Mini 上 65 fps - 太棒了! (2认同)
  • 保存为 .npy 文件轻而易举,我每 10-15 毫秒就会收到一帧。结果是 100FPS - 67FPS。我想SSD在这里也扮演着重要的角色。 (2认同)

ibi*_*nja 11

您将需要使用Pillow(PIL)库中的ImageGrab并将捕获转换为numpy数组.当你有阵列时,你可以使用opencv随心所欲.我将捕获转换为灰色,并使用imshow()作为演示.

这是一个快速入门的代码:

from PIL import ImageGrab
import numpy as np
import cv2

img = ImageGrab.grab(bbox=(100,10,400,780)) #bbox specifies specific region (bbox= x,y,width,height *starts top-left)
img_np = np.array(img) #this is the array obtained from conversion
frame = cv2.cvtColor(img_np, cv2.COLOR_BGR2GRAY)
cv2.imshow("test", frame)
cv2.waitKey(0)
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)

你可以用你喜欢的频率在那里插入一个阵列来保持捕捉帧.之后,您只需解码帧.不要忘记在循环之前添加:

fourcc = cv2.VideoWriter_fourcc(*'XVID')
vid = cv2.VideoWriter('output.avi', fourcc, 6, (640,480))
Run Code Online (Sandbox Code Playgroud)

在循环内你可以添加:

vid.write(frame) #the edited frame or the original img_np as you please
Run Code Online (Sandbox Code Playgroud)

更新
最终结果看起来像这样(如果你想实现一个帧流.存储为视频只是在捕获的屏幕上使用opencv的演示):

from PIL import ImageGrab
import numpy as np
import cv2
while(True):
    img = ImageGrab.grab(bbox=(100,10,400,780)) #bbox specifies specific region (bbox= x,y,width,height)
    img_np = np.array(img)
    frame = cv2.cvtColor(img_np, cv2.COLOR_BGR2GRAY)
    cv2.imshow("test", frame)
    cv2.waitKey(0)
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)

希望有所帮助


sza*_*ián 6

基于这篇文章和其他帖子,我做了这样的事情。它截取屏幕截图并写入视频文件而不保存img。

import cv2
import numpy as np
import os
import pyautogui

output = "video.avi"
img = pyautogui.screenshot()
img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
#get info from img
height, width, channels = img.shape
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output, fourcc, 20.0, (width, height))

while(True):
 try:
  img = pyautogui.screenshot()
  image = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
  out.write(image)
  StopIteration(0.5)
 except KeyboardInterrupt:
  break

out.release()
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)


Sar*_* Ak 6

您可以尝试这段代码,因为它对我有用。我在Linux上测试过

import numpy as np
import cv2
from mss import mss
from PIL import Image

sct = mss()

while 1:
    w, h = 800, 640
    monitor = {'top': 0, 'left': 0, 'width': w, 'height': h}
    img = Image.frombytes('RGB', (w,h), sct.grab(monitor).rgb)
    cv2.imshow('test', cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR))
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break
Run Code Online (Sandbox Code Playgroud)

确保安装了以下软件包:

枕头、opencv-python、numpy、mss


小智 5

你可以试试这个=>

import mss
import numpy

with mss.mss() as sct:
    monitor = {'top': 40, 'left': 0, 'width': 800, 'height': 640}
    img = numpy.array(sct.grab(monitor))
    print(img)
Run Code Online (Sandbox Code Playgroud)