简体   繁体   English

为什么我的 python 脚本的 output 文件为空

[英]why my output file of python script is empty

i am creating a python script to record the screen of desktop.我正在创建一个 python 脚本来记录桌面屏幕。

In this i am taking only the selected area by the user and only record the selected area and convert it into a video file.在这个我只取用户选择的区域,只记录选择的区域并将其转换为视频文件。

but while doing this the output of the script is a empty video file(0 bytes)但是在执行此操作时,脚本的 output 是一个空视频文件(0 字节)

can anybody tell me where am i doing wrong.谁能告诉我我在哪里做错了。 As it was working fine without the bbox(x1,x2,y1,y2) .因为它在没有bbox(x1,x2,y1,y2)的情况下工作正常。

here is the code: EDIT:这是代码:编辑:

import tkinter as tk
from tkinter import *
from tkinter import ttk ,FLAT
from PIL import Image, ImageTk, ImageGrab, ImageEnhance
import cv2
import numpy as np
import threading
filename="test.avi"
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
frame_rate = 10
root = tk.Tk()


def show_image(image):
    win = tk.Toplevel()
    win.image = ImageTk.PhotoImage(image)
    tk.Label(win, image=win.image).pack()
    win.grab_set()
    win.wait_window(win)

def area_sel():
    x1 = y1 = x2 = y2 = 0
    roi_image = None

    def on_mouse_down(event):
        nonlocal x1, y1
        x1, y1 = event.x, event.y
        canvas.create_rectangle(x1, y1, x1, y1, outline='red', tag='roi')

    def on_mouse_move(event):
        nonlocal roi_image, x2, y2
        x2, y2 = event.x, event.y
        canvas.delete('roi-image') 
        roi_image = image.crop((x1, y1, x2, y2)) 
        canvas.image = ImageTk.PhotoImage(roi_image)
        canvas.create_image(x1, y1, image=canvas.image, tag=('roi-image'), anchor='nw')
        canvas.coords('roi', x1, y1, x2, y2)
        canvas.lift('roi') 

    root.withdraw()  
    image = ImageGrab.grab()  
    bgimage = ImageEnhance.Brightness(image).enhance(0.3)  
    win = tk.Toplevel()
    win.attributes('-fullscreen', 1)
    win.attributes('-topmost', 1)
    canvas = tk.Canvas(win, highlightthickness=0)
    canvas.pack(fill='both', expand=1)
    tkimage = ImageTk.PhotoImage(bgimage)
    canvas.create_image(0, 0, image=tkimage, anchor='nw', tag='images')
    win.bind('<ButtonPress-1>', on_mouse_down)
    win.bind('<B1-Motion>', on_mouse_move)
    win.bind('<ButtonRelease-1>', lambda e: win.destroy())
    win.focus_force()
    win.grab_set()
    win.wait_window(win)
    root.deiconify()  

    if roi_image:
        region = x1, y1, x2, y2

        start_recording(region) #calling main function to record screen
        return region


def recording_screen(x1, y1, x2, y2):
    global recording
    recording = True

    while recording:

        img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
        frame=np.array(img) # for recording
        out.write(cv2.cvtColor(frame,cv2.COLOR_RGB2BGR))

out = cv2.VideoWriter() 
def start_recording(region):
    x1,y1,x2,y2 = region
    if not out.isOpened():

            out.open(filename,fourcc, frame_rate,(x2-x1,y2-y1))
    threading.Thread(target=recording_screen, args=region, daemon=True).start()

def stop_recording():
    global recording
    recording = False
    out.release()

sel_area = ttk.Button(root, text='select area to Record', width=30, command=area_sel)
sel_area.grid(row=0, column=0)

stp_rec = ttk.Button(root, text='Stop Recording', width=30, command=stop_recording)
stp_rec.grid(row=0, column=1)

root.mainloop()

You are using ImageGrab which is macOS and Windows only, so I can't test your complete code on my setup.您使用的是 macOS 和 Windows 的ImageGrab ,因此我无法在我的设置中测试您的完整代码。

The problem in your code is you have coupled the area selection and video recording.您的代码中的问题是您已将区域选择和视频录制结合起来。 Once the area is selected and you have x1 , y1 , x2 , and y2 .选择区域后,您将拥有x1y1x2y2 Return these values.返回这些值。 Initialize the cv2.VideoWriter the first time.第一次初始化cv2.VideoWriter

What you can try now is use the arguments pass to start_recording((x1, y1, x2, y2)) .您现在可以尝试使用 arguments 传递给start_recording((x1, y1, x2, y2))

def start_recording(region):
    x1,y1,x2,y2 = region
    if not out.isOpened():

        out.open(filename,fourcc, frame_rate,(y2-y1,x2-x1)) #given x2 > x1, y2 > y1
    threading.Thread(target=recording_screen, args=region, daemon=True).start()

EDIT:编辑:

The issue was wrong shape passed in the following call.问题是在以下调用中传递了错误的形状。

out.open(filename,fourcc, frame_rate,(y2-y1,x2-x1))

The Size value passed is (y2-y1,x2-x1) ie (height, width) .传递的Size值是(y2-y1,x2-x1)(height, width) However, the constructor expects (width, height) .但是,构造函数需要(width, height) See doc here .请参阅此处的文档。

Also, the img = ImageGrab.grab(bbox=(x1, y1, x2, y2)) returns an RGB image .此外, img = ImageGrab.grab(bbox=(x1, y1, x2, y2))返回一个RGB 图像 But out.write(frame) expects a BGR image .但是out.write(frame)需要一个BGR 图像 It can be fixed as:它可以固定为:

img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
frame = np.array(img)
out.write(cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM