я хочу отобразить указатель мыши в моей записи - PullRequest
0 голосов
/ 17 февраля 2020

Я делаю рекордер экрана, который записывает экран рабочего стола. но когда я записываю экран, указатель мыши (курсор) не виден в записи. так есть ли способ показать указатель мыши в моей записи. это мой код ..

import cv2
import numpy as np
import pyautogui
import datetime
date=datetime.datetime.now()

SCREEN_SIZE = (1366, 768)
framerate=12

fourcc = cv2.VideoWriter_fourcc(*'XVID')
filename='E:/project/videos/rec_%s%s%s%s%s%s.avi' %(date.year,date.month,date.day,date.hour,date.minute,date.second)

out = cv2.VideoWriter(filename, fourcc,framerate, SCREEN_SIZE)

while True:

    img = pyautogui.screenshot()

    frame = np.array(img)

    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    out.write(frame)

    cv2.imshow('screenshot', frame)

    if cv2.waitKey(1) == ord("q"):
        break

cv2.destroyAllWindows()
out.release()

1 Ответ

0 голосов
/ 17 февраля 2020

Я не думаю, что это возможно при таком подходе, но я всегда рад, когда меня исправляют и учат чему-то новому. Я знаю пару обходных путей.

Во-первых, продолжать использовать pyautogui и вызывать его функцию mouseposition() и вставлять / рисовать свой собственный курсор мыши syntheti c на захвате. Я сделал это с помощью функции fillPoly() OpenCV:

#!/usr/bin/env python3

import cv2
import numpy as np
import pyautogui
import datetime

# X and Y coordinates of mouse pointer
Xs = [0,8,6,14,12,4,2,0]
Ys = [0,2,4,12,14,6,8,0]

while True:

    img = pyautogui.screenshot()
    mouseX,mouseY = pyautogui.position()
    mouseX *= 2
    mouseY *= 2

    frame = np.array(img)
    frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)

    # Synthesize mouse pointer
    Xthis = [4*x+mouseX for x in Xs]
    Ythis = [4*y+mouseY for y in Ys]
    points = list(zip(Xthis,Ythis))
    points = np.array(points, 'int32')
    cv2.fillPoly(frame,[points],color=[255,255,255])

    # Make it a bit smaller for display
    frame = cv2.resize(frame,(960,540))

    cv2.imshow('Title', frame)
    if cv2.waitKey(1) == ord("q"):
        break

cv2.destroyAllWindows()
out.release()

enter image description here


Второй - использовать ffmpeg, который может захватывать мышь - вы можете либо запустить ffmpeg вместо вашего текущего приложения, либо перенаправить вывод из ffmpeg в ваше приложение через канал и продолжить обрабатывать его, как сейчас. Это может выглядеть так:

#!/usr/bin/env python3

# ffmpeg -y -pix_fmt bgr0 -f avfoundation -r 20 -t 10 -i 1 -vf scale=w=3840:h=2160 -f rawvideo /dev/null

import sys
import cv2
import time
import subprocess
import numpy as np

w,h = 3840, 2160

def ffmpegGrab():
    """Generator to read frames from ffmpeg subprocess"""
    cmd = [
        'ffmpeg',
        '-pix_fmt', 'bgr0',
        '-f', 'avfoundation',
        '-capture_cursor', '1',
        '-capture_mouse_clicks', '1',
        '-r', '20',
        '-i', '1',
        '-vf','scale=w=3840:h=2160',
        '-f', 'rawvideo',
        'pipe:1'
    ]
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    while True:
        frame = proc.stdout.read(w*h*4)
        yield np.frombuffer(frame, dtype=np.uint8).reshape((h,w,4))

# Get frame generator
gen = ffmpegGrab()

# Get start time
start = time.time()

# Read video frames from ffmpeg in loop
nFrames = 0
while True:
    # Read next frame from ffmpeg
    frame = next(gen)
    nFrames += 1
    frame = cv2.resize(frame,(960,540))

    cv2.imshow('screenshot', frame)

    if cv2.waitKey(1) == ord("q"):
        break

    fps = nFrames/(time.time()-start)
    print(f'FPS: {fps}')


cv2.destroyAllWindows()
out.release()

enter image description here

Обратите внимание, что pyauto gui занимает около 600 мс, чтобы захватить один кадр на моей маме c, в то время как ffmpeg выше достигает 20 кадров в секунду, или 50 мс на кадр.

Ключевые слова : Python. обработка изображений, ffmpeg, pyauto gui, захват экрана, захват экрана, захват экрана, захват экрана, fps. скорость, прайм.

...