Last active
October 14, 2023 16:45
-
-
Save Robadob/4270726698f2412bb1020d6cc3f30f92 to your computer and use it in GitHub Desktop.
This script allows webcam images to be captured at random intervals to create a timelapse video
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cv2 # opencv-python | |
from datetime import datetime, timedelta | |
import time | |
import random | |
import re | |
import argparse | |
class CamContext: | |
def __init__(self): | |
self.cam = cv2.VideoCapture(0) | |
def __enter__(self): | |
return self.cam | |
def __exit__(self, exc_type, exc_value, traceback): | |
self.cam.release() | |
return False # Don't suppress exceptions | |
# Seed with current time | |
random.seed() | |
# arg parse | |
parser = argparse.ArgumentParser( | |
prog='Random Webcam Timelapse', | |
description='This script allows webcam images to be captured at random intervals to create a timelapse video') | |
parser.add_argument('--min', default=60, type=int, help="Minimum delay between captures (seconds)") | |
parser.add_argument('--max', default=120, type=int, help="Maximum delay between captures (seconds)") | |
parser.add_argument('--hours', default=1, type=int, help="Number of hours to execute for (combines with -m/--mins)") | |
parser.add_argument('--mins', default=0, type=int, help="Number of mins to execute for (combines with -h/--hours)") | |
parser.add_argument('--fps', default=24, type=int, help="Frames per second of the resulting video") | |
args = parser.parse_args() | |
min_wait = args.min | |
max_wait = args.max | |
end_time = datetime.now() + timedelta(hours=args.hours, minutes=args.mins) | |
print(f"Running for {args.hours}h{args.mins}m, with {min_wait}-{max_wait}s intervals.") | |
# Video output stream | |
out = None | |
while True: | |
# Sleep random (break if sleep would exceed end time) | |
sleep_time = random.randint(min_wait, max_wait) | |
if datetime.now() + timedelta(seconds=sleep_time) > end_time: | |
break | |
time.sleep(sleep_time) | |
# Capture image with cam 0 (and release cam again, to prevent blocking legit uses) | |
result = None | |
try: | |
with CamContext() as cam: | |
result, image = cam.read() | |
except Exception as e: | |
print(f"{datetime.now().isoformat()}: Failed to Enable Cam") | |
# If image was captured, write it out | |
if result: | |
if not out: | |
# Init output video | |
start_str = re.sub(r'[^\w_. -]', '', datetime.now().isoformat()) | |
end_str = re.sub(r'[^\w_. -]', '', end_time.isoformat()) | |
vid_path = f"{start_str}_{end_str}.mp4" | |
height, width, layers = image.shape | |
print(vid_path) | |
out = cv2.VideoWriter(vid_path, cv2.VideoWriter_fourcc(*'mp4v'), args.fps, (width,height)) | |
out.write(image) | |
print(f"{datetime.now().isoformat()}: Captured Image") | |
else: | |
print(f"{datetime.now().isoformat()}: Failed to Capture Image") | |
if out: | |
out.release() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment