Things used in this project
The purpose of this project was to see whether there was any correlation between weather and the color of clothing people chose to wear. We were curious as to what extent the weather affected people's clothing choices. Some individuals may plan out their day accordingly, others may not care at all. We wanted to know roughly how much there was a change of color then.
We deployed our project in the window of our Computer Science teacher's classroom; an area with enough foot traffic to gather lots of data. Our project required a camera and needed to be displayed publicly, so we decided to design our enclosure in a way that would be visually appealing to people. Since we were trying to find a correlation between clothing color and weather, the face of the enclosure was fashioned in a way that made it look like a friendly cloud.
Developing the code was a simple process. The camera was set to capture an image every 60 seconds. A .jpg image was captured along with a 3D ndarray (Numpy array) populated with RGB values of the image. The next step was finding the overall average color of the image. In order to save on time, we did a rough analysis of the RGB values by utilizing pixels across a slanted line reaching from the top left to bottom right. Once that was completed, we recorded the average red, green, and blue values along with a time stamp and the image name to a file. Debugging the code was also pretty straightforward. In order to test that the camera was taking pictures every 60 seconds, we would change the loop for image capture to run only two times. The results of the image in the file were checked to ensure that everything was operational.
We faced challenges in both the design and programming process. For the camera, we needed to design and install the device in a manner which would prevent it from falling, and we needed to find a way which would prevent window glare from messing with the image. Our solutions were to place suction pads on the face of the device and mount it straight onto the glass window. By doing this we solved both problems at once. Glare was eliminated from the image, and we no longer had to fear that the device would fall. From the programming side of things, getting the camera to capture to a 3D Numpy (Python package) ndarray and converting the file into a .csv file was a challenge. Due to an unintentional mishap found in the code, the average RGB values we recorded were continuously added up in their own variables instead of resetting to 0 and capturing the new RGB average. This problem is resolved in the csv converter file.
Some knowledge and skill we gained was how to use Inkscape, how to use a laser-cutter, and how to work with a Raspberry Pi. On a broader scale, what we learned here was that a line of communication is necessary between the hardware designers and the software developers, and that careful planning is needed in order to ensure that everything runs smoothly and according to plan.
Custom parts and enclosures
Camera capture and color analysisPython
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()
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) correctedg.append(avggreen) correctedb.append(avgblue) 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()
Did you replicate this project? Share it!I made one
Love this project? Think it could be improved? Tell us what you think!