【问题标题】:Recommended values for OpenCV detectMultiScale() parametersOpenCV detectMultiScale() 参数的推荐值
【发布时间】:2014-01-15 01:33:04
【问题描述】:

CascadeClassifier::detectMultiScale() 的推荐参数是什么?我应该根据哪些因素更改默认参数?

void CascadeClassifier::detectMultiScale(
    const Mat& image, 
    vector<Rect>& objects, 
    double scaleFactor=1.1,
    int minNeighbors=3, 
    int flags=0, 
    Size minSize=Size(),
    Size maxSize=Size() )

【问题讨论】:

    标签: c++ opencv cascade-classifier


    【解决方案1】:

    在这些参数中,需要多注意其中的四个:

    • scaleFactor – 指定在每个图像比例下图像尺寸缩小多少的参数。

      基本上,比例因子用于创建比例金字塔。更多解释可以找到here。简而言之,如here 所述,您的模型在训练期间定义了固定大小,在xml 中可见。这意味着在图像中检测到这种大小的人脸(如果存在)。但是,通过重新缩放输入图像,您可以将较大的人脸调整为较小的人脸,使其可以被算法检测到。

      1.05 是一个很好的可能值,这意味着您使用一小步来调整大小,即将大小减小 5%,您增加了与模型匹配大小的机会发现检测。这也意味着该算法工作得更慢,因为它更彻底。您可以将其提高到 1.4 以加快检测速度,但可能会完全丢失一些人脸。

    • minNeighbors – 指定每个候选矩形应保留多少个邻居的参数。

      此参数会影响检测到的人脸质量。更高的值导致更少的检测,但质量更高。 3~6 物有所值。

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

      这个参数决定了你想要检测的小尺寸。你来决定!通常,[30, 30] 是人脸检测的良好开端。

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

      此参数确定您要检测的大小。再一次,你决定! 通常不需要手动设置,默认值假设你要检测的人脸大小没有上限。

    【讨论】:

    • 图像金字塔是否与滑动窗口技术结合使用?如果我们使用滑动窗口以不同的比例和不同的大小扫描图像,那我们不就不需要使用图像金字塔了吗?
    • “minNeighbors”指的是什么?是关于修剪同一张脸周围的过多检测吗?
    • @user961627 是的,图像金字塔和滑动窗口技术正在结合使用。如果您使用滑动窗口以不同比例和不同尺寸扫描图像,则不再需要使用图像金字塔,因为图像金字塔只是在处理时对图像进行上/下采样。对于minNeighbors,是的,它是关于修剪同一张脸周围的过多检测。说明请参考答案。
    • @Micka 不要 100% 同意 scaleFactor。事实上,您希望它尽可能高,同时仍然获得“好”的结果,这必须根据经验确定。它在很大程度上取决于要检测的目标、级联的类型和训练;过去,24x24 FD 级联的价值甚至高达1.1scaleFactorminSize 的值太低将导致巨大的计算成本,因为需要生成更多的金字塔层。 1.05 的一个因素需要的层数大约是 1.1 的两倍(以及 > 2 倍的时间)。
    • @IwillnotexistIdonotexist 这显然是真的,抱歉我没有提到它。我只是想说,可以让检测器根据某人的确切需求选择窗口大小,并且可以计算 scaleFactor 来满足这些需求。但是如果不知道训练窗口的大小和最小/最大大小以及对计算时间和检测灵敏度/特异性的限制,很难推荐一个值:)
    【解决方案2】:

    如果您有良好的 CPU 和 RAM 性能或更多,您可以设置 比例因子=1 minNeighbors=3

    如果您在 raspberry 之类的嵌入式系统中工作,我建议您选择 smth like scaleFactor= 2, (数值越高,精度越低) minNeighbors = 1,(值越高,精度越低,但可靠性越高) 该算法将运行得更快,否则如果 CPU 性能和 RAM 不够,它将冻结。

    希望对你有帮助

    【讨论】:

    • ScaleFactor 应始终大于 1,对于良好的 CPU 和 RAM,应始终大于 1.05。
    【解决方案3】:
    cl_int err;
        cl_uint numPlatforms;
    
        err = clGetPlatformIDs(0, NULL, &numPlatforms);
        if (CL_SUCCESS == err)
        printf("\nDetected OpenCL platforms: %d", numPlatforms);
        else
        printf("\nError calling clGetPlatformIDs. Error code: %d", err);
    
        string str ="haarcascade_frontalface_alt2.xml";
        ocl::OclCascadeClassifier fd;
        fd.load(str);
        ocl::oclMat frame, frameGray;
        Mat frameCpu;
    
    
        CvVideoCapture vcap = openVideo("0");
        vcap.set(CV_CAP_PROP_FRAME_WIDTH,320);
        vcap.set(CV_CAP_PROP_FRAME_HEIGHT,240);
    
        static const cv::Size maxSize;
    
        for(;;){
        //  // processing loop
            vector<Rect> faces;
        vcap >> frameCpu;
        frame = frameCpu;
        ocl::cvtColor(frame, frameGray, CV_BGR2GRAY);
        //ocl::equalizeHist(frameGray, frameGray);
        //Mat mm(frameGray);
        //cvWaitKey(100);
    
        fd.detectMultiScale(frameGray,faces,1.05,3,0|CV_HAAR_FIND_BIGGEST_OBJECT ,minSize,maxSize);
    
    
          for(int   i=0; i<  faces.size() ; i++)
           {
             if(faces.size())
             //circle(img, Point(palm[i].x+ palm[i].width/2,palm[i].y+palm[i].height/2),palm[i].width,Scalar(255,0,0), 2,8 );       
                 cv::rectangle(frameCpu, faces[i],Scalar(255,0,0), 2,8 );       
           }
    
          imshow("fsfs",frameCpu);
    
        cvWaitKey(1);
    

    【讨论】:

      猜你喜欢
      • 2015-09-19
      • 1970-01-01
      • 2012-07-26
      • 2016-07-13
      • 1970-01-01
      • 2018-10-07
      • 1970-01-01
      • 1970-01-01
      • 2016-02-23
      相关资源
      最近更新 更多