使用 OpenCV 和 Python-2.7 进行屏幕截图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24129253/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 04:03:52  来源:igfitidea点击:

Screen Capture with OpenCV and Python-2.7

pythonpython-2.7opencvnumpyvideo-capture

提问by Renan V. Novas

I'm using Python 2.7and OpenCV 2.4.9.

我正在使用Python 2.7OpenCV 2.4.9

I need to capture the current frame that is being shown to the user and load it as an cv::Matobject in Python.

我需要捕获向用户显示的当前帧,并将其加载为Python 中的cv:: Mat对象。

Do you guys know a fast way to do it recursively?

你们知道递归的快速方法吗?

I need something like what's done in the example below, that captures Matframes from a webcam recursively:

我需要类似于下面示例中所做的事情,它以递归方式从网络摄像头捕获Mat帧:

import cv2

cap = cv2.VideoCapture(0)
while(cap.isOpened()):
    ret, frame = cap.read()
    cv2.imshow('WindowName', frame)
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cap.release()
        cv2.destroyAllWindows()
        break

In the example it's used the VideoCapture classto work with the captured image from the webcam.

在示例中,它使用VideoCapture 类来处理从网络摄像头捕获的图像。

With VideoCapture.read() a new frame is always being readed and stored into a Matobject.

使用 VideoCapture.read() 总是会读取新帧并将其存储到Mat对象中。

Could I load a "printscreens stream"into a VideoCapture object? Could I create a streaming of my computer's screen with OpenCV in Python, without having to save and delete lots of .bmpfiles per second?

我可以将“printscreens 流”加载到 VideoCapture 对象中吗?我可以在 Python 中使用 OpenCV 创建计算机屏幕的流媒体,而不必每秒保存和删除大量.bmp文件吗?

I need this frames to be Matobjects or NumPy arrays, so I can perform some Computer Vision routines with this frames in real time.

我需要这些帧是Mat对象或NumPy 数组,因此我可以实时使用这些帧执行一些计算机视觉例程。

采纳答案by Renan V. Novas

That's a solution code I've written using @Raoul tips.

这是我使用@Raoul 提示编写的解决方案代码。

I used PIL ImageGrab module to grab the printscreen frames.

我使用 PIL ImageGrab 模块来抓取打印屏幕帧。

import numpy as np
from PIL import ImageGrab
import cv2

while(True):
    printscreen_pil =  ImageGrab.grab()
    printscreen_numpy =   np.array(printscreen_pil.getdata(),dtype='uint8')\
    .reshape((printscreen_pil.size[1],printscreen_pil.size[0],3)) 
    cv2.imshow('window',printscreen_numpy)
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

回答by Neabfi

I had frame rate problems with other solutions, msssolve them.

我在使用其他解决方案时遇到了帧速率问题,请mss解决它们。

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

回答by Phani Rithvij

This is the updated answer for the answer by @Neabfi

这是@Neabfi 的答案的更新答案

import time

import cv2
import numpy as np
from mss import mss

mon = {'top': 160, 'left': 160, 'width': 200, 'height': 200}
with mss() as sct:
    # mon = sct.monitors[0]
    while True:
        last_time = time.time()
        img = sct.grab(mon)
        print('fps: {0}'.format(1 / (time.time()-last_time)))
        cv2.imw('test', np.array(img))
        if cv2.waitKey(25) & 0xFF == ord('q'):
            cv2.destroyAllWindows()
            break

And to save to a mp4 video

并保存到 mp4 视频

import time

import cv2
import numpy as np
from mss import mss


def record(name):
    with mss() as sct:
        # mon = {'top': 160, 'left': 160, 'width': 200, 'height': 200}
        mon = sct.monitors[0]
        name = name + '.mp4'
        fourcc = cv2.VideoWriter_fourcc(*'mp4v')
        desired_fps = 30.0
        out = cv2.VideoWriter(name, fourcc, desired_fps,
                              (mon['width'], mon['height']))
        last_time = 0
        while True:
            img = sct.grab(mon)
            # cv2.imshow('test', np.array(img))
            if time.time() - last_time > 1./desired_fps:
                last_time = time.time()
                destRGB = cv2.cvtColor(np.array(img), cv2.COLOR_BGRA2BGR)
                out.write(destRGB)
            if cv2.waitKey(25) & 0xFF == ord('q'):
                cv2.destroyAllWindows()
                break


record("Video")