Skip to content

Instantly share code, notes, and snippets.

@emm-ess
Created September 21, 2016 15:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emm-ess/dcd0831f97f302e4740591a9efd990c0 to your computer and use it in GitHub Desktop.
Save emm-ess/dcd0831f97f302e4740591a9efd990c0 to your computer and use it in GitHub Desktop.
Basic script for listening to button presses and taking photos on a Raspberry Pi. It's work in progress so...
import time
import os
import sys
import getopt
import io
import picamera
import RPi.GPIO as GPIO
import datetime
from PIL import Image
import threading
config = {}
config['dir'] = 'photos/'
config['numberOfPhotos'] = 4
config['imgSize'] = 2464
config['inputPin'] = 23
config['outputPin'] = 15
config['lightPin'] = 14
config['indicator1Pin'] = 24
config['indicator2Pin'] = 25
# 0 -> Display only
# 1 -> LEDs only
config['countdownMode'] = 1
cam = None
stream = None
hotSince = None
class countdownThread (threading.Thread):
def __init__(self, threadID, name, method, led):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.method = method
self.led = led
self.time = 10.0
def run(self):
sleep = 0.1
for i in range(0, 10):
GPIO.output(self.led, GPIO.HIGH)
time.sleep(sleep)
GPIO.output(self.led, GPIO.LOW)
time.sleep(1 - sleep)
sleep += 0.1
def createFolderStructure():
if not os.path.exists(config['dir']):
os.makedirs(config['dir'])
def countdown():
if config['countdownMode'] == 0:
countdownDisplay()
elif config['countdownMode'] == 1:
countdownLED()
def countdownDisplay():
# o = None
for i in reversed(range(0, 10)):
num = i + 1
cam.annotate_text = '%s' % num
# print(i)
# proc = subprocess.Popen(["./pngview", "-l", "4", "./overlays/countdown-3.png"]) # ./pngview -l 3 ./overlays/countdown-3.png
# img = config['overlays']['countdown'][i]
# # img.convert('RGB')
# pad = Image.new('RGB', (
# ((img.size[0] + 31) // 32) * 32,
# ((img.size[1] + 15) // 16) * 16,
# ))
# # Paste the original image into the padded one
# pad.paste(img, (0, 0))
# if not o:
# o = cam.add_overlay(pad.tobytes(), layer=3, size=img.size, alpha=128)
# else:
# o.update(img.tostring())
time.sleep(1)
# os.kill(proc.pid, signal.SIGTERM)
# proc.communicate()
# cam.remove_overlay(o)
cam.annotate_text = ''
def countdownLED():
threads = []
thread1 = countdownThread(1, "Thread-1", "lin", config['indicator1Pin'])
thread2 = countdownThread(2, "Thread-2", "log", config['indicator2Pin'])
thread1.start()
thread2.start()
threads.append(thread1)
threads.append(thread2)
for t in threads:
t.join(10)
def handleButtonPress(channel):
now = datetime.datetime.now()
if (now - hotSince).total_seconds() > 0.5:
unsetButtonDetection()
takePhotos()
setButtonDetection()
def unsetButtonDetection():
# GPIO.remove_event_detect(config['inputPin'])
GPIO.output(config['outputPin'], GPIO.LOW)
def setButtonDetection():
GPIO.output(config['outputPin'], GPIO.HIGH)
# tell the GPIO library to look out for an
# event on pin 23 and deal with it by calling
# the buttonEventHandler function
global hotSince
hotSince = datetime.datetime.now()
def takePhotos():
global stream
imgs = []
timeStamp = '{:%Y%m%d_%H%M%S}'.format(datetime.datetime.now())
print('take pictures: ' + timeStamp)
# proc = subprocess.Popen(["./pngview", "-l", "4", "./overlays/image-0.png"])
countdown()
# Now fix the values
# camera.shutter_speed = camera.exposure_speed
# camera.exposure_mode = 'off'
# g = camera.awb_gains
# camera.awb_mode = 'off'
# camera.awb_gains = g
for i, filename in enumerate(cam.capture_continuous(stream, 'jpeg')):
print('Captured image %s' % i)
stream.seek(0)
img = Image.open(stream)
imgs.append(img.copy())
stream.seek(0)
if i == config['numberOfPhotos'] - 1:
# os.kill(proc.pid, signal.SIGTERM)
break
else:
# os.kill(proc.pid, signal.SIGTERM)
# proc = subprocess.Popen(["./pngview", "-l", "4", "./overlays/image-%s.png" % i])
countdown()
# Turn automation back on
# camera.exposure_mode = 'auto'
# camera.awb_mode = 'auto'
combineImages(timeStamp, imgs)
def combineImages(timeStamp, imgs):
try:
print("copying")
img = Image.new('RGB', (config['imgSize'] * 2, config['imgSize'] * 2))
img.paste(imgs[0], (0, 0))
img.paste(imgs[1], (config['imgSize'], 0))
img.paste(imgs[2], (0, config['imgSize']))
img.paste(imgs[3], (config['imgSize'], config['imgSize']))
print("saving")
img.save(config['dir'] + timeStamp + '.jpg', 'JPEG')
print("saved")
except IOError:
print("IOError")
def usage():
print("Usage: python3 fotomat.py --dir photos --photos 4 --size 2464")
def getOptions(argv):
global config
try:
opts, args = getopt.getopt(argv, "d:p:s:", ["dir=", "photos=", "size="])
except getopt.GetoptError:
usage()
sys.exit(2)
for opt, arg in opts:
if opt in ("-d", "--dir"):
config['dir'] = arg.strip()
elif opt in ("-p", "--photos"):
# TODO
# config['numberOfPhotos'] = arg
pass
elif opt in ("-s", "--size"):
config['size'] = arg
def pushOverlaysIntoArray(arr, prefix, max):
for i in range(0, max):
img = Image.open(prefix + '-%s.png' % i)
arr.append(img.copy())
def loadOverlays():
global config
config['overlays'] = {}
config['overlays']['image'] = []
pushOverlaysIntoArray(config['overlays']['image'], './overlays/image', 4)
config['overlays']['countdown'] = []
pushOverlaysIntoArray( config['overlays']['countdown'], './overlays/countdown', 10)
def main(argv):
getOptions(argv)
# loadOverlays()
# tell the GPIO module that we want to use
# the chip's pin numbering scheme
GPIO.setmode(GPIO.BCM)
GPIO.setup(config['outputPin'], GPIO.OUT)
GPIO.setup(config['lightPin'], GPIO.OUT)
GPIO.setup(config['indicator1Pin'], GPIO.OUT)
GPIO.setup(config['indicator2Pin'], GPIO.OUT)
# setup pin 23 as an input
GPIO.setup(config['inputPin'], GPIO.IN, pull_up_down=GPIO.PUD_UP)
setButtonDetection()
GPIO.add_event_detect(config['inputPin'], GPIO.FALLING, handleButtonPress, 200)
createFolderStructure()
with picamera.PiCamera() as camera:
global cam
global stream
stream = io.BytesIO()
cam = camera
camera.annotate_text_size = 128
camera.resolution = (config['imgSize'], config['imgSize'])
camera.flash_mode = 'on'
camera.rotation = 90
camera.start_preview()
# camera.exif_tags['IFD0.Artist'] = 'Me!'
# camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2013 Me!'
try:
while True:
pass
except KeyboardInterrupt:
pass
camera.stop_preview()
GPIO.cleanup()
stream.close()
if __name__ == "__main__":
main(sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment