ChameleonPi - Camouflage your Pi using a camera and LedBorg
How about getting your Raspberry Pi to blend in with it's surroundings using an LedBorg!
What we need is a simple cycle of events to do this:
- Take a photo using the camera
- Load the image data into our program
- Crop the image so we focus on the center of our view
- Average the remaining pixels into a single pixel
- To cope with lighting changes, brighten the pixel up so one of red, green, or blue is fully on
- Convert the pixel colour into an LedBorg code
- Set the LedBorg to the calculated code
Sounds complicated, but we will use Python's image library PIL to do the heavy lifting for the most part.
You can download ChameleonPi.py as text here.
Save it on your Raspberry Pi as ChameleonPi.py
Make it executable using
chmod +x ChameleonPi.py
and run it using
#!/usr/bin/env python # coding: latin-1 # Import library functions we need import time import os import threading from PIL import Image # Setup for ChameleonPi imageFile = '/tmp/chameleon-image.jpg' # Image file to read in for processing imageCommand = 'raspistill -t 0 -o ' + imageFile # Command used to create image file interval = 1 # Seconds to wait between updates # Set the LedBorg colour by LedBorg code def SetColour(colour): LedBorg=open('/dev/ledborg','w') LedBorg.write(colour) LedBorg.close() # Convert a single 0-255 channel into an LedBorg 0-2 code def ChannelToCode(c): if c < 85: return '0' elif c < 171: return '1' else: return '2' # Set the LedBorg colour by 0-255 RGB values def SetRgb(r, g, b): ledCode = ChannelToCode(r) + ChannelToCode(g) + ChannelToCode(b) SetColour(ledCode) # Class for the user interaction thread class WaitForUser(threading.Thread): # The code which will be run when the thread is started def run(self): global waiting # Wait for the user to press enter tempString = raw_input() # Set the running flag and finish print 'Please wait...' waiting = False # Setup status flags global waiting waiting = True try: # Setup a thread to wait for user input print 'Press ENTER to end the program' WaitForUser().start() # Run until interrupted while waiting: # Call the external command to generate a photo os.system(imageCommand) # Read in the photo photo = Image.open(imageFile) # Crop out the center section width, height = photo.size x1 = int(width * 0.4) x2 = int(width * 0.6) y1 = int(height * 0.4) y2 = int(height * 0.6) cropPhoto = photo.crop((x1, y1, x2, y2)) # Average the cropped image down to a single colour tinyPhoto = cropPhoto.resize((1,1), Image.ANTIALIAS) r, g, b = tinyPhoto.getpixel((0,0)) # Scale RGB such that the highest channel is fully on scale = 255.0 / max(r, g, b) r *= scale g *= scale b *= scale # set the LedBorg colour SetRgb(r, g, b) # Wait a while if waiting: time.sleep(interval) print 'All done :)' SetColour('000') except KeyboardInterrupt: # CTRL+C exit, turn off the LedBorg print 'Terminated' SetColour('000')