получение файла avi объемом 6 кб при попытке записи видео с помощью opencv и tkinter

#python #opencv #tkinter

#питон #opencv #tkinter

Вопрос:

У меня есть приложение Tkinter с несколькими кадрами/страницами, и на одной странице/кадре у меня есть кадр камеры, который запускает камеру и захватывает звезды, когда я перехожу на эту страницу.Теперь я хочу записать это видео, но когда я попытался записать его, я получаю файл `avi` объемом 6 кб, который вообще не работает и кажется поврежденным.

мой код

  class FrontCameraPage(tk.Frame):  def __init__(self, parent, controller):  tk.Frame.__init__(self, parent)  self.controller = controller   self.label = tk.Label(self, text="FRONT CAMERA", font=MediumFont, bg="white").grid(row=0, column=0, columnspan=2, sticky="nsew")  self.cameraFrame = tk.Frame(self, bg=gray)  self.cameraFrame.grid(row=1, column=0, sticky="nsew")  self.buttonFrame = tk.Frame(self, bg="white")  self.buttonFrame.grid(row=1, column=1, sticky="nsew", padx=(10, 0))   #creating buttons and frames --  self.end= tk.Button(self.buttonFrame, text="STOP", font=small_Font, bg=dark_blue, fg="White")  self.end.grid(row=2, column=0, ipadx=10, pady=(0, 5))  self.end['command'] = self.stop_capture   self.cancelButton = tk.Button(self.buttonFrame, text="Cancel", font=small_Font, bg=dark_blue, fg="white")  self.cancelButton.grid(row=3, column=0, ipadx=10)  self.cancelButton['command'] = lambda: controller.show_frame(someOtherPage)  #----------------------------------------------------------------------------------------------   # setup callbacks for switching in and out events starts and stops when I change frames  self.bind('lt;lt;SwitchIngt;gt;', self.start_capture)  self.bind('lt;lt;SwitchOutgt;gt;', self.stop_capture)   self.capture = None # task id for the capture loop  width, height = 200, 200  self.cap = cv2.VideoCapture(0)  self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)  self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)    self.fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')  self.out = cv2.VideoWriter('output.avi', self.fourcc, 20.0, (width, height))   self.lmain = tk.Label(self.cameraFrame)  self.lmain.pack()   def start_capture(self, event=None):  if self.capture is None:  self.show_frame()  print('capture started')    def stop_capture(self, event=None):  if self.capture:  self.after_cancel(self.capture)  self.out.release()  self.capture = None  print('capture stopped')    def show_frame(self):  ret, frame = self.cap.read()  if ret:  frame = cv2.flip(frame, 1)  cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)  img = Image.fromarray(cv2image)  #----------------------------------------------------------------  self.out.write(cv2image)  #----------------------------------------------------------------  self.imgtk = ImageTk.PhotoImage(image=img)  self.lmain.configure(image=self.imgtk)  self.capture = self.after(10, self.show_frame)   

Комментарии:

1. Если вы распечатаете размер кадра с помощью print(frame.shape) inside show_frame() , вы обнаружите, что фактический размер кадра не 200×200. Таким образом, размер выходного кадра при создании видеозаписи не совпадает с фактическим размером кадра. Вам нужно получить фактический размер кадра, используя self.cap.get(...) после вызова self.cap.set(...) .

2. Если вы работаете в Windows: Убедитесь,что ваше приложение имеет доступ к библиотеке DLL opencv_ffmprg, которая необходима для успешной записи видео.

3. @Micka да, я нахожусь в Windows и изучил, как установить opencv_ffmprg, но я не могу найти папку OpenCV на диске «C»

4. Извините, опечатка. Найдите opencv_ffmp* он должен находиться в том же месте, что и остальные двоичные файлы библиотеки DLL opencv.

5. @Micka я не могу их найти

Ответ №1:

Это связано с тем, что фактический размер кадра, возвращаемый пользователем self.cap.read() , не соответствует размеру при создании записи видео.

Вам нужно получить фактический размер кадра, используя self.cap.get(...) после вызова self.cap.set(...) :

 class FrontCameraPage(tk.Frame):  def __init__(self, parent, controller):  tk.Frame.__init__(self, parent)  self.controller = controller   ...    width, height = 200, 200  self.cap = cv2.VideoCapture(0)  self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)  self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)   # get the final frame size  width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))  height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))   self.fourcc = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')  self.out = cv2.VideoWriter('output.avi', self.fourcc, 20.0, (width, height))  ...  

Комментарии:

1. Я нахожусь в Windows и изучил, как установить opencv_ffmprg, но я не могу найти папку OpenCV на диске «C». Я загрузил opencv с помощью pip, это проблема или мне нужно загрузить ее с помощью установщика exe

2. @stark Я думаю, что необходимая библиотека DLL должна быть включена при установке opencv-python модуля. Вы получили какую-либо ошибку, не найдя никакой библиотеки DLL при выполнении сценария? Вы пробовали мое предложение в моем ответе?

3. да, я пробовал этот код, который вы отправили, но он не работает, я думаю, что проблема может быть в opencv_ffmpg

4. Просто сказать «Это не работает» не позволяет нам помочь. Вам нужно описать, что не работает, и опубликовать полный отчет о любой полученной ошибке.

5. И во время запуска приложения я не получаю никаких ошибок, только эти предупреждения [ WARN:1] global D:aopencv-pythonopencv-pythonopencvmodulesvideoiosrccap_msmf.cpp (438) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback [ WARN:0] global D:aopencv-pythonopencv-pythonopencvmodulesvideoiosrccap_msmf.cpp (438) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback