27 December 2015

Project: Photo Booth

Not too long ago, I was at a celebration where there was a photo booth. A camera on a tripod was pointed towards a backdrop. People could grab some props, stand in front of the backdrop, and the attendant would start the program, which would take a picture every 5 seconds or so. In between shots, you could race over to the props table, grab something new, race back, and pose with it, all before the timer expired.

The pictures would be composed onto a 4x6 photograph, complete with a logo of the event electronically slapped onto the corner, and printed out for you.

It was a lot of fun. Every party should have a photo booth.

For small, friends-and-family gatherings, though, the manned photo booth is unreasonable (and probably cost prohibitive). Fortunately, we live in a Maker era, and computing parts are affordable and abundant, so like many, many others (as is well documented on the Internet -- just like this post!), I decided to make my own photo booth.

TL; DR;

Fear my mad woodworking skillz!
The photobooth is a Raspberry Pi with an attached 7-inch touch screen for user interface and input. The Pi controls a Canon 300D / Digital Rebel DSLR over USB using gphoto2. Photos are downloaded to the Pi, re-sized, and composited together with a logo using ImageMagick. The composites are manually scp'd off the Pi occasionally, put on an SD card, and printed on a Canon Selphy CP910.

The whole application is written in Python 2.7 with a Kivy front end.

Unlike other photo booths which wrap everything up in a box or some such, I opted for a minimalist approach. Since I was using a DSLR on a tripod, I decided to mount the display, which holds the Raspberry Pi behind it, to the tripod neck, just below the camera (which is where the subjects should be looking, anyway). I had some scrap pieces of wood to make a frame. Wood glue and nails hold the frame together, and I chiseled out a ledge for the Raspberry Pi display to rest on. Some plumbers straps hold the screen in place via the mounting holes on the back, and some wood screws into the frame. Finally, a couple of U-bolts and foam hold the frame to the neck of the tripod.

Et voila!

Camera

Initially, I was going to use a Raspberry Pi camera, but I was worried about light. The Raspberry Pi camera is tiny, so needs a lot of light to take good pictures. A DSLR would be better, since it's a huge light bucket in comparison, and I happened to have an old Canon 300D / Digital Rebel sitting idle. Once I discovered gphoto2, there was no going back.

The down side to using a circa 2003 camera is it communicates over USB 1.1. Which...

...is...

...really...

...slow.

Downloading an image off the camera takes 30 seconds at highest resolution (a whopping 6.3 megapixels). Dropping the camera to lowest resolution reduces the time to around 15 seconds, but it's still painful. I ended up adding messages to the display while gphoto2 was churning in the background so the users don't think the application broke.

All this could be mitigated by using a more modern camera with a fast memory card and USB 2 (A faster microSD card in the Pi wouldn't hurt, either). But my budget for this project did not allow for the purchase of a newer camera. So interesting messages it was.

Printer

Based on this instructables, I opted for the Canon Selphy photo printer. It was around $80 on Amazon, and I could use it to print personal photos from home when not being used by the photo booth.

When I went to purchase a Canon Selphy, the CP900 had been replaced by the CP910. I figured it was still a pretty safe bet, since there weren't many differences between the two -- just the WiFi access point, as far as I could tell. And if I could incorporate the access point in the photo booth, bonus!

Unfortunately, things did not work out as I had hoped. The Gutenprint drivers available for the Selphy printers did not include the CP910 because it was too new. And unlike others' experiences with the CP900, the older drivers did not work well for me, even when talking tot he printer over USB. I was only able to print one picture. The next time I tried to print, the printer would load the photo paper, then hang. I had to disconnect the USB cable to get out of that mode, and then upon page ejection, the ink cartridge would be aligned to the wrong color (ah, dye sublimation printers).

The image was getting out of the cups queue, so I surmised something was wonky on the printer end.

The Selphy did, however, print just fine in batch mode from an SD card, so I opted for a manual, sneakernet solution. Every once in a while, I would collect the accumulated photo booth photos via scp, copy them to an SD card, and batch print them. The printer only holds 18 pages in the tray, so there would have been a lot of interruptions to service the printer anyway.

Conclusion

This was a fun project. I learned a bit about new libraries, and introduced myself to a new user interface option. I wrote some really ugly code while trying to wrap my head around all the new stuff. Now that I have a better idea of how things are supposed to interact in Kivy, I should go back and write things better. Make some unit tests to verify my code. Comment my code better. Make it ready for prime time. But I probably won't. 

This was, first and foremost, a research project to explore new ground. And when venturing into the unknown, it's hard to do test-driven development because you're unsure how things are meant to work. There was a lot of iterations on design on this project as I slowly figured out how Kivy wanted to be used. Once you've got an understanding of how things are supposed to work, then test-driven development can come into play. We'll use it on the next project.

Want to see what my ugly code looks like? This project is available on GitHub. Please check out my other projects to see how I normally write code.