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

标签 android c++ c opencv

我正在使用 Android 开发一个项目,在该项目中,我使用 OpenCV 从图库中的所有图像中检测人脸。从图像中获取人脸的过程在服务中执行。服务持续工作,直到处理完所有图像。它将检测到的人脸存储在内部存储中,如果 Activity 打开,也会显示在 GridView 中。

我的代码是:

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()));

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

如有任何帮助,我们将不胜感激。谢谢。

最佳答案

注意detectMultiScale()的参数:

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

    scaleFactor 取决于您训练的检测器的大小,但实际上,您需要将其设置得尽可能高,同时仍能获得“好”结果,因此这应该根据经验确定。
    < br/> 您的 1.1 值对于此目的可能是一个很好的值。这意味着,使用相对较小的步长来调整大小(将大小减小 10%),您会增加找到与检测模型匹配的大小的机会。如果您训练的检测器大小为 10x10,那么您可以检测大小为 11x11、12x12 等的人脸。但事实上,1.1 的系数大约需要金字塔中层数的两倍(以及 2 倍的计算时间),比 1.2 的系数大。

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

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

  • maxSize – 最大可能的对象大小。大于该值的对象将被忽略。

最后可以根据不同的特征(比如Haar、LBP、HoG)尝试不同的分类器。通常,LBP 分类器比 Haar 的分类器快几倍,但也不太准确。

同时强烈建议查看以下问题:

关于android - 如何提高android中的OpenCV人脸检测性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28622792/

相关文章:

java - 锁屏而不关闭

C++11/14 调用解决方法

c++ - 代码执行无法继续,因为找不到 cpprest_2_10.dll

c++ - 如何在 Doxygen 内联代码中转义特殊命令

android - 升级到新的 Admob 问题

java - 多个 OnClick 事件不适用于所有对象

android - 自动更新/在应用程序中添加一些文件

c++ - 如何让 boost json 使用正确的数据类型

如果我尝试打印值,则 C strtok 工作,但如果我尝试传递值,则出现段错误和 null

c - 编写 ARM 机器指令并从 C 执行它们(在 Raspberry pi 上)