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

asked 2020-07-19 06:40:59 -0600

Niessoh gravatar image

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

edit retag flag offensive close merge delete

Comments

I also need to add that If I use larger numbers such as 640, 480, the recordings are saved, its as if opencv has issues with resizing down. maybe my webcam doesnt support it? I dont know

Niessoh gravatar imageNiessoh ( 2020-07-19 06:42:08 -0600 )edit