We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello,
This is my first post on this forum, and i'm in need of your help. I'm working on a project with an android that has a set of animatronic eyes and a facetracking feature. I'm using the opencv library and Processing 3.3.6 to execute the tracking, and an arduino t control the eyes. At the moment i've created a script where the eyes are following only ONE face, but sometimes the eyes 'jump' when a new face enters the webcam. I would like to avoid this, so my reasoning was to always get the biggest width of the faces detected and send the x and y coordinates to the arduino. I found similar questions on the forum to 'Get the largest element from an array' but although i understand the logic my sketch keeps on outputting all sets of x and y coordinates detected. A supplementary note is in place that i work heuristically with code and have very basic knowledge of programming languages. Any push in the right direction is highly appreciated. Below the processing code:
import gab.opencv.*;
import processing.video.*;
import java.awt.*;
import processing.serial.*;
Capture video;
OpenCV opencv;
Serial myPort; // Create object from Serial class
int newXpos, newYpos;
//These variables hold the x and y location for the middle of the detected face
int midFaceX = 0;
int midFaceY = 0;
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);
//println(Serial.list()); // List COM-ports (Use this to figure out which port the Arduino is connected to)
String portName = Serial.list()[1];
//select first com-port from the list (change the number in the [] if your sketch fails to connect to the Arduino)
myPort = new Serial(this, portName, 19200); //Baud rate is set to 19200 to match the Arduino baud rate.
video.start();
}
void draw() {
scale(2);
opencv.loadImage(video);
image(video, 0, 0 );
noFill();
stroke(0, 255, 0, 40);
strokeWeight(3);
Rectangle[] faces = opencv.detect();
int maxValueFace = 0;
int maxIndex = -1;
for (int i = 0; i < faces.length; i++ ) {
if (faces[i].width > maxValueFace) {
maxIndex = i;
maxValueFace = faces[i].width;
//println(maxValueFace);
rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height); //
midFaceX = faces[i].x + (faces[i].width/2); // middle of the face
midFaceY = faces[i].y + (faces[i].height/2); // middle of the face
float xpos = map(midFaceX, 0, width, 90, 120); //maps range of servos L->R
float ypos = map(midFaceY, 0, height, 90, 120); //maps range of servos U->D
int newXpos = (int)xpos; //converts position X float into integer
int newYpos = (int)ypos; //converts position Y float into integer
myPort.write(newXpos+"x"); // send X coordinate to Arduino
myPort.write(newYpos+"y"); // send Y coordinate to Arduino
println(midFaceX + "," + midFaceY);
}
}
}
void captureEvent(Capture c) {
c.read();
}
Answers
Use a separate loop for finding the max, remember the index.
The block starting at line 51 then needs moving outside the loop and should just use the remembered index.
Thank you for your response, i'm struggling my way through it bit by bit. I've placed from 51 line onward in a separate loop like this:
Still no success. If I comment out from line 51 onward and print the 'maxIndex' it still prints multiple numbers when multiple faces are detected. Is there something incorrect in the way i've set up the max declaration?
lines 8 to 20 are STILL within the loop (which runs from line 1 to the end)