【问题标题】:Opencv - Haar cascade - Face tracking is very slowOpencv - Haar 级联 - 人脸跟踪非常慢
【发布时间】:2015-01-08 07:01:30
【问题描述】:

我开发了一个使用 OpenCV 库通过摄像头跟踪面部的项目。 我使用带有haarcascade_frontalface_alt.xml 的haar 级联来检测人脸。

我的问题是,如果从网络摄像头捕获的图像不包含任何人脸,则检测人脸的过程非常缓慢,因此来自摄像头的图像(连续向用户显示)会延迟。

我的源代码:

void camera() 
{
    String face_cascade_name = "haarcascade_frontalface_alt.xml";
    String eye_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
    CascadeClassifier face_cascade;
    CascadeClassifier eyes_cascade;
    String window_name = "Capture - Face detection";
    VideoCapture cap(0);

    if (!face_cascade.load(face_cascade_name))
        printf("--(!)Error loading\n");

    if (!eyes_cascade.load(eye_cascade_name))
        printf("--(!)Error loading\n");

    if (!cap.isOpened()) 
    {
        cerr << "Capture Device ID " << 0 << "cannot be opened." << endl;
    } 
    else 
    {
        Mat frame;
        vector<Rect> faces;
        vector<Rect> eyes;
        Mat original;
        Mat frame_gray;
        Mat face;
        Mat processedFace;

        for (;;) 
        {
            cap.read(frame);
            original = frame.clone();    
            cvtColor(original, frame_gray, CV_BGR2GRAY);
            equalizeHist(frame_gray, frame_gray);
            face_cascade.detectMultiScale(frame_gray, faces, 2, 0,
                    0 | CASCADE_SCALE_IMAGE, Size(200, 200));

            if (faces.size() > 0)
                rectangle(original, faces[0], Scalar(0, 0, 255), 2, 8, 0);

            namedWindow(window_name, CV_WINDOW_AUTOSIZE);
            imshow(window_name, original);
        }

        if (waitKey(30) == 27)
            break;
    }
}

【问题讨论】:

  • “非常慢”是什么意思?你的图像解决方案是什么? face_cascade.detectMultiScale 需要一些时间。如果你已经使用了发布模式的 opencv 库,那么可能还有一次机会:也许 openCV 也有一个 gpu haarcascade 检测器,但我不知道。
  • 我的图像解决方案是 640 x 480。如果图像不包含人脸,我的意思是函数 detectMultiscale 处理后检测人脸的速度非常慢:(
  • 所以只有没有检测到人脸才慢,有人脸就快?!?
  • 这不可能吧??

标签: c++ opencv face-detection face-recognition


【解决方案1】:

Haar 分类器本质上相对较慢。此外,由于detectMultiScale 在 OpenCV 中是并行化的,因此您无法对算法本身进行太多优化。

关于你的代码的唯一说明:你真的得到了一些用minSize 检测到的脸,等于Size(200, 200)?当然,minSize 越大,性能就越好。

在检测到任何东西之前尝试缩放图像:

const int scale = 3;
cv::Mat resized_frame_gray( cvRound( frame_gray.rows / scale ), cvRound( frame_gray.cols / scale ), CV_8UC1 );
cv::resize( frame_gray, resized_frame_gray, resized_frame_gray.size() );
face_cascade.detectMultiScale(resized_frame_gray, faces, 1.1, 3, 0 | CASCADE_SCALE_IMAGE, Size(20, 20));

(不要忘记将minSize更改为更合理的值并将检测到的人脸位置转换为真实比例)

将图像尺寸缩小 2、3、5 倍对于任何图像处理算法来说都是极大的性能提升,尤其是在涉及检测等成本高昂的事情时。

如前所述,如果调整大小不起作用,请尝试使用探查器获取其他一些瓶颈。

您还可以切换到 LBP 分类器,该分类器速度相对较快,但准确度较低。

希望它会有所帮助。

【讨论】:

  • 感谢您的帮助,但是当图像中没有人脸时,检测MultiScale 的过程非常缓慢。
  • 我将尝试将其付诸实践。在看到此之前,我想知道这种方法是否可行。我想知道这会在多大程度上降低检测性能。例如,与树莓派相比,我很困惑 iPhone 怎么能如此轻松地做到这一点。
  • 增加 minSize 确实将延迟从秒变为毫秒。谢谢楼主!
【解决方案2】:

可能对你有用:

有一个Simd Library,它有一个HAAR 和LBP 级联分类器的implementation。它可以使用来自 OpenCV 的标准 HAAR 和 LBP 级联。此实现使用 SSE4.1、AVX2 和 NEON(ARM) 进行了 SIMD 优化,因此它的工作速度比原始 OpenCV 实现快 2-3 倍。

【讨论】:

  • 你的图书馆看起来很酷。它与 Agner Fog 的 Vector Class Library 或 Yeppp! 相比如何?
  • @Zboson 据我所知,Agner Fog 的矢量类库和 Yeppp 是通用的矢量库。 Simd 库更多地涉及图像处理。
【解决方案3】:

我经常使用 Haar 级联分类器,在配备 4GB Ram 和 2GHz CPU 的 Intel PC/Mac (Windows/Ubuntu/OS X) 上,可以轻松地在 640x480 图像上以 15 帧/秒的速度进行人脸检测。你的配置是什么?

您可以尝试以下几种方法。

  1. 您不必在每个框架内创建窗口 (namedWindow(window_name, CV_WINDOW_AUTOSIZE);)。只需先创建它并更新图像。

  2. 您可以试试在没有直方图均衡的情况下它的运行速度。网络摄像头并不总是需要。

  3. 按照上面 Micka 的建议,您应该检查您的程序是在调试模式还是发布模式下运行。

  4. 使用分析器查看是否存在瓶颈。

  5. 如果您还没有这样做,您是否测量了注释掉人脸检测和绘制矩形时获得的帧速率?

【讨论】:

  • 我检查并看到如果图像中没有人脸,detectMultislace 进程非常慢:(
  • waitkey(30) 语句可以使事情变慢很多。有关这方面的讨论,请参阅 stackoverflow.com/questions/18701236/…
  • 你是说没有人脸的时候函数运行的比较慢?!这肯定不是真的!
  • 我在 900MHZ RPI 上获得 2 FPS
  • 当没有检测功能时我得到 12FPS,这看起来很糟糕
【解决方案4】:

您可以使用 LBP Cascade 来检测人脸。它要轻得多。您可以在 OpenCV 源目录中找到 lbpcascade_frontalface.xml

【讨论】:

    猜你喜欢
    • 2016-10-26
    • 2019-11-30
    • 2016-05-20
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    • 2020-12-23
    • 1970-01-01
    相关资源
    最近更新 更多