My wife was getting frustrated with me continually leaving the garage door open. Mice would get in overnight, and we would find them in traps in the house. Sure, I could get an inexpensive Wifi adapter for my garage door openers and remotely close them via an app, but what fun is that? I figured I could put my newly purchased Google AIY Vision kit to use and see what I could do with computer vision!
For those that want to get familiar with the Vision Kit, I recommend going to https://aiyprojects.withgoogle.com/vision to see the kit and the examples. It consists of a Raspberry Pi Zero WH, a Raspberry Pi V2 Camera, and a Vision Bonnet (a Myriad 2450 ML accelerator) along with some other stuff (LEDs, buzzer). After experimenting with the smile detector and other examples, I wanted to put the kit to use.
I set up the kit on a small shelf that I installed in my garage facing towards the garage doors. Totally optional, but I plugged the kit into a smart plug, so it could power down at night and start up in the morning (what's the point of it running overnight?).
First, I needed to collect some data for the computer vision model. I wrote a simple Python script to take a photo and save it with a timestamp. I then set up a cron job run that script once an hour from sunrise to sunset. I did this for about a week to get a good range of lighting and different states (one door open, both doors open, both doors closed, garage empty, 1 or 2 cars in the garage) for the model. Python script code below:
#!/usr/bin/env python3
#Take some photos of the garage to further improve the image classifier
#Run hourly as a cron job during daylight hours
from datetime import datetime
from picamera import PiCamera, Color
#set the filename path for the garage photos
timenow = datetime.now()
timeStr = timenow.strftime("%m-%d-%Y-%H%M%S")
file_path = '/home/pi/garage_screenshots/garage_' + timeStr + '.jpg'
with PiCamera(sensor_mode=4, resolution=(1640, 1232), framerate=30) as camera:
camera.capture(file_path)
Once I had enough photos, I leveraged the Google Colab from the Vision Kit tutorial. It runs a default flower classification model so I had to replace the flower photos with the photos from my garage. Given that a Colab is only a temporary instance, you have to upload the photos to the Colab each time you run it. A small price to pay for being able to use the Google GPUs to train your model. I created a garage_photos folder with 2 subfolders: open and closed. These subfolders align to the inference labels that you would get as output from the model. I populated the open folder with photos with at least one garage door open, and populated the closed folder with photos of both the doors closed Here is the change I made in the Colab:
python scripts/retrain.py \
--bottleneck_dir=tf_files/bottlenecks \
--how_many_training_steps=500 \
--model_dir=tf_files/models/ \
--summaries_dir=tf_files/training_summaries/$ARCHITECTURE \
--output_graph=tf_files/retrained_graph.pb \
--output_labels=tf_files/retrained_labels.txt \
--architecture=$ARCHITECTURE \
--image_dir=tf_files/garage_photos
All the other steps remain the same. I saved a local copy of the Google Colab to my Google Drive so I wouldn't have to update the Colab each time I ran it. Based on the output, my model was getting low 90s in accuracy for validation and test data. Good enough for me, and I could continually add more photos to improve the model results.
Once the Colab was complete, I downloaded the model (two files are created: retrained_graph.binaryproto and retrained_labels.txt) and copied them over to the Raspberry Pi Zero.
Now, the script to check the garage door status! I kept this simple as well, adding a cron job to run the script only once (near dusk, so I change the time as we get more or less sunlight). I *heavily* leveraged Google's mobilenet_based_classifier.py Python script to feed in the model arguments and run inference. Once the results were in, I took a camera capture (just to validate the inference results) and emailed the garage door status and a photo to my wife and I using smtplib. I also set up a Twilio trial account to send a text message of the garage door status (no image though, to keep it cheaper) using the Twilio API. And when the cronjob ran, success!
Future improvements?
So what's next? I think the next step for me is to automate it! If the garage door is open, I still have to go downstairs and close it. How much of a pain is that? :) Why not just have the program close the garage door if it detects that it is open?
That will be version 2 of this project. I started testing out a 2-channel relay switch with the vision kit, and I was able to run a simple script to have each relay open and close (but boy was it a pain to figure out how to wire it given that it is a 5V relay with 3.3V logic on the Raspberry Pi!). I plan to run wire from the relay to the push buttons for the garage door openers and trigger them when the program detects a door open. I will also have to update the model to differentiate between the two garage doors. Right now my model only cares if 1 door is open or if they are both closed.
I hope you enjoyed this project. It was fun to learn the inner workings of the Vision Kit and then repurpose it for something practical for my home. Feel free to leave me any comments and/or feedback. Thanks!
Comments