Poor Performance with OpenCV 2.4.8 face detection - java

I installed the OpenCV 2.4.8 Java API to play with the face detection example that is given in the tutorial.
In the example, lbpcascade_frontalface.xml -which is a CascadeClassifier- works OK in detecting the female face image (lena.png) that they provide. However, when I tried it on this random image from the web, the classifier produced the following image, missing 4 obvious(!) faces:
I am quite disappointed because I expected this (with the clear contrasts) to be a very easy image for detecting faces.
1) Coding in Java, is it possible to improve this classifier to detect all faces in this picture? Or do I need C++ for this?
2) I looked at OpenCV's CascadeClassification web page and saw taht it is possible to train your own classifier. But the instructions are in C++. Has anyone done this using Java or is it only doable in C++?

The training is not related to any programming language.
http://docs.opencv.org/doc/user_guide/ug_traincascade.html
You need only to use two already written programs included in the opencv library: createsamples and traincascade. You can use Haar and LBP features too, but the Haar features are slightly better for face detection. (And by the way: don't use haartraining).

I have saved your image and this c++ code finds the missing 4 faces as well as all the others (note the different Haar cascade and the minimum size):
Mat im1 = imread("JuVIA.png", CV_LOAD_IMAGE_COLOR);
vector<Rect> faces;
CascadeClassifier cascade( "C:/local/opencv249/sources/data/haarcascades/haarcascade_frontalface_alt2.xml" );
cascade.detectMultiScale( im1, faces, 1.1, 2, 0| CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++ )
cv::rectangle( im1, *r, CV_RGB(255,0,0) );
imshow("in", im1);
imwrite( "miss4.png", im1);
waitKey();

It is because the faceDetector the tutorial chose to use is lbpcascade_frontalface.xml which is not good enough, at least couldn't detect all the faces in the picture you used.
You may change to use haarcascade_frontalface_alt.xml under opencv-2.4.8\sources\data\haarcascades folder. Then all faces would be detected.
Here following is the result:, more details please refer to:http://www.pkuaas.org/?uid-1140-action-viewspace-itemid-3224

Related

OpenCV applying filters to specific place in image

Hello I am using OpenCV for Java and want to blur faces from image, but I keep failing to apply it only for face. How can I do it?
Your question is too general. What basically needs to be done is to run a face detection algorithm (google for face detection opencv), extract the rectangle of pixels depicting the face using cv::rect, blur them and replace the original pixels. I suggest you read about face detection (try to understand the main ideas regardless of openCV), read some tutorials on implementation and then, if you need assistance, write a more specific question here and people are sure to answer you.

Detecting faces that are looking into the webcam

I'm currently doing a face detection in Java/JavaCV.
So far I've been experimenting with the code.
I'm using this face cascade = haarcascade_frontalface_alt_tree.xml
I've got this code below for Detecting largest face found in the webcam
CvSeq faces = cvHaarDetectObjects(img, classifier, storage, 1.1, 1,
CV_HAAR_DO_ROUGH_SEARCH|CV_HAAR_FIND_BIGGEST_OBJECT);
My first question is:
Since this is only detecting one face - the largest face found in the webcam
is this the correct way to do it to detect multiple faces?
CvSeq faces = cvHaarDetectObjects(img, classifier, storage, 1.1, 1, CV_HAAR_DO_CANNY_PRUNING);
My second question is:
Is it possible to detect faces that are only looking into the webcam? and those that are not looking into the wbecam?
So the it will detect faces but I want to set some sort of scores - so let's say 1 is for faces that are looking into the webcam and 2 - for faces that are looking away from the webcam? How do I proceed to do this?
Thank you.
If a person looks directly, his/her eye should be perpendicular(if he/she doesn't have an eye problem :P).
This theory suggests, pupil and iris should be circular and not elliptical if a person looks directly.
Please note that I meant by the visible part of pupil and iris only.
Most face detection lib are trained toward people facing the camera since this isa major constraint for face recognition. This being said, Haar cascade can be trained also to detect profile or even focusing on eyes and nose (ie part of face).
I didn't use javaCV myself but tested openIMAJ (which rocks for me!) which can reuse openCV configuration file (as far as I understood). In the source of their face detection library, you will find models for profile and eye detection.

How to detect faces with jviolajones library?

I'm trying count faces in the picture with jviolajones library. I want to do this in pure Java with no extra dependencies so OpenCV is not an option. My code is like:
detector.getFaces("filePath", 1.2f,1.1f,.05f, 2,true);
I've tried haarcascade_frontalface_alt and haarcascade_frontalface_default from OpenCV. But results are bad about 5 pictures recognized good for 30 tested.
I've tried adjust parameters but it didn't help. Any suggestion for better results, or maybe another library. I was wondering, maybe I have to prepare pictures before detecting faces?
This works:
detector.getFaces("filePath", 1.2f,1.1f,.05f, 2,true);
But I had to scaled my photos to 640x480 and transform them to gray, this works with haarcascade_frontalface_default.xml classifier from OpenCV.

Loading an image using OpenCV in Android

I apologize if this question has already been covered on this site, but I can't seem to find a straight forward answer. I'm making an android app that uses OpenCV to take a picture, process it to detect objects, and figure out the coordinates of those objects in the scene.
All the tutorials I find for android seem to be real time processing of the camera preview or using c++, which I would strongly prefer to not have to go down the c++ road. I'm sure I'm missing something simple but I don't know what it is.
On another note, the objects I'm trying to detect are billiards balls on a table. What would be the best pre-processing technique to better detect the balls? I did a quick test using the canny method, and it seems that the light reflecting off the balls breaks up the circle shape.
To load images in Android, you can use
Bitmap bMap=BitmapFactory.decodeResource(getResources(),R.drawable.image1)
where image1 is a image under Resources folder of your Android project.
Then convert Bitmap to bytes or Mat and process in C++ (OpenCV) or Java with matToBitmap or MatToBitmap methods in android-opencv.
If you are comfortable in processing using Mat data type, you can use (you need android-opencv project to use this)
Mat m = Highgui.imread("/media/path_to_image");
You can use blobs, hough circles to detect billiard balls. There is no certain way to answer this. You can try using normalized RGB or Lab colorspaces to play around (to remove reflection of the billiard balls) to see if you detect billiard balls (by running hough circles, blob detectors).
The real-time scenario will require you to use machine-learning techniques to detect billiard balls by using certain feature vectors, then do training and testing.
This works for me (got the answer from here: How to get Mat with a drawable input in Android using OpenCV)
Mat img = null;
try {
img = Utils.loadResource(this, R.drawable.image_id, CvType.CV_8UC4);
} catch (IOException e) {
e.printStackTrace();
}
I know it's too late, but someone may use this.
Highgui has been removed from opencv for android.
You can use Imgcodes instead.
Mat BGRMat = Imgcodecs.imread(getResources().getDrawable(R.drawable.img).toString());

How should I do image processing in Java?

I'm making an applet that lets users crop out a piece of an image and save it. For cropping, I'm going to implement a "magic wand"-esque tool. I can do all this in Matlab but i'm having some trouble figuring out the Java libraries. Here are a few tasks I need to perform:
Randomly access pixels in an image by (x,y) and return a single object (java.awt.Color, ARGB int, short[], whatever -- as long as I'm not dealing with channels individually)
Create an alpha channel from a boolean[ ][ ]
Create a N by M image that's initialized to green
Any pros out there who can help me? Just some code snippets off the top of your head would be fine.
Many thanks,
Neal
You want to use the Java2D libraries. Specifically, you want to use the BufferedImage class from the library to deal with your images. You can access individual pixels and do all of the things you have specified above. Sun/Oracle has a good tutorial to get you started in the right direction. The second part in that tutorial goes over creating an alpha channel. Oh, and to access individual pixels, you want to use the WritableRaster class. So you can do something like this. Hope this gets you started.
WritableRaster imageRaster = Bufferedimg.getRaster();
//use java random generation to get a random x and y coordinate, then call this to access the pixel
imageRaster.getPixel(x, y,(int[])null);
ImageJ is a mature, open-source image processing framework that supports macros, plugins and a host of other features.
Marvin is a Java image processing framework that can help you. It provides algorithms for filtering, feature extraction, morphological analysis, tranformations, segmentation and so forth. Moreover, its architecture supports real-time video processing with the same algorithms.

Categories