Last active
August 29, 2022 20:53
-
-
Save martinohanlon/52a7557a91d9e5b353a278447fbacc34 to your computer and use it in GitHub Desktop.
a guizero app which uses the picamera to make stop motion gifs
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
# This is a simple gui for creating stop motion animations using the Pi camera | |
# martin@ohanlonweb.com | |
# stuffaboutcode.com | |
# Instructions: | |
# - Connect a camera module | |
# - Enable the camera (Menu > Preferences > Raspberry Pi Configuration, Interfaces, Camera) | |
# - Install the relevant modules, open a terminal (Menu > Accessories > Terminal) and run: | |
# - sudo pip3 install guizero | |
# - sudo pip3 install imageio | |
# - Run the program | |
# - python3 guizero_stopmotion.py | |
from guizero import App, Box, Picture, Text, PushButton, info | |
from io import BytesIO | |
import imageio | |
from PIL import Image | |
from picamera import PiCamera | |
from picamera.array import PiRGBArray | |
from time import time | |
def update_gui(): | |
if len(animation.images) == 0: | |
instructions.value = "take your first image" | |
pic_button.enable() | |
del_button.disable() | |
reset_button.disable() | |
save_button.disable() | |
animation.hide() | |
else: | |
# build gif from animation.images | |
# write the animated gif to BytesIO object | |
gif_output = BytesIO() | |
imageio.mimsave(gif_output, animation.images, format="gif") | |
# set the animation to a PIL image of the gif | |
animation.image = Image.open(gif_output) | |
instructions.value = "take another image" | |
# enable the gui | |
pic_button.enable() | |
del_button.enable() | |
reset_button.enable() | |
save_button.enable() | |
animation.show() | |
def take_pic(): | |
# take a picture | |
pic_button.disable() | |
instructions.value = "adding ..." | |
gui.tk.update() | |
# capture the image | |
camera.capture(camera_output, "rgb") | |
# append the camera image to the list as a numpy array | |
animation.images.append(camera_output.array) | |
# truncate the camera output now we have dealt with it | |
camera_output.truncate(0) | |
update_gui() | |
def del_pic(): | |
instructions.value = "deleting ..." | |
gui.tk.update() | |
animation.images.pop() | |
update_gui() | |
def reset(): | |
animation.images = [] | |
update_gui() | |
def save(): | |
file_name = "animation_{}.gif".format(time()) | |
imageio.mimsave( | |
file_name, | |
animation.images, | |
format="gif") | |
info("save", "animation saved as {}".format(file_name)) | |
# create the camera | |
camera = PiCamera(resolution="640x480") | |
camera_output = PiRGBArray(camera) | |
# create the gui | |
gui = App(title="stop motion animation") | |
controls = Box(gui, layout="grid") | |
instructions = Text(gui) | |
pic_button = PushButton( | |
controls, | |
text="take image", | |
command=take_pic, | |
grid=[0,0]) | |
del_button = PushButton( | |
controls, | |
text="delete last", | |
command=del_pic, | |
grid=[1,0]) | |
reset_button = PushButton( | |
controls, | |
text="reset", | |
command=reset, | |
grid=[2,0]) | |
save_button = PushButton( | |
controls, | |
text="save", | |
command=save, | |
grid=[3,0]) | |
animation = Picture(gui) | |
animation.images = [] | |
update_gui() | |
gui.display() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have the feeling that you keep the default auto value for exposure.
As far as I know, you want to have a fixed value that is identical for all the frame from your stop motion.
Otherwise, fixed element in the picture might change "color" just because the average light of the scene.
To avoid that, best would be to take a first picture in auto mode, get the chosen exposure and fix it to that value for all picture.
Full disclosure, I never player much with camera on the Pi and the last time I did stop motion was likely 30 years ago in the analog world...
Regards