如何在android中提高OpenCV人脸检测性能?

时间:2015-02-20 06:20:56

标签: android c++ c opencv

我正在研究android中的一个项目,我正在使用OpenCV来检测图库中所有图像的面部。从图像中获取面部的过程在服务中执行。服务持续工作,直到处理完所有图像。它将检测到的面部存储在内部存储器中,并在网格视图中显示活动是否已打开。

我的代码是:

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)
        {


        }


    }
}   

一切都很好,但检测面很慢。表现非常缓慢。当我调试代码然后我发现需要时间的行是:

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

我已经检查过多个帖子,但是我没有得到任何解决方案。 请告诉我该怎么做才能解决这个问题。

非常感谢任何帮助。谢谢。

2 个答案:

答案 0 :(得分:9)

您应该注意detectMultiScale()

的参数
  • scaleFactor - 参数指定每个图像比例下图像尺寸减少的程度。此参数用于创建比例金字塔。这是必要的,因为模型在训练期间具有固定的大小。没有金字塔,唯一要检测的大小就是这个修复(也可以从XML中读取)。然而,通过使用多尺度表示,即使用相同的检测窗口检测大面和小面,面部检测可以是尺度不变的。

    scaleFactor取决于训练有素的探测器的大小,但实际上,您需要将其设置得尽可能高,同时仍然能够获得良好的探测器。结果,所以这应该凭经验确定。

    您的1.1值对于此目的而言可能是一个很好的价值。这意味着,使用相对较小的步长进行大小调整(将大小减小10%),可以增加与检测模型匹配大小的机会。如果训练有素的探测器尺寸为10x10,则可以检测尺寸为11x11,12x12的面部,依此类推。但实际上1.1因子要求金字塔中的层数(和2倍的计算时间)大约是1.2倍。

  • minNeighbors - 参数指定每个候选矩形应保留多少个邻居。 级联分类器使用滑动窗口方法。通过应用此方法,您可以在窗口上滑动窗口,而不是调整窗口大小并再次搜索,直到无法进一步调整窗口大小。在每次迭代中,存储了(级联分类器的)真实输出,但不幸的是它实际上检测到许多误报。并且为了消除误报并从检测中获得正确的面部矩形,应用邻域方法。 3-6对它来说是一个很好的价值。如果该值太高,那么您也可能失去真正的积极因素。

  • minSize - 关于minNeighbors的滑动窗口方法,这是级联可以检测到的最小窗口。小于该值的对象将被忽略。通常cv::Size(20, 20)足以进行面部检测。

  • maxSize - 最大可能的对象大小。大于此的对象将被忽略。

最后,您可以尝试基于不同功能的不同分类器(例如Haar,LBP,HoG)。通常,LBP分类器比Haar快几倍,但也不太准确。

强烈建议您查看以下问题:

答案 1 :(得分:1)

相反,将图片作为Bitmap进行阅读,然后使用Mat将其转换为Utils.bitmapToMat(defaultBitmap,image),您可以直接使用Mat image = Highgui.imread(imagepath);您可以here查看imread()功能。

此外,由于探测器正在寻找至少具有相当小的尺寸(20,20)的面,因此下面的线花费太多时间。检查this视频,了解使用OpenCV进行人脸检测的可视化。

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