Loading...
Logo
Processing Forum
im having some problems with facial detection software in processing serially communicating  a servo using arduino. 

everything compiles, but nothing happens. somewhat a newbie, obviously. 

heres the code from both ends:

processing code:

the processing code:
Copy code

  1. import hypermedia.video.*;
  2. import java.awt.Rectangle;
  3. import processing.serial.*;        


  4. int gx = 15;
  5. int gy = 35;
  6. int spos=90;

  7. Serial port; 

  8. OpenCV opencv;

  9. // contrast/brightness values
  10. int contrast_value    = 0;
  11. int brightness_value  = 0;



  12. void setup() {

  13.     size( 320, 240 );

  14.     opencv = new OpenCV( this );
  15.     opencv.capture( width, height );                   // open video stream
  16.     opencv.cascade( OpenCV.CASCADE_FRONTALFACE_ALT );  // load detection description, here-> front face detection : "haarcascade_frontalface_alt.xml"

  17.     // print usage
  18.     println( "Drag mouse on X-axis inside this sketch window to change contrast" );
  19.     println( "Drag mouse on Y-axis inside this sketch window to change brightness" );

  20.  println(Serial.list());
  21.  port = new Serial(this, Serial.list()[1], 9600);
  22. }


  23. public void stop() {
  24.     opencv.stop();
  25.     super.stop();
  26. }



  27. void draw() {

  28.     // grab a new frame
  29.     // and convert to gray
  30.     opencv.read();
  31.     opencv.convert( RGB );
  32.     opencv.contrast( contrast_value );
  33.     opencv.brightness( brightness_value );

  34.     // proceed detection
  35.     Rectangle[] faces = opencv.detect( 1.2, 2, OpenCV.HAAR_DO_CANNY_PRUNING, 40, 40 );

  36.     // display the image
  37.     image( opencv.image(), 0, 0 );

  38.     // draw face area(s)
  39.     noFill();
  40.     stroke(255,0,0);
  41.     for( int i=0; i<faces.length; i++ ) {
  42.         rect( faces[i].x, faces[i].y, faces[i].width, faces[i].height ); 
  43.     }
  44. }



  45. /**
  46.  * Changes contrast/brigthness values
  47.  */
  48. void mouseDragged() {
  49.     contrast_value   = (int) map( mouseX, 0, width, -128, 128 );
  50.     brightness_value = (int) map( mouseY, 0, width, -128, 128 );
  51. }
  52. void update(int x) 
  53. {
  54.   //Calculate servo postion from mouseX
  55.   spos= x/4;

  56.   //Output the servo position ( from 0 to 180)
  57.   port.write(spos + "a"); 
  58.     gx = x/2;
  59.   gy = 100-x/2;

  60. }



and the Arduino code:

Copy code
  1.  
  2. #include <Servo.h>

  3. Servo neck;

  4. int xPos=0;
  5. int yPos = 0;

  6. void setup()  {
  7.   Serial.begin(9600);
  8.   neck.attach(13);
  9. }

  10. void loop()  {
  11.   if(Serial.available() >0)  {
  12.     xPos=Serial.read();
  13.     yPos=Serial.read();
  14.   }
  15.   int xServo = map(xPos, 0, 320, 20, 70);
  16.   int yServo = map(yPos, 0, 240, 20, 70);
  17.   neck.write(xServo);





Replies(11)

Hi Danieljay,

Maybe I'm wrong but you have an "update" function that writes to your serial port and you don't call this function in the draw loop.

In draw you'll need to add :

Copy code
  1. for( int i=0; i<faces.length; i++ ) {
  2.         update( faces[i].x); 
  3.     }

Hope it help !
thanks, but its giving me this error:


thanks  thomaspaillot


its working, but not great. i guess now i want to make the servo move its positions based on my movements once the facial tracking is registered to servo. 

any suggestions?

thanks you've been a huge help!
You cannot use faces before declaring/initializing it...
Up, I am also interested in this code. Can you help us ? 

its working, but not great. i guess now i want to make the servo move its positions based on my movements once the facial tracking is registered to servo. 

any suggestions?
Look at the openCV example: 

Copy code
  1.     for( int i=0; i<faces.length; i++ ) {
  2.         rect( faces[i].x, faces[i].y, faces[i].width, faces[i].height ); 
  3.         rect( faces[i].x + 0.5*faces[i].width, faces[i].y + 0.34*faces[i].height, 5, 5 ); 
  4.         
  5.         if (!faces[i].isEmpty()) 
  6.         {
  7.           println("there is a face");
  8.         }

  9.         //never enters
  10.          if (faces[i].width == 0) 
  11.         {
  12.           println("zero w");
  13.         }

  14.         print("(" + faces[i].x + "," + faces[i].y + ") ");
  15.         println("w: " + faces[i].width + ", h: " + faces[i].height);
  16.     }

Line # 3 gives you the centre point of the face. Either send that directly to Arduino, or normalize it by calculating it vis-a-vis the width and height of your applet.
You can check this tutorial, it's for openFrameworks but you can use the basics concept and rewrite it for processing. I start from this tutorial to make a processing sketch that track the biggest "blob" in the image and to send the movement to the servo in arduino. It works well.
Thank you for your answers. I'll see what I can do with all this new information. 
Dear Thomaspaillot ,  I do not want to abuse, but would it be possible to share your code for the "blob" project? This could also help me, I think ... Thanks


There's nothing special in this sketch but maybe you'll find it useful. You'll need ControlP5 library to run it.

Source :  Blob sketch


Thomas Paillot
Thank you Thomas for your help.  I use a Trossen with 2 servo and a webcam. But I don't understand why when the webcam detects something, the servo changes direction and loses the target. 

My Arduino code
Copy code
  1. #define DSERVO_TWO_X_PIN 3
  2. #define DSERVO_TWO_Y_PIN 4

  3. #include <Servo.h>

  4. Servo vert;
  5. Servo horz;
  6. byte xy[2];

  7. void setup() {
  8.   horz.attach(3);
  9.   vert.attach(5);
  10.   
  11.   Serial.begin(9600);
  12.   
  13. }

  14. void loop() {
  15.   
  16.   
  17.   if(Serial.available() > 1) {
  18.     xy[0] = Serial.read();
  19.     xy[1] = Serial.read();
  20.     
  21.     // now that we have the xy we can go ahead
  22.     // and write them to the serial
  23.     float ratio = 180.0/255.0;
  24.     horz.write(xy[0] * ratio);
  25.     vert.write(xy[1] * ratio);
  26.     delay(25);
  27.   }
  28.   
  29. }
Your arduino code seems ok. I made a few error in my processing code on the y value that is send to the arduino. Here's the sketch corrected. It should work this time.


Thomas Paillot