Development Step #2 / Tracking a face with Open CV and using USB Camera.
o Approach.
- Face Detection
For this development step I will be using the examples provided in the OpenCV library in Processing and test out the different tracking accuracy of facial features.
- USB Camera
I am looking for a way to capture video, which is streamed through an USB port. I am going to look for help through different forums.
The camera that I plan on using is Logitech c310.
o Learning Experience.
- Face Detection
First I started with face detection out of a static image.
Input:
Code: https://gist.github.com/TheVisualG/ada0a95f989c5c333a197a2d1a2bf75f
Output:
I Learned:
in order to activate the face detection in Processing we need to use:
Rectangle[] faces;
opencv.loadCascade(OpenCV.CASCADE _FRONTALFACE); // I can select different parts of the body as a detection target.
faces = opencv.detect();
- Live Video
Input:
Live video streamed from my laptop camera.
Code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import gab.opencv.*; | |
import processing.video.*; | |
import java.awt.*; | |
Capture video; | |
OpenCV opencv; | |
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(); | |
} | |
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); | |
for (int i = 0; i < faces.length; i++) { | |
println(faces[i].x + "," + faces[i].y); | |
rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height); | |
} | |
} | |
void captureEvent(Capture c) { | |
c.read(); | |
} |
Output:
I learned:
Streaming live video in Processing using following commands:
import processing.video.*;
Capture video;
video = new Capture(this, 640/2, 480/2);
video.start(); image(video, 0, 0 );
void captureEvent(Capture c)
{ c.read();
}
- USB Camera
I googled around and bumped into this post from the Processing forums:
https://forum.processing.org/two/discussion/7736/using-usb-camera-instead-of- isight
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import processing.video.*; | |
Capture cam; | |
void setup() { | |
size(1280, 960); | |
String[] cameras = Capture.list(); | |
if (cameras == null) { | |
println("Failed to retrieve the list of available cameras, will try the default…"); | |
cam = new Capture(this, 640, 480); | |
} if (cameras.length == 0) { | |
println("There are no cameras available for capture."); | |
exit(); | |
} else { | |
println("Available cameras:"); | |
printArray(cameras); | |
// The camera can be initialized directly using an element | |
// from the array returned by list(): | |
cam = new Capture(this, cameras[80]); | |
// Or, the settings can be defined based on the text in the list | |
//cam = new Capture(this, 640, 480, "Built-in iSight", 30); | |
// Start capturing the images from the camera | |
cam.start(); | |
} | |
} | |
void draw() { | |
if (cam.available() == true) { | |
cam.read(); | |
} | |
image(cam, 0, 0, width, height); | |
// The following does the same as the above image() line, but | |
// is faster when just drawing the image without any additional | |
// resizing, transformations, or tint. | |
//set(0, 0, cam); | |
} |
o Result.
- Face Detection
Input:
Code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import gab.opencv.*; | |
import java.awt.Rectangle; | |
OpenCV opencv; | |
Rectangle[] faces; | |
void setup() { | |
opencv = new OpenCV(this, "profile_test.jpg"); | |
size(960, 960); | |
opencv.loadCascade(OpenCV.CASCADE_FRONTALFACE); | |
faces = opencv.detect(); | |
} | |
void draw() { | |
image(opencv.getInput(), 0, 0); | |
noFill(); | |
stroke(0, 255, 0); | |
strokeWeight(3); | |
for (int i = 0; i < faces.length; i++) { | |
rect(faces[i].x, faces[i].y, faces[i].width, faces[i].height); | |
} | |
} |
Output:
When it comes to tracking nose, eye, mouth there are many false-positives. That is why I believe frontal face and profile are more optimal options, or more detailed tracking can be used with pain background, without any texture that might bring an error.
opencv.loadCascade(OpenCV.CASCADE _FRONTALFACE);
opencv.loadCascade(OpenCV.CASCADE _PROFILE);
opencv.loadCascade(OpenCV.CASCADE _EYE);
opencv.loadCascade(OpenCV.CASCADE _MOUTH);
- Live Video
Output:
- USB Camera.
I plugged the USB camera and ran the code, but unfortunately the only thing that was detected was my laptop camera.
I tried different USB ports, checked if the camera runs on other computers and it did. Aer long struggles I ended
up manually reinstalling the UBS driver from the official website:
http://support.logitech.com/en_us/product/hdwebcam-c310/downloads
Finally I succeeded and I had the full list of camera optioons (resolution and fps) :
Now in order to switch between camera I need to change the number in this line of code:
cam = new Capture(this, cameras[80]);
Code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import processing.video.*; | |
Capture cam; | |
void setup() { | |
size(1280, 960); | |
String[] cameras = Capture.list(); | |
if (cameras == null) { | |
println("Failed to retrieve the list of available cameras, will try the default…"); | |
cam = new Capture(this, 640, 480); | |
} if (cameras.length == 0) { | |
println("There are no cameras available for capture."); | |
exit(); | |
} else { | |
println("Available cameras:"); | |
printArray(cameras); | |
cam = new Capture(this, cameras[80]); | |
cam.start(); | |
} | |
} | |
void draw() { | |
if (cam.available() == true) { | |
cam.read(); | |
} | |
image(cam, 0, 0, width, height); | |
} |
o Sources.
My sources are from the Processing examples included in the OpenCV library.
https://forum.processing.org/two/discussion/7736/using-usb-camera-instead-of- isight
http://support.logitech.com/en_us/product/hdwebcam-c310/downloads