Skip to content

Commit

Permalink
Intermediate cleanup commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjeng committed Nov 21, 2020
1 parent dbb16ac commit 228e616
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 128 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
# PiTimelapse

Timelapse photography with the Raspberry Pi camera.

## Summary

A long-term time lapse is an effective and fun way to communicate changes over time. However, most cameras which are custom-built to capture time lapse videos are very costly. While DSLRs are able to capture photos at set intervals, the images captured cannot be accessed (without purchasing additional equipment) until the entire set of photos. Our project captures the individual frames of a time-lapse video with cheap, reliable, off-the-shelf components, with the added benefit of allowing one to review and work with the images as they are being captured by uploading the images to Dropbox.

## Other Work

Plenty of work has already been done in the field of time-lapse photography, including an [Instructables Site](http://www.instructables.com/id/How-to-make-a-long-term-time-lapse/), an amazing [Vimeo video](http://www.photographyblogger.net/a-year-long-time-lapse-study-of-the-sky/), and a [project by David Hunt](http://www.davidhunt.ie/raspberry-pi-in-a-dslr-camera/) using a Raspberry Pi to control a DSLR camera

## Additonal Resources

[Testing Multiple Pi Camera Options](https://www.raspberrypi-spy.co.uk/2013/06/testing-multiple-pi-camera-options-with-python/)
5 changes: 5 additions & 0 deletions REQUIREMENTS.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
click>=7.1
matplotlib>=3.3
numpy>=1.19
opencv-python>=4.4
tqdm>=4.53
2 changes: 2 additions & 0 deletions on_the_pi/crontab
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# runs script once on reboot
@reboot /PATH/TO/SCRIPT/rtlC -d 24 &
20 changes: 15 additions & 5 deletions src/main/others/rtlC → on_the_pi/rtlC
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
# Timelapse controller for Raspberry Pi

IMAGEDIR=imagesCONTINUOUS
DELAY=55
DELAY=54
ISUPLOAD=0
# Note: The total time interval between images is
# approximately $DELAY+5 seconds, since the camera module
# takes approximately 5 seconds to calibrate i
while getopts i:d: OPTION
while getopts "i:d:u:" OPTION
do
case $OPTION in
i)
Expand All @@ -15,11 +16,15 @@ do
d)
DELAY=$OPTARG
;;
u)
ISUPLOAD=$OPTARG
;;
esac
done

PROJECTDIR=/home/pi/techxtimelapse
# mkdir $PROJECTDIR/$IMAGEDIR
mkdir -p "$PROJECTDIR/$IMAGEDIR"
# # /home/pi/Dropbox-Uploader/dropbox_uploader.sh mkdir "$IMAGEDIR"

# As of 13 Dec 2013,
# -sh, -co, -sa range from -100 to 100. Default at 0
Expand All @@ -31,6 +36,11 @@ PROJECTDIR=/home/pi/techxtimelapse
while true;
do
filename=$(date +"%Y%m%d_%H%M-%S").jpg
raspistill --metering matrix --nopreview --output $PROJECTDIR/$IMAGEDIR/$filename
sleep $DELAY
raspistill --metering matrix --nopreview --output "$PROJECTDIR/$IMAGEDIR/$filename"

if [ $ISUPLOAD = 1 ]; then
/home/pi/Dropbox-Uploader/dropbox_uploader.sh upload $PROJECTDIR/$IMAGEDIR/$filename $IMAGEDIR
fi

sleep "$DELAY"
done
27 changes: 0 additions & 27 deletions pom.xml

This file was deleted.

111 changes: 111 additions & 0 deletions postprocessing/diff_images.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/usr/bin/env python3

import glob
import os
from enum import Enum
from typing import List

import click
import cv2
import matplotlib.pyplot as plt
import numpy as np
import tqdm


def calculate_diffs(file_list: List[str]) -> List[float]:
# calculates the differences between successive images

this_image = cv2.imread(file_list[0], cv2.IMREAD_COLOR)
height, width = this_image.shape[:2]
diffs = []
for path in tqdm.tqdm(file_list[1:]):
next_image = cv2.imread(path, cv2.IMREAD_COLOR)
try:
diffs.append(cv2.norm(this_image, next_image) / (height * width))
except cv2.error as e:
# https://stackoverflow.com/a/792163/1404966
raise ValueError(f"Could not compute norm with image {path}") from e
this_image = next_image
return diffs


def exponential_moving_average(values: List[float], window: int = 20) -> np.array:
weights = np.exp(np.linspace(-1.0, 0.0, window))
weights /= weights.sum()

# here, we will just allow the default since it is an EMA
a = np.convolve(values, weights)[: len(values)]
a[:window] = a[window]
return a


def moving_average(values: List[float], window: int = 20) -> np.array:
weights = np.repeat(1.0, window) / window
# specifying "valid" to convolve requires that there are enough data points.
return np.convolve(values, weights, "valid")


SmoothingOption = Enum("SmoothingOption", "NO MA EMA")


def smooth_values(values: List[float], smoothing_option: SmoothingOption) -> np.array:
if smoothing_option == SmoothingOption.NO:
return np.array(values)
if smoothing_option == SmoothingOption.MA:
return moving_average(values)
if smoothing_option == SmoothingOption.EMA:
return exponential_moving_average(values)


@click.command(
help="Computes the differences between consecutive images in a directory."
)
@click.option(
"-i",
"--image-directory",
required=True,
type=click.Path(exists=True),
help="Directory where images are stored. Expected to be .jpg files, and will be processed in lexicographic order.",
)
@click.option(
"-d",
"--diff-file",
type=click.File("w"),
help=".csv file to store diffs. If not specified, diffs will not be stored.",
)
@click.option(
"-p", "--show-plot", is_flag=True, default=False, help="Show diffs as plot."
)
@click.option(
"-s",
"--smoothing-option",
type=click.Choice(
list(map(lambda x: x.name, SmoothingOption)), case_sensitive=False
),
default=SmoothingOption.NO.name,
help="Smoothing options for values shown on plot.",
)
def main(
image_directory: str,
diff_file: click.utils.LazyFile,
show_plot: bool,
smoothing_option: str,
):
print("Computing diffs...")
file_list = glob.glob(os.path.join(image_directory, "*.jpg"))
diffs = calculate_diffs(file_list)
if diff_file is not None:
print(f"Writing diffs to {diff_file.name}")
for diff in diffs:
diff_file.write(f"{diff}\n")
else:
print(f"Diffs are {np.array(diffs)}")
if show_plot:
smoothed_diffs = smooth_values(diffs, SmoothingOption[smoothing_option])
plt.plot(diffs)
plt.plot(smoothed_diffs)
plt.show()


if __name__ == "__main__":
main()
28 changes: 14 additions & 14 deletions src/main/others/ipmailer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3

### BEGIN INIT INFO
# Provides: ipmailer.py
Expand All @@ -12,32 +12,32 @@

import subprocess
import smtplib
import socket
from email.mime.text import MIMEText
import datetime
# Change to your own account information

# [Nov 21, 2020]: This script is no longer used.

### ENTER OWN INFORMATION HERE
to =
gmail_user =
gmail_password =
to = None
gmail_user = None
gmail_password = None

smtpserver = smtplib.SMTP('smtp.gmail.com', 587)
smtpserver = smtplib.SMTP("smtp.gmail.com", 587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo
smtpserver.login(gmail_user, gmail_password)
today = datetime.date.today()
# Very Linux Specific
arg='ip route list'
p=subprocess.Popen(arg,shell=True,stdout=subprocess.PIPE)
arg = "ip route list"
p = subprocess.Popen(arg, shell=True, stdout=subprocess.PIPE)
data = p.communicate()
split_data = data[0].split()
ipaddr = split_data[split_data.index('src')+1]
my_ip = 'Your ip is %s' % ipaddr
ipaddr = split_data[split_data.index("src") + 1]
my_ip = "Your ip is %s" % ipaddr
msg = MIMEText(my_ip)
msg['Subject'] = 'IP For RaspberryPi on %s' % today.strftime('%b %d %Y')
msg['From'] = gmail_user
msg['To'] = to
msg["Subject"] = "IP For RaspberryPi on %s" % today.strftime("%b %d %Y")
msg["From"] = gmail_user
msg["To"] = to
smtpserver.sendmail(gmail_user, [to], msg.as_string())
smtpserver.quit()
1 change: 0 additions & 1 deletion src/main/python/imageComparison/__init__.py

This file was deleted.

81 changes: 0 additions & 81 deletions src/main/python/imageComparison/selectImages.py

This file was deleted.

0 comments on commit 228e616

Please sign in to comment.