Python, when making a video it seems to ignore the set FPS

asked 2019-07-12 08:59:03 -0500

the_phet gravatar image

I have the following code, which it just created a video of a set length recorded from a camera (USB camera connected to the computer):

##############################################################################
# Reads from the cam and makes a video until user press q or timeout
##############################################################################

import cv2
import threading
import time, random, string, sys


class RecordVideo():


    def __init__(self, user_time):

        self.duration = user_time


    def random_filename(self, size):
        ''' to create random names for the dataset pictures '''

        w = ''.join(random.choice(string.ascii_lowercase) for i in range(size))
        return w+'.avi'


    def kill_video(self, event, time_to_wait):
        '''Waits for time_wait time. Then sets and event so that the timeout 
        is marked and the video recording stops'''
        time.sleep(time_to_wait+1) # cam always takes around 1s to warm up
        event.set()


    def record_video(self, filename):

        vc = cv2.VideoCapture(2)
        vc.set(cv2.CAP_PROP_FRAME_WIDTH, 1024) #frame resolution for CA
        vc.set(cv2.CAP_PROP_FRAME_HEIGHT, 576)
        cv2.namedWindow("video")

        fourcc = cv2.VideoWriter_fourcc(*'X264')
        random_name = self.random_filename(1)
        out = cv2.VideoWriter(filename+random_name, fourcc, 15.0, (1024,576))

        event = threading.Event()

        if self.duration > 0:
            timer = threading.Thread(target=self.kill_video, 
                    args=(event,self.duration))
            timer.start()

        frame_counter = 0

        while(1):
            frame_counter += 1
            ret,frame = vc.read()
            out.write(frame)
            cv2.imshow("video",frame)

            key = cv2.waitKey(1)

            if key == ord('q') or event.is_set():
                break

        vc.release()
        out.release()
        cv2.destroyAllWindows()


    def record_threaded(self, filename):
        threading.Thread(target=self.record_video, args=(filename,)).start()


if __name__ == "__main__":

    if len(sys.argv) > 1:
        user_time = float(sys.argv[1])
    else:
        user_time = 0

    rv = RecordVideo(user_time)
    rv.record_threaded()

The code does work and makes videos, but they have the wrong length when I change the FPS. If I set the camera to 15FPS, and this code as you can see goes to 15FPS, and then I execute this code for let's say 30 seconds, then it will make a 30 seconds video, but if I change the FPS - both in the camera or the code- then the length of the video will change depending on the FPSs set, it will either be longer or short, but never the length I asked it for.

There's the line "key = cv2.waitKey(1)" and I have changed its value, but it seems to sort of ignore it. I cannot control the FPS with that, or with the property.

I have been having this problem for a very long time. With Python 3.3.0 it was fine, but the moment it got updated to 3.3.1, then everything went wrong.

I am using Python3, Ubuntu, Opencv 3.4.4

edit retag flag offensive close merge delete