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 ...
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