it-swarm.com.de

Erfassen Sie Videodaten vom Bildschirm in Python

Gibt es eine Möglichkeit, mit Python (vielleicht mit OpenCV oder PIL) kontinuierlich oder in einem Teil des Bildschirms Frames zu erfassen, zumindest bei 15 fps oder mehr? Ich habe es in anderen Sprachen gesehen, also sollte es theoretisch möglich sein. 

Ich muss die Bilddaten nicht in einer Datei speichern. Ich möchte eigentlich nur, dass ein Array ausgegeben wird, das die rohen RGB-Daten enthält (wie in einem Numpy-Array oder so), da ich es einfach nehmen und an eine große LED-Anzeige senden werde (wahrscheinlich nach einer Größenänderung).

10
Adam Haile

Es gibt eine andere Lösung mit mss , die eine viel bessere Bildrate bietet. (Getestet auf einem Macbook Pro mit MacOS Sierra)

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
16
Neabfi

Sie müssen ImageGrab aus der Pillow (PIL) -Bibliothek verwenden und das Capture in ein numpy-Array konvertieren. Wenn Sie das Array haben, können Sie mit opencv machen, was Sie möchten. Ich habe Capture in Grau konvertiert und imshow () als Demonstration verwendet.

Hier ist ein kurzer Code zum Einstieg: 

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()

sie können dort ein Array mit der Frequenz anschließen, die Sie für die Aufnahme von Frames benötigen. Danach decodiert man einfach die Frames. Vergessen Sie nicht, vor der Schleife hinzuzufügen:

fourcc = cv2.VideoWriter_fourcc(*'XVID')
vid = cv2.VideoWriter('output.avi', fourcc, 6, (640,480))

und innerhalb der Schleife können Sie hinzufügen:

vid.write(frame) #the edited frame or the original img_np as you please

UPDATE
Das Endergebnis sieht in etwa so aus (wenn Sie einen Frame-Stream erzielen möchten, der ist. Speichern Sie als Video nur eine Demonstration der Verwendung von opencv auf dem erfassten Bildschirm):

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()

Hoffentlich hilft das

9
ibininja

Ich habe all das oben ausprobiert, aber es gab mir nicht die Echtzeit-Bildschirmaktualisierung ... Sie können dies versuchen. Dieser Code wurde getestet und erfolgreich getestet und liefert auch eine gute fps-Ausgabe. Sie können dies auch anhand der jeweils benötigten Schleifenzeit beurteilen.

import numpy as np
import cv2
from PIL import ImageGrab as ig
import time

last_time = time.time()
while(True):
    screen = ig.grab(bbox=(50,50,800,640))
    print('Loop took {} seconds',format(time.time()-last_time))
    cv2.imshow("test", np.array(screen))
    last_time = time.time()
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break
2
Istiyak

Sie können dies versuchen =>

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)
2
Sandzz

Sie können versuchen, diese. Dieser Code funktioniert für mich. Ich habe Linux getestet

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', np.array(img))
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

stellen Sie sicher, dass das folgende Paket installiert ist

Pillow, opencv-python, numpy, mss

1
Sarath Ak

basierend auf diesem post und anderen posts, habe ich so etwas gemacht .

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(image), cv2.COLOR_RGB2BGR)
  out.write(img)
  StopIteration(0.5)
 except KeyboardInterrupt:
  break

out.release()
cv2.destroyAllWindows()
1

Bei allen oben genannten Lösungen konnte ich keine nutzbare Framerate erhalten, bis ich meinen Code folgendermaßen geändert habe:

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

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

sct = mss()

while 1:

    sct_img = sct.grab(bbox)
    cv2.imshow('screen', np.array(sct_img))

    if cv2.waitKey(1) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

Mit dieser Lösung bekomme ich problemlos mehr als 20 Bilder pro Sekunde.

Überprüfen Sie diesen Link als Referenz: https://python-mss.readthedocs.io/examples.html

0
Markoe7

Ich habe ImageGrab von PIL ausprobiert und es gab mir 20fps, was in Ordnung ist, aber die Verwendung von win32-Bibliotheken gab mir +40fps, was unglaublich ist!

Ich habe this code von Frannecklp verwendet, aber es hat nicht gut funktioniert, also musste ich es ändern:

- Zuerst pip install pywin32, falls Sie die Bibliotheken verwenden

-importieren Sie die Bibliotheken stattdessen wie folgt:

import cv2
import numpy as np
from win32 import win32gui
from pythonwin import win32ui
from win32.lib import win32con
from win32 import win32api

um einen einfachen Bildschirm zu erhalten, machen Sie:

from grab_screen import grab_screen
import cv2
img = grab_screen()
cv2.imshow('frame',img)

und um Frames zu bekommen:

while(True):
#frame = grab_screen((0,0,100,100))
frame = grab_screen()
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q') or x>150:
    break
0
Reza Hosseini