[英]How to improve OpenCV face detection performance in android?
我正在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()));
我已经检查了多个帖子以解决此问题,但没有得到任何解决方案。 请告诉我该怎么做才能解决这个问题。
任何帮助将不胜感激。 谢谢。
您应该注意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的分类器快几倍,但准确性也较低。
强烈建议您仔细检查以下问题:
代替将图像读取为Bitmap
,然后通过使用Utils.bitmapToMat(defaultBitmap,image)
将其转换为Mat
Utils.bitmapToMat(defaultBitmap,image)
可以直接使用Mat image = Highgui.imread(imagepath);
您可以在此处检查imread()
函数。
此外,由于检测器正在寻找至少具有很小的Size(20,20)的面部,因此线下花费了太多时间。 观看此视频,以查看使用OpenCV进行面部检测的可视化。
mJavaDetector.detectMultiScale(image,faceDetections,1.1, 10, 0, new Size(20,20), new Size(image.width(), image.height()));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.