commit cfc913bd112e1d1231ea3c4a16e2a56eba95eefd Author: Nico Melone Date: Thu Jul 9 13:13:50 2020 -0500 Initial commit diff --git a/EXAMPLE.config.json b/EXAMPLE.config.json new file mode 100644 index 0000000..3d5e01c --- /dev/null +++ b/EXAMPLE.config.json @@ -0,0 +1,14 @@ +{ + "real_days": 0, + "real_hours": 0, + "real_mins": 30, + "real_seconds": 0, + "target_length_min": 0, + "target_length_sec": 30, + "target_fps": 30, + "camera_ip": "192.168.2.231", + "camera_port": 3400, + "camera_username": "henrypump", + "camera_password": "HPCamera1903", + "output_file": "test1.avi" +} \ No newline at end of file diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..f13ba96 --- /dev/null +++ b/README.txt @@ -0,0 +1,45 @@ +In this folder are two files: EXAMPLE.config.json and timelapse_maker.EXAMPLE + +EXAMPLE.config.json is an example config file. The config file looks like the following: + +{ + "real_days": 0, + "real_hours": 0, + "real_mins": 30, + "real_seconds": 0, + "target_length_min": 0, + "target_length_sec": 30, + "target_fps": 30, + "camera_ip": "192.168.2.231", + "camera_port": 3400, + "camera_username": "henrypump", + "camera_password": "HPCamera1903", + "output_file": "test1.avi" +} + +Where: + real_days: the number of real time days to capture images + real_hours: the number of real time hours to capture images + real_mins: the number of real time minutes to capture images + real_seconds: the number of real time seconds to capture images + target_length_min: the number of minutes the output file should be (this is used in conjunction with target_length_sec to get the full length of the output) + target_length_sec: the number of seconds the output file should be (this is used in conjunction with target_length_min to get the full length of the output) + target_fps: the frames per second the output file should be run at (10fps is choppy, 15fps is less-choppy, 24fps is cinematic, 30fps is smooth, 60fps is really smooth) + camera_ip: the ip address of the camera (the " marks are important) + camera_port: the port number for the camera + camera_username: the username to login to the camera (the " marks are important) + camera_password: the password to login to the camera (the " marks are important) + output_file: the name of the output file (the " marks are important also be sure to include .avi else Windows won't recognize it) + +The name of the config file should be: + config.json + +Once the config file is setup just double click timelapse_maker.exe and the software should run itself. +Some caveats: + The software is only guaranteed for Panasonic iPro cameras + The software will not recover in anyway in the event of a windows reboot or the software being closed. + The software is better suited to longer run times ie: setting longer real time runs is better than shorter ones + The software defaults to making a timelapse folder in its current folder where it stores all the images once the video is made this folder can be deleted + DO NOT close the window else you'll have to start over, the images won't be lost but the run will be skewed + The software processes all the images in the timelapse folder regardless of what run they are from + Technically the software could be run remotely and given a public IP that is port forwarded but is NOT recommened diff --git a/timelapse_maker.exe b/timelapse_maker.exe new file mode 100644 index 0000000..b5622b0 Binary files /dev/null and b/timelapse_maker.exe differ diff --git a/timelapse_maker.py b/timelapse_maker.py new file mode 100644 index 0000000..c7f2768 --- /dev/null +++ b/timelapse_maker.py @@ -0,0 +1,93 @@ +import requests +from requests.auth import HTTPDigestAuth +import time +from cv2 import VideoWriter, imread, VideoWriter_fourcc +import numpy as np +import glob +import os +import json +import progressbar +from natsort import natsorted + +def calc_interframetime(real_days,real_hours,real_mins,real_seconds,target_length_min,target_length_sec,target_fps): + #converts real time inputs into seconds + rd = real_days*24*60*60 + rh = real_hours*60*60 + rm = real_mins*60 + rs = rd+rh+rm+real_seconds + #calculate the target frames for the final output + target_frames = (target_length_min*60 + target_length_sec) * target_fps + #calculate the wait time between frames + spf = rs/target_frames + return target_frames,spf + +#url = 'https://httpbin.org/digest-auth/auth/user/pass' +def makevideo(): + + PERSIST = {} + try: + with open("config.json", 'r') as persist_file: + PERSIST = json.load(persist_file) + except Exception: + return False + + target_frames,interframe_time = calc_interframetime( + PERSIST['real_days'], + PERSIST['real_hours'], + PERSIST['real_mins'], + PERSIST['real_seconds'], + PERSIST['target_length_min'], + PERSIST['target_length_sec'], + PERSIST['target_fps']) + try: + now = time.time() + with open('timelapse/{}.jpg'.format(now), 'wb') as handle: + pass + os.remove('timelapse/{}.jpg'.format(now)) + except: + os.mkdir('timelapse') + print("Number of frames:{}\nReal Time between frames: {} seconds".format(target_frames,interframe_time)) + + #for every frame in the range of target_frames + for x in progressbar.progressbar(range(target_frames),prefix='Collecting Photos: '): + #open a file and pull the current picture from the camera + now = time.time() + try: + with open('timelapse/{}.jpg'.format(now), 'wb') as handle: + response = requests.get("http://" + PERSIST['camera_ip'] + ":" + str(PERSIST['camera_port']) + "/cgi-bin/camera", + auth=HTTPDigestAuth(PERSIST['camera_username'],PERSIST['camera_password']),stream=True) + if not response.ok: + print(response) + + for block in response.iter_content(1024): + if not block: + break + + handle.write(block) + except: + print("\nMissed frame {} check connection/settings to camera!".format(x)) + os.remove('timelapse/{}.jpg'.format(now)) + if x != target_frames-1 and interframe_time-(time.time()-now) > 0: + #wait the calculated time between frames minus the processing time for this frame to start again + time.sleep(interframe_time-(time.time()-now)) + + + #filenames = natsorted(filenames) + img_array = [] + + #load the pictures with cv2 + for filename in progressbar.progressbar(glob.glob('timelapse/*.jpg'),prefix='Loading Photos: '): #filenames: + img = imread(filename) + height, width, _ = img.shape + size = (width,height) + img_array.append(img) + + #setup the video format + out = VideoWriter(PERSIST['output_file'], VideoWriter_fourcc(*'MP42'), PERSIST['target_fps'], size) + + #output the video + for i in progressbar.progressbar(range(len(img_array)),prefix='Processing Video: '): + out.write(img_array[i]) + out.release() +makevideo() +input("Press ENTER to exit program") \ No newline at end of file