1

I am working on a project in android in which i am using OpenCV to detect faces from all the images which are in the gallery. The process of getting faces from the images is performing in the service. Service continuously working till all the images are processed. It is storing the detected faces in the internal storage and also showing in the grid view if activity is opened.

My code is:

CascadeClassifier mJavaDetector=null;

public void getFaces()
{

    for (int i=0 ; i<size ; i++)        
    {

        File file=new File(urls.get(i));
        imagepath=urls.get(i);

        defaultBitmap=BitmapFactory.decodeFile(file, bitmapFatoryOptions);

        mJavaDetector = new CascadeClassifier(FaceDetector.class.getResource("lbpcascade_frontalface").getPath());

        Mat image = new Mat (defaultBitmap.getWidth(), defaultBitmap.getHeight(), CvType.CV_8UC1);
        Utils.bitmapToMat(defaultBitmap,image);

         MatOfRect faceDetections = new MatOfRect();
            try
            {
                mJavaDetector.detectMultiScale(image,faceDetections,1.1, 10, 0, new Size(20,20), new Size(image.width(), image.height()));
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }


        if(faceDetections.toArray().length>0)
        {


        }


    }
}   

Everything is fine but it is detection faces very slow. The performance is very slow. When i debug the code then i found the line which is taking time is:

mJavaDetector.detectMultiScale(image,faceDetections,1.1, 10, 0, new Size(20,20), new Size(image.width(), image.height()));

I have checked multiple post for this problem but i didn't get any solution. Please tell me what should i do to solve this problem.

Any help would be greatly appreciated. Thank you.

Anil Sharma
  • 11
  • 1
  • 4

2 Answers2

10

You should pay attention to the parameters of detectMultiScale():

  • scaleFactor – Parameter specifying how much the image size is reduced at each image scale. This parameter is used to create a scale pyramid. It is necessary because the model has a fixed size during training. Without pyramid the only size to detect would be this fix one (which can be read from the XML also). However the face detection can be scale-invariant by using multi-scale representation i.e., detecting large and small faces using the same detection window.

    scaleFactor depends on the size of your trained detector, but in fact, you need to set it as high as possible while still getting "good" results, so this should be determined empirically.

    Your 1.1 value can be a good value for this purpose. It means, a relative small step is used for resizing (reduce size by 10%), you increase the chance of a matching size with the model for detection is found. If your trained detector has the size 10x10 then you can detect faces with size 11x11, 12x12 and so on. But in fact a factor of 1.1 requires roughly double the # of layers in the pyramid (and 2x computation time) than 1.2 does.

  • minNeighbors – Parameter specifying how many neighbours each candidate rectangle should have to retain it. Cascade classifier works with a sliding window approach. By applying this approach, you slide a window through over the image than you resize it and search again until you can not resize it further. In every iteration the true outputs (of cascade classifier) are stored but unfortunately it actually detects many false positives. And to eliminate false positives and get the proper face rectangle out of detections, neighbourhood approach is applied. 3-6 is a good value for it. If the value is too high then you can lose true positives too.

  • minSize – Regarding to the sliding window approach of minNeighbors, this is the smallest window that cascade can detect. Objects smaller than that are ignored. Usually cv::Size(20, 20) are enough for face detections.

  • maxSize – Maximum possible object size. Objects bigger than that are ignored.

Finally you can try different classifiers based on different features (such as Haar, LBP, HoG). Usually, LBP classifiers are a few times faster than Haar's, but also less accurate.

And it is also strongly recommended to look over these questions:

Community
  • 1
  • 1
Kornel
  • 5,264
  • 2
  • 21
  • 28
  • i have checked these all parameters already. so i found that LBP classifiers are faster and accurate than Haar and Hog. – Anil Sharma Feb 20 '15 at 12:09
  • then optionally you can scale down your images if their resolution is larger than 0.9-1.0 MP and then scale back the face rectangles to the original size. – Kornel Feb 20 '15 at 15:19
1

Instead reading images as Bitmap and then converting them to Mat via using Utils.bitmapToMat(defaultBitmap,image) you can directly use Mat image = Highgui.imread(imagepath); You can check here for imread() function.

Also, below line takes too much time because the detector is looking for faces with at least having Size(20, 20) which is pretty small. Check this video for visualization of face detection using OpenCV.

mJavaDetector.detectMultiScale(image,faceDetections,1.1, 10, 0, new Size(20,20), new Size(image.width(), image.height()));
Melike
  • 468
  • 1
  • 7
  • 15
  • hello melike initially i use Mat image = Highgui.imread(imagepath); but performace was same. It was giving me gray faces. so how can i get color faces as images have from Highgui.imread(imagepath); – Anil Sharma Feb 23 '15 at 09:37
  • `Highgui.imread(imagepath, CV_LOAD_IMAGE_COLOR);` From the [link](http://docs.opencv.org/java/2.4.9/org/opencv/highgui/Highgui.html#imread%28java.lang.String,%20int%29), CV_LOAD_IMAGE_COLOR - If set, always convert image to the color one – Melike Feb 24 '15 at 11:04
  • thanx melike for sharing useful information. i couldn't understand how to set CV_LOAD_IMAGE_COLOR value and use it plz explain it. – Anil Sharma Feb 26 '15 at 07:42
  • You don't need to set it, it's an OpenCV flag defined in Highgui module. Use it like below, `Highgui.imread(imagepath, org.opencv.highgui.Highgui.CV_LOAD_IMAGE_COLOR);` – Melike Feb 26 '15 at 10:38