簡體   English   中英

使用 OpenCV 和 Python-2.7 進行屏幕截圖

[英]Screen Capture with OpenCV and Python-2.7

我正在使用Python 2.7OpenCV 2.4.9

我需要捕獲顯示給用戶的當前幀,並將其加載為 Python 中的cv:: Mat對象。

你們知道遞歸的快速方法嗎?

我需要類似於下面示例中所做的事情,它以遞歸方式從網絡攝像頭捕獲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

在示例中,它使用VideoCapture 類來處理從網絡攝像頭捕獲的圖像。

使用 VideoCapture.read() 總是會讀取新幀並將其存儲到Mat對象中。

我可以將“printscreens 流”加載到 VideoCapture 對象中嗎? 我可以在 Python 中使用 OpenCV 創建計算機屏幕的流媒體,而不必每秒保存和刪除大量.bmp文件嗎?

我需要這些幀是Mat對象或NumPy 數組,以便我可以實時使用這些幀執行一些計算機視覺例程。

這是我使用@Raoul 提示編寫的解決方案代碼。

我使用 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

我在使用其他解決方案時遇到了幀速率問題,請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

這是@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

並保存到 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")

這是 Python 3 的實現

此函數在正在運行的應用程序列表中查找應用程序:

def capture_dynamic():
    toplist, winlist = [], []
    
    def enum_cb(hwnd, results):
        winlist.append((hwnd, win32gui.GetWindowText(hwnd)))
        
    win32gui.EnumWindows(enum_cb, toplist)

    wnd = [(hwnd, title) for hwnd, title in winlist if 'spotify' in title.lower()]

    if wnd:
        wnd = wnd[0]
        hwnd = wnd[0]

        bbox = win32gui.GetWindowRect(hwnd)
        img = ImageGrab.grab(bbox)
        return img
    else:
        return None

此功能顯示圖像,直到按下字母“q”:

import cv2
import numpy as np

while(True):
#   Dynamic Version
    screen_grab =  capture_dynamic()
    
    if(screen_grab == None):
        print("No Window Found! Please Try Again")
        break
        
    screen_grab = np.array(screen_grab)
    cv2.imshow('window',cv2.cvtColor(screen_grab, cv2.COLOR_BGR2RGB))
    
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

確保您要捕獲的應用程序應該在前台,而不是在任何其他應用程序后面

請點贊!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM