【发布时间】:2021-08-13 11:06:01
【问题描述】:
我对 python 很陌生,尤其是 tkinter 和 opencv。
我有某种方式(一点方法)来创建最终将控制显微镜和人工智能的 gui。但是我遇到了一个绊脚石,试图录制在 gui 中显示的视频,我认为这与已经在显示器中捕获的视频源有关,但我找不到解决方法。一切正常,直到我点击记录然后它崩溃并且我收到错误:打开 VIDEOIO(V4L2:/dev/video0): can't open camera by index.
抱歉,代码太长了,但我已将其缩减到尽可能多的程度。
问题出在 root.recbtn 和 def rec 部分。
import cv2
import tkinter as tk
import multiprocessing
from tkinter import *
from PIL import Image,ImageTk
from datetime import datetime
from tkinter import messagebox, filedialog
e = multiprocessing.Event()
p = None
# Defining CreateWidgets() function to create necessary tkinter widgets
def createwidgets():
root.cameraLabel = Label(root, bg="gray25", borderwidth=3, relief="ridge")
root.cameraLabel.grid(row=2, column=1, padx=10, pady=10, columnspan=3)
root.browseButton = Button(root, bg="gray25", width=10, text="BROWSE", command=destBrowse)
root.browseButton.grid(row=1, column=1, padx=10, pady=10)
root.recbtn = Button(root, bg="gray25", width=10, text="Record", command=rec)
root.recbtn.grid(row=1, column=5, padx=10, pady=10)
root.saveLocationEntry = Entry(root, width=55, textvariable=destPath)
root.saveLocationEntry.grid(row=1, column=2, padx=10, pady=10)
# Calling ShowFeed() function
ShowFeed()
# Defining ShowFeed() function to display webcam feed in the cameraLabel;
def ShowFeed():
# t5 # Capturing frame by frame
ret, frame = root.cap.read()
if ret:
# Flipping the frame vertically
frame = cv2.flip(frame, 1)
# Changing the frame color from BGR to RGB
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
# Creating an image memory from the above frame exporting array interface
videoImg = Image.fromarray(cv2image)
# Creating object of PhotoImage() class to display the frame
imgtk = ImageTk.PhotoImage(image = videoImg)
# Configuring the label to display the frame
root.cameraLabel.configure(image=imgtk)
# Keeping a reference
root.cameraLabel.imgtk = imgtk
# Calling the function after 10 milliseconds
root.cameraLabel.after(10, ShowFeed)
else:
# Configuring the label to display the frame
root.cameraLabel.configure(image='')
def destBrowse():
# Presenting user with a pop-up for directory selection. initialdir argument is optional
# Retrieving the user-input destination directory and storing it in destinationDirectory
# Setting the initialdir argument is optional. SET IT TO YOUR DIRECTORY PATH
destDirectory = filedialog.askdirectory(initialdir="YOUR DIRECTORY PATH")
# Displaying the directory in the directory textbox
destPath.set(destDirectory)
def rec():
vid_name = datetime.now().strftime('%d-%m-%Y %H-%M-%S')
# If the user has selected the destination directory, then get the directory and save it in image_path
if destPath.get() != '':
vid_path = destPath.get()
# If the user has not selected any destination directory, then set the image_path to default directory
else:
messagebox.showerror("ERROR", "No Directory Selected!")
# Concatenating the image_path with image_name and with .jpg extension and saving it in imgName variable
vidName = vid_path + '/' + vid_name + ".avi"
capture = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D')
videoWriter = cv2.VideoWriter(vidName, fourcc, 30.0, (640, 480))
while (True):
ret, frame = capture.read()
if ret:
cv2.imshow('video', frame)
videoWriter.write(frame)
if cv2.waitKey(1) == 27:
break
capture.release()
videoWriter.release()
# Creating object of tk class
root = tk.Tk()
# Creating object of class VideoCapture with webcam index
root.cap = cv2.VideoCapture(0)
# Setting width and height
width, height = 1200, 1200
root.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
root.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
# Setting the title, window size, background color and disabling the resizing property
root.title("Test-AI-tes")
root.geometry("1600x1024")
root.resizable(True, True)
root.configure(background = "gray18")
# Creating tkinter variables
destPath = StringVar()
imagePath = StringVar()
createwidgets()
root.mainloop()
谢谢!
【问题讨论】:
-
你为什么不重用
root.cap而不是在这里创建一个新的:capture = cv2.VideoCapture(0)。此外,除了在使用tkinter时不应该使用while True循环之外,问题似乎并不集中在tkinter上。如果是这样,请删除tkinter标签 -
你想在 tkinter 窗口中实时显示视频还是你想保存帧然后显示它?
-
感谢回复,根据@TheLizzard 的评论切换到capture = root.cap,它可以录制但实时视频冻结。我希望视频保持实时,但也能够在记录命中时保存部分提要。
-
@PaulTansley 看看this。将
while True循环实现为tkinter循环。 -
谢谢@TheLizzard。我想我现在差不多了,只需要定义一个停止录制功能。
标签: python tkinter opencv-python