How to detect multiple faces using opencv in order to generate an output of flickering LED lights

edited April 2015 in Arduino

Hi there,

I am a fairly new at using processing and opencv, so please bear with me. I have been working on a light installation using Arduino and Processing. I am capturing people using face detection with a webcam and opencv, and translating it into a light installation that is working off a 16x32 LED matrix panel. The light installation is a response of the amount of spectators who are viewing the lights and being recorded at the same time - the idea is that the more people being recorded will generate a greater display of flickering lights, and when no one is viewing/being recorded, the lights will not flicker.

I have managed to get opencv to detect faces and output it to Arduino to display on the lights, however I can only get the lights to flash more intensely when people are not being detected, rather than when they are being detected. Therefore, the lights are working in reverse, and they flicker more when no-one is being detected, and less when there are people being detected.

I have attached both my Processing and Arduino code for reference, although I do not think that the Arduino code needs to be changed at all.

( I have highlighted an area in the processing code which I believe is the part that is causing the issue)

I would really appreciate who knows a way of changing this so the face detection triggers more lights :) Thanks

I have also cross posted this question on Stackoverflow to reach a wider audience -- Stackoverflow forum.

// Processing code:


> import gab.opencv.*;
> import java.awt.*;
> import processing.video.*;
> import processing.serial.*;
> import java.awt.Color;
> 
> Capture video;
> OpenCV opencv;
> 
> Serial myPort;  // Create object from Serial class
> int inByte = -1; 
> 
> void setup() 
> {
>   size(640, 480);
>   video = new Capture(this, 640/2, 480/2);
>   opencv = new OpenCV(this, 640/2, 480/2);
>   opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE);
>   video.start();
>   
>   println(Serial.list());
>   //colorMode(HSB, 100,100,100);
>   String portName = Serial.list()[5];
>   myPort = new Serial(this, Serial.list()[5], 9600);
>  
> }
> 
> void draw() {
>   
>   scale(2);
>   opencv.loadImage(video);
> 
>   image(video, 0, 0 );
> 
>   noFill();
>   stroke(0, 255, 0);
>   strokeWeight(3);
>   Rectangle[] faces = opencv.detect();
>   println(faces.length);
> 
> //  do cool stuff here:
> 
>     int x = int(random(32));
>     int y = int(random(16));
>     int H = int(222);
>     int S = int(5);
>     int L = int(random(3));
> 
>     
>     int R =  int(random(255));
>     int G =  int(random(255));
>     int B =  int(random(255));
> 
>     
>     int F = 0;
>     String toard = x + ":" + y + ":" + R + ":" + G + ":" + B + ":" + F +".";
>     
>      myPort.write(toard);   
>      
>   
**>   for (int i = 0; i < faces.length; i++) {
>    
>       rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height);
>       toard = x + ":" + y + ":" + 0 + ":" + 0 + ":" + 0 + "."; 
>       myPort.write(toard);
>       if (faces.length == 0){
>        delay(faces[0].x); 
>        
>        
>  
>      } 
>   }**
>   
> 
>     // listen back to the serial data from arduino
>     // this is handy for debugging
>     
>       while (myPort.available () > 0) {
>       
>         // send the string to the arduino over serial port
>         inByte = myPort.read();
>        
>     }
>   
>  }
> 
> 
> void captureEvent(Capture c) {
>   c.read();
> }
>  

//Arduino Code:


> const char EOPmarker = '.';
> char serialbuf[32];
> 
> #include <Adafruit_GFX.h>
> #include <RGBmatrixPanel.h> // Hardware-specific library
> #define MAX_STRING_LEN 20
> #include <string.h>
> 
> #define CLK 8  // MUST be on PORTB! (Use pin 11 on Mega)
> #define LAT A3
> #define OE  9
> #define A   A0
> #define B   A1
> #define C   A2
> RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, false);
> 
> uint8_t r=7, g=7, b=7;
> 
> void setup() {
>    
> 
>   Serial.begin(9600);
>   matrix.begin();
>   pinMode(13, OUTPUT);
>   digitalWrite(13, LOW);
> }
> 
> void loop() {
>   

>     if (Serial.available() > 0) {
>       static int bufpos = 0; 
>       char inchar = Serial.read(); 

>       if (inchar != EOPmarker) { 
>         serialbuf[bufpos] = inchar; 
>         bufpos++; 
>         
>       }
>       
>       else { 
>  
>         serialbuf[bufpos] = 0; 
>         bufpos = 0; ![]()
>  
>       }
>       
>     
>  // this is where we grab the x y HSB values and do whatever we thing is nice :) 
>                // send back to processing for debugging 
>   
>          int x = atoi(subStr(serialbuf, ":", 1));
>          int y = atoi(subStr(serialbuf, ":", 2));
>          int R = atoi(subStr(serialbuf, ":", 3));
>          int G = atoi(subStr(serialbuf, ":", 4));
>          int B = atoi(subStr(serialbuf, ":", 5));
>          int F = atoi(subStr(serialbuf, ":", 6));
> 
>          
>          float vR = map(R, 0,255, 0,7);
>          float vG = map(G, 0,255, 0,7);
>          float vB = map(B, 0,255, 0,7);
>           
>           Serial.write(x);
>       matrix.drawPixel(x, y, matrix.Color333(vR, vG, vB));
>     
> 
>     }
>   
> }
> 
> 
> // this is the function that allows us to easily grab an item from the string by index
> 
> char* subStr (char* input_string, char *separator, int segment_number) {
>   char *act, *sub, *ptr;
>   static char copy[MAX_STRING_LEN];
>   int i;
>   strcpy(copy, input_string);
>   for (i = 1, act = copy; i <= segment_number; i++, act = NULL) {
>     sub = strtok_r(act, separator, &ptr);
>     if (sub == NULL) break;
>   }
>   
>  return sub;
> 
> }
Sign In or Register to comment.