【问题标题】:getting a 6kb avi file while trying to record video with opencv and tkinter尝试使用 opencv 和 tkinter 录制视频时获取 6kb avi 文件
【发布时间】:2022-01-13 03:00:00
【问题描述】:

我有一个多帧/多页 Tkinter 应用程序,在一个页面/帧中,我有一个相机框架,当我导航到该页面时,它会启动相机和星星捕捉现在我想录制该视频,但当我尝试录制它时我得到了一个 6kb 的 ```avi`` 文件,它根本不工作而且似乎已损坏。

我的代码


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('<<SwitchIn>>', self.start_capture)
        self.bind('<<SwitchOut>>', 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)

【问题讨论】:

  • 如果你在show_frame()里面使用print(frame.shape)打印出帧大小,你会发现实际的帧大小不是200x200。因此创建视频写入器时的输出帧大小与实际帧大小不匹配。调用self.cap.set(...) 后,您需要使用self.cap.get(...) 获取实际帧大小。
  • 如果您在 Windows 中工作:确保您的应用程序可以访问 opencv_ffmprg dll,这是成功编写视频所必需的。
  • @Micka 是的,我在 Windows 上并研究了如何设置 opencv_ffmprg 但我无法在“C”驱动器上找到 openCv 文件夹
  • 抱歉,打错了。搜索 opencv_ffmp* 它应该与所有 opencv dll 二进制文件的其余位置相同。
  • @Micka 我找不到他们

标签: python opencv tkinter


【解决方案1】:

这是因为self.cap.read()返回的实际帧大小与创建视频写入器时的大小不匹配。

调用self.cap.set(...)后需要使用self.cap.get(...)获取实际帧大小:

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))
        ...

【讨论】:

  • 我在 Windows 上查看如何设置 opencv_ffmprg 但我无法在“C”驱动器上找到 openCv 文件夹我使用 pip 下载了 opencv 是一个问题,或者我必须使用那里下载它exe安装程序
  • @stark 我认为安装opencv-python 模块时应该包含所需的DLL。执行脚本时,您是否因找不到任何 DLL 而出现任何错误?您在我的回答中尝试了我的建议吗?
  • 是的,我尝试了您发送的这段代码,但它不起作用我认为问题可能出在 opencv_ffmpg
  • 只是说 “它不起作用” 并不能让我们提供帮助。您需要描述什么不起作用并发布您遇到的任何错误的完整回溯。
  • 在运行应用程序时,我没有收到任何错误,只有这些警告 [ WARN:1] global D:\a\opencv-python\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (438) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback [ WARN:0] global D:\a\opencv-python\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (438) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback
猜你喜欢
  • 1970-01-01
  • 2012-03-04
  • 2021-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
  • 2016-08-07
相关资源
最近更新 更多