Pi 5!

A project log for Pi 5 Photo Booth

Designed to be as user-friendly as possible and take great photos, without breaking the bank

colin-pateColin Pate 02/23/2024 at 02:120 Comments

I've added a few cool upgrades and new features to the booth since my last update. One of the biggest is that I decided to upgrade from the Pi 4B to the Pi 5!

The Pi 5 offers a few key improvements:

Each of these on their own isn't enough to justify the switch, but when a new Pi comes out after 5 years of waiting, you can't not put one in a project.

Here's a rundown of the new features I've added to the photo booth.

Distortion Correction

The officially sanctioned Pi HQ Camera M12 Portrait lens is the best M12 lens with an appropriate focal length that I've found so far, though I've only tested it against two AliExpress lenses that didn't quite measure up. Its main drawback is that it has a surprising amount of barrel distortion for being a portrait lens. This door photo shows how curvy it gets at the edges.

This distortion isn't super noticeable for most photos, but can make people's faces at the edge of the frame look a little weird. In my search for maximum image quality, I decided to take advantage of OpenCV's easy distortion correction functions.

Correcting for the distortion involves printing out a checkerboard, taking a bunch of pictures holding the checkerboard, running a quick script to get the lens intrinsics, and implementing the distortion correction in the main photo booth script.

Here's my quick and dirty script that reads the checkerboard and outputs a file of the lens correction (warning, magic numbers and hardcoded paths abound).

The main file looks for the the intrinsics file (set in config.yaml) and if it exists, it remaps the image. Here's the result of the remapping on the door photo above.

Glowy Pulsing LED Button

When testing the photo booth at an NYE party, I discovered that the distinction between the button and camera weren't clear to some users, despite their different locations and appearances. To help make sure that everyone would know where to put their finger, I added a nice button with a blue LED ring surround, and added code to give it a smooth pulsing effect. The best one I could find is on AliExpress, linked below. I went with the 22mm size.

Hardware PWM

The switch from the 4B to 5 necessitated a few changes to the software. The 5 doesn't support the pigpio library that I was using to control the LEDs and read the button, so I switched to gpiozero. However, I wasn't super happy with the PWM control in this library, so I switched to using the rpi_hardware_pwm library. I had to modify it a bit to get it to work with the pins I wanted, so I submitted a PR to hopefully get that fixed soon.


I discovered that no matter how you name your files, when you upload them to iCloud or Google Photos, they get shuffled randomly in the resulting album. This was pretty annoying, especially when I wanted to upload both the color and monochrome photos to the same album, because the color images wouldn't show up next to their monochrome version. I realized that what they want for chronological sorting is timestamps in the EXIF metadata of the images. I used the piexif library to add the timestamps as EXIF, and voila, the photos are sorted in chronological order!

formatted_datetime ="%Y:%m:%d %H:%M:%S")
zeroth_ifd = {piexif.ImageIFD.Make: "colin",
                  piexif.ImageIFD.XResolution: (w, 1),
                  piexif.ImageIFD.YResolution: (h, 1),
                  piexif.ImageIFD.Software: "colin p"
exif_ifd = {piexif.ExifIFD.DateTimeOriginal: formatted_datetime,
                    piexif.ExifIFD.LensMake: "colin",
                    piexif.ExifIFD.Sharpness: 65535,
                    piexif.ExifIFD.LensSpecification: ((1, 1), (1, 1), (1, 1), (1, 1)),
exif_dict = {"0th":zeroth_ifd, "Exif":exif_ifd}
exif_bytes = piexif.dump(exif_dict), quality=95, exif=exif_bytes)