Home > Enterprise >  getting a 6kb avi file while trying to record video with opencv and tkinter
getting a 6kb avi file while trying to record video with opencv and tkinter

Time:12-10

I have a multi frame/pages Tkinter application and in one page/frame I have a camera frame which starts the camera and stars capturing when I navigate to that page now I want to record that video but when I tried to record it I am getting a 6kb ```avi`` file which is not working at all and seems corrupted.

my code


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)

CodePudding user response:

It is because the actual frame size returned by self.cap.read() does not match the size when creating the video writer.

You need to get the actual frame size using self.cap.get(...) after calling 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))
        ...
  • Related