[英]why my output file of python script is empty
我正在創建一個 python 腳本來記錄桌面屏幕。
在這個我只取用戶選擇的區域,只記錄選擇的區域並將其轉換為視頻文件。
但是在執行此操作時,腳本的 output 是一個空視頻文件(0 字節)
誰能告訴我我在哪里做錯了。 因為它在沒有bbox(x1,x2,y1,y2)
的情況下工作正常。
這是代碼:編輯:
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()
您使用的是 macOS 和 Windows 的ImageGrab
,因此我無法在我的設置中測試您的完整代碼。
您的代碼中的問題是您已將區域選擇和視頻錄制結合起來。 選擇區域后,您將擁有x1
、 y1
、 x2
和y2
。 返回這些值。 第一次初始化cv2.VideoWriter
。
您現在可以嘗試使用 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()
編輯:
問題是在以下調用中傳遞了錯誤的形狀。
out.open(filename,fourcc, frame_rate,(y2-y1,x2-x1))
傳遞的Size
值是(y2-y1,x2-x1)
即(height, width)
。 但是,構造函數需要(width, height)
。 請參閱此處的文檔。
此外, img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
返回一個RGB 圖像。 但是out.write(frame)
需要一個BGR 圖像。 它可以固定為:
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.