Marcelo MuroDorianaDiego Martinez
Published © GPL3+

Chromatic Climate: LoT Project

In this project, we set up a camera in a busy hallway to record the colors and hues people wear during specific weather patterns.

IntermediateFull instructions provided805
Chromatic Climate: LoT Project

Things used in this project

Hardware components

Resistor 330 ohm
Resistor 330 ohm
×6
RGB Diffused Common Cathode
RGB Diffused Common Cathode
×2
Wire Cable - By the Foot
OpenBuilds Wire Cable - By the Foot
×1
SparkFun solder
×1
Raspberry Pi 2 Model B
Raspberry Pi 2 Model B
×1
Female/Female Jumper Wires
Female/Female Jumper Wires
×8

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Laser cutter (generic)
Laser cutter (generic)

Story

Read more

Custom parts and enclosures

Face Piece

This is front piece that is glued to the rest of the enclosure.

Enclosure

Box pieces that are to be screwed together and glued to the face piece.

Schematics

Fritzing Diagram

Bread bored Diagram of RGB LED's

PCB sketch (optional)

We did not use a PCB for this project. However, one can be used as shown in this sketch.

Code

Camera capture and color analysis

Python
This script sets up the camera to capture images at 60 second intervals for a specified amount of time (in this case, a week) and also analyzes the RGB values of the image to calculate an 'average' color. It then outputs the 'average' color out to the LEDs
from time import sleep
import thread
import datetime
import picamera
import picamera.array
import RPi.GPIO as GPIO

tracker = open("data.txt", "a")

pins = [40,38,36,22,24,26]
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(1)

for pin in pins:
  GPIO.setup(pin, GPIO.OUT)


completedString = []

imageData = 0
sumRed = 0
sumGreen = 0
sumBlue = 0
avgR = 0
avgG = 0
avgB = 0 
minute = 0


def analyze(x,imageNum):
  global sumRed, sumGreen, sumBlue
  global avgR, avgG, avgB

  tupleArray = []
  flag = 1
  i = 1
  imagename = "image%s.jpg" % imageNum
  
  tupleArray = imageData

  while i < 640:
    sumRed += tupleArray[i,i,0].item()
    sumGreen += tupleArray[i,i,1].item()
    sumBlue += tupleArray[i,i,2].item()
    i += 1
  
  avgR = sumRed / 640
  avgG = sumGreen / 640
  avgB = sumBlue /640

  tracker.write("Time: %s \nAvg Red: %s \nAvg Green: %s \nAvg Blue: %s \nImage name: %s \n\n" % (timestamp, avgR,
  avgG, avgB, imagename))
  tracker.flush()
  return

#40, 26 RED
#38, 24 GREEN
#36, 22 BLUE

timestamp = 0

with picamera.PiCamera() as camera:
  with picamera.array.PiRGBArray(camera) as output:
    while(minute < 10080):
        camera.iso = 800
        camera.resolution = (640,640)
        camera.capture(output,'rgb')
        camera.capture("pics/img%s.jpg" % str(minute))
        timestamp = datetime.datetime.now().strftime("%d. %B %Y %I:%M:%S%p")
        imageData = output.array
        thread.start_new_thread(analyze, (1,minute))
        if(avgR > 255 / 2):
          GPIO.output(40, GPIO.HIGH)
          GPIO.output(26, GPIO.HIGH)
        else:
          GPIO.output(40, GPIO.LOW)
          GPIO.output(26, GPIO.LOW)

        if(avgG > 255 / 2):
          GPIO.output(38, GPIO.HIGH)
          GPIO.output(24, GPIO.HIGH)
        else:
          GPIO.output(38, GPIO.LOW)
          GPIO.output(24, GPIO.LOW)

        if(avgB > 255 / 2):
          GPIO.output(36, GPIO.HIGH)
          GPIO.output(22, GPIO.HIGH)
        else:
          GPIO.output(36, GPIO.LOW)
          GPIO.output(22, GPIO.LOW)
        sleep(60)
        output.truncate(0)
        minute += 1
GPIO.cleanup()

csvconvert.py

Python
This script corrects an error that is present in the camera capture script. The problem lies within the recording of the RGB values. Once it is done recording, the corrected RGB values are parsed into a .csv file. You must provide a blank .csv file in order for this script to run. This script assumes that you have named your recorded data 'data' and have saved it in the .txt format.
datafile = open("data.txt", "r")

csvfile = open("vals.csv", "a")

csvfile.write("Time,Average Red,Average Green,Average Blue,Image\n")

avgred = []
avggreen = []
avgblue = []

correctedr = []
correctedg = []
correctedb = []

timestamp = []
name = []

for line in datafile:
	if(line[0:8] == "Avg Red:"):
		avgred.append(int(line[9:]))
	elif(line[0:10] == "Avg Green:"):
		avggreen.append(int(line[11:]))
	elif(line[0:9] == "Avg Blue:"):
		avgblue.append(int(line[10:]))
	elif(line[0:5] == "Time:"):
	  #timelen removes the newline operator from the timestamp
		timelen = len(line) - 2
		timestamp.append(line[6:timelen])
	elif(line[0:5] == "Image"):
	  #textlen removes the newline operator from the image name
		textlen = len(line) - 2
		name.append(line[12:textlen])

counter = 0
length = len(avgred) - 1

correctedr.append(avgred[0])
correctedg.append(avggreen[0])
correctedb.append(avgblue[0])

for num in avgred:
	if counter < length:
		if avgred[counter + 1] > avgred[counter]:
			correctedr.append(avgred[counter + 1] - avgred[counter])
		else:
			correctedr.append(avgred[counter + 1])

		if avggreen[counter + 1] > avggreen[counter]:
			correctedg.append(avggreen[counter + 1] - avggreen[counter])
		else:
			correctedg.append(avggreen[counter + 1])

		if avgblue[counter + 1] > avgblue[counter]:
			correctedb.append(avgblue[counter + 1] - avgblue[counter])
		else:
			correctedb.append(avgblue[counter + 1])
			
		csvfile.write("%s,%s,%s,%s,%s\n" %(timestamp[counter],correctedr[counter],
			correctedg[counter],correctedb[counter],name[counter]))
	counter += 1

csvfile.close()
datafile.close()

Credits

Marcelo Muro

Marcelo Muro

-1 projects • 0 followers
Doriana

Doriana

-1 projects • 1 follower
Diego Martinez

Diego Martinez

-1 projects • 0 followers
18 year old college student at UIC

Comments