#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)
insideshow_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