I am using opencv(cv2) in python to record videos(only video required) from multiple webcams simultaneously. Though they are not synchronized they record at a constant framerate. The problems are
They record at 4fps when resolution is set to 1080p, while desired is 30fps. The cameras I am using support this. While previewing though the framerate is 30fps which leads me to believe I may be doing some thing wrong while recording. I am using threading as in imutils library to get the videos as suggested in this blog post.
Is there anyway to synchronize the different camera outputs(videos).
PC specs:
- Intel i5 7thgen,
- 8gb ddr3 ram,
- SSD harddrive.
The webcams I'm using are Genius 32200312100 WideCam F100 USB 2.0 WebCam.
I do not think these are a limitation as I've been monitoring the CPU and memory usage while recording.
Any help is appreciated and if any further information is required please feel free to ask.
I'm open to using any encodings that will not compromise the quality of the picture.
Edit: I'm posting the code below.
class VideoRecorder():
#Function that runs once when the VideoRecorder class is called.
def __init__(self,cam_id = 0):
#Initialize the camera and set its properties
self.cam_id = cam_id
self.framerate = 30
self.video_height = 720
self.video_width = 1280
self.cap = cv2.VideoCapture(self.cam_id)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT,self.video_height)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH,self.video_width)
self.cap.set(cv2.CAP_PROP_FPS,self.framerate)
# Grab a initial frame, It is to warm up the camera.
# This frame will not be used
temp1, temp2 = self.cap.read()
#Set the place where the file is to be stored
storage_path = "{Output_folder}"
file_name = datetime.datetime.now().strftime("%m%d%Y_%H%M%S")
file_name = "cam_" + str(self.cam_id) + "_" + file_name + ".avi"
self.file = os.path.join(storage_path,file_name)
#Initialize a videowriter object to save the recorded frames to a file
self.fourcc = cv2.VideoWriter_fourcc(*'H264')
self.out = cv2.VideoWriter(self.file,self.fourcc,self.framerate,
(self.video_width,self.video_height))
def record(self, timer = 10):
#Start a timer for the recording to see how long the recording should be
self.start_time = time.time()
#Start a frame counter to calculate the framerate at the end
self.frame_count = 0
#Run an loop for given time to get frames from camera and store them
while(self.cap.isOpened()):
tora1 = time.time()
ret, frame = self.cap.read()
print("Time for reading the frame",time.time()-tora1)
if ret == True:
tora2 = time.time()
self.out.write(frame)
print("Time for write",tora2-time.time())
self.frame_count += 1
else:
break
current_time = time.time()
self.elapsed_time = current_time - self.start_time
if(self.elapsed_time > timer):
self.stop()
break
#Start the recording in a thread
def start(self, timer):
video_thread = threading.Thread(target = self.record, args = (timer,))
#video_thread.daemon = True
video_thread.start()
#Print the fps and release all the objects
def stop(self):
print("Frame count: %d"%self.frame_count)
self.fps = self.frame_count/self.elapsed_time
print(self.elapsed_time)
print("fps: %f"%self.fps)
self.out.release()
self.cap.release()
print("Done")
if __name__ == "__main__":
#Giving which arguments to pass to the script form command line ans
#getting them in a args structure
ap = argparse.ArgumentParser()
ap.add_argument("-t", "--runtime", type = int, default = 10,
help = "TIme for which the videorecoder runs")
ap.add_argument("-id", "--cam_id", type=int, default= 0,
help="give camera id")
args = vars(ap.parse_args())
required_time = args["runtime"]
video_thread = []
for i in range(args["cam_id"]+1):
t = VideoRecorder(i)
video_thread.append(t)
t.start(required_time)