Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Why is setting frame height and width prevents saving the webcam stream to disk?

Hello everyone. Excuse me for the vague title. I have faced a weird situation in which, setting the frame height and width fails the stream recording on disk. That is, I have written a simple app that records my webcam streams to disk. The issue is, in order to speed things up, I tried to reduce the frame height and width by writing:

video_capture.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
video_capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)

and since I have written these two lines of code, my recordings are not saved! the files get created! but they are only 6KB only! meaning nothing goes into them!

For better understanding this is my actual webcam loop (I removed extra code so the actual loop is clear) :

def live_feed(detector, video_capture, video_writer, save_feed=False, video_feed_save_folder='feeds', scaler=1.0, acc_threshold=0.9, upper_threshold=300, hop=60, slow_motion=False, slow_motion_threshold=0.02, hard_rescale=False, **kwargs):
    try:
        video_capture.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
        video_capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)

        while detector.is_running():
            # Capture frame-by-frame
            ret, frame_orig = video_capture.read()
            if ret == False:
                print("in Detector: Failed to retrieve frame(is webcam ready?)")
                break 

            if hard_rescale:
                frame = Detector.image_resize(frame_orig, width=48)
            else:
                frame = cv2.resize(frame_orig,
                                    None,
                                    fx=scaler,
                                    fy=scaler,
                                    interpolation=cv2.INTER_LINEAR)

            print(f'{i}:oiginal frame {frame_orig.shape} : new frame {frame.shape}')

            if detector.get_display_live_feed(): 
                # Display the resulting frame
                cv2.imshow('FV <Detector>', frame_orig) # or frame
                if slow_motion:
                    time.sleep(slow_motion_threshold) 
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

            if detector.save_feed:
                video_writer.write(frame_orig)
        video_capture.release()
        if detector.save_feed:
            video_writer.release()
        cv2.destroyAllWindows()

    except Exception as exp:
        print(f'Detector: {exp.args}') 
        raise exp

and this is how I create Video_capture and video_writers :

def _setup_feed_archive(self):
    self.frame_h, self.frame_w = (240, 320)
    self.archive_file_path = None
    self.video_capture = None
    self.video_writer = None

    if self.source_type == SourceType.Webcam:
        webcam_source = self.input_source + cv2.CAP_DSHOW if platform.system() == 'Windows' else self.input_source
        st, frame_orig = cv2.VideoCapture(webcam_source).read()
        if frame_orig is None:
            webcam_source = self.input_source
        self.video_capture = cv2.VideoCapture(webcam_source)

    elif self.source_type == SourceType.VideoStream:
        print(f'VideoStream Detected. input comming from: {self.input_source}')
        self.video_capture = cv2.VideoCapture(self.input_source)

    if self.video_capture != None:
        ret, frame_orig = self.video_capture.read()
        print(f'image is valid?: {ret}')
        (self.frame_h, self.frame_w, _) = frame_orig.shape

    if self.get_save_stream_status():
        dtime_str = datetime.now()
        todays_dtime = dtime_str.strftime("%a %x %X").replace(':', '_').replace('/', '_').replace(' ', '__')
        filename = f'recording_{todays_dtime}.avi'
        self.archive_file_path = os.path.join(self.video_feed_save_folder, filename)

        if not os.path.exists(self.video_feed_save_folder):
            os.mkdir(self.video_feed_save_folder)

        print(f'archive path: {self.archive_file_path}')
        # ffmpeg should be installed or configuring this becomes a headache
        self.video_writer = cv2.VideoWriter(self.archive_file_path, cv2.VideoWriter_fourcc(*'XVID'), 6, (self.frame_w, self.frame_h))

So I'm completeley confused why the video_writer doesnt record the stream. Everything else works just fine, except when those two lines are specified, the video_writer doesnt record anything. My webcam is a logitech C270. could this be becasue of the webcam I have, or is it an OpenCV bug ? what should I be looking for to get this fixed, as I dont get any exceptions or any clues. everything works except writing to files! if I comment out those two lines, everything starts working just fine!!

By the way I'm using anaconda 3 (python3.7.4, and I'm on windows 10, and I use opencv 4.1.2 )

I'd greatly appreciate if anyone could shed somelight on this or give me some hints, or suggestions to follow in order to get this to work or know what is happening. Thank you very much in advance