带有面部检测和形状预测的 Dlib 网络摄像头捕获速度很慢
Posted
技术标签:
【中文标题】带有面部检测和形状预测的 Dlib 网络摄像头捕获速度很慢【英文标题】:Dlib webcam capture with face detection and shape prediction is slow 【发布时间】:2016-07-14 18:29:47 【问题描述】:我正在开发一个 C++ 程序,该程序应该从网络摄像头流中检测人脸,而不是使用人脸地标裁剪它们并交换它们。
我使用 OpenCV 和 Viola-Jones 人脸检测对人脸检测进行了编程。工作正常。比我搜索如何从 ROI 中分割只是面部。我尝试了一些皮肤检测实现,但都没有成功。
比我发现 dlib 人脸地标。我决定试一试。刚开始我遇到了一些问题,因为我必须将cv::Mat
转换为cv_image
,将矩形转换为矩形等。所以我尝试只用 dlib 来做。我只是使用cv::VideoCapture
获取流,然后我想展示使用 dlib image_window
捕获的内容。但问题是它非常慢。 Down是使用的代码。注释行是执行相同但使用 OpenCV 的行。 OpenCV 比没有注释的代码更快、更流畅、更连续,就像 5 FPS。那太糟了。我无法想象当我应用人脸检测和人脸地标时会有多慢。
我做错了吗?我怎样才能让它更快?还是应该使用 OpenCV 进行视频捕捉和展示?
cv::VideoCapture cap;
image_window output_frame;
if (!cap.open(0))
cout << "ERROR: Opening video device 0 FAILED." << endl;
return -1;
cv::Mat cap_frame;
//HWND hwnd;
do
cap >> cap_frame;
if (!cap_frame.empty())
cv_image<bgr_pixel> dlib_frame(cap_frame);
output_frame.set_image(dlib_frame);
//cv::imshow("output",dlib::toMat(dlib_frame));
//if (27 == char(cv::waitKey(10)))
//
// return 0;
//
//hwnd = FindWindowA(NULL, "output");
while(!output_frame.is_closed())//while (hwnd != NULL);
编辑: 切换到释放模式后,显示捕获的帧变得很好。 但我继续尝试使用 dlib 进行 面部检测 和 形状预测,就像这里的示例 http://dlib.net/face_landmark_detection_ex.cpp.html。这是相当滞后的。所以我关闭了形状预测。仍然“滞后”。
所以我认为人脸检测会减慢速度。所以我尝试使用 OpenCV 进行人脸检测,因为它明显优于 dlib 检测器。我需要将检测到的 cv::Rect 转换为 dlib::rectangle。我用过这个。
std::vector<dlib::rectangle> dlib_rois;
long l, t, r, b;
for (int i = cv_rois.size() - 1; i >= 0; i--)
l = cv_rois[i].x;
t = cv_rois[i].y;
r = cv_rois[i].x + cv_rois[i].width;
b = cv_rois[i].y + cv_rois[i].height;
dlib_rois.push_back(dlib::rectangle(l, t, r, b));
但是这种 OpenCV 人脸检测 和 dlib 形状预测 的组合变得残酷滞后。处理单帧大约需要4s。
我不知道为什么。 OpenCV 人脸检测绝对没问题,dlib 形状预测似乎并不难处理。有人可以帮我吗?
【问题讨论】:
dlib.net/faq.html#Whyisdlibslow 我会尝试发布模式。现在谢谢。但是我仍然想知道带有面部检测的 OpenCV 怎么可能比仅在 dlib 中显示捕获的帧更流畅。 @DavisKing 感谢它似乎与 OpenCV 相当。 无论如何形状预测都很慢。我在某处看到它很快,但在我的实现中它真的很慢。我在小照片上花了几秒钟。没有实时处理:/ @Gondil 和 DavisKing 是的 Dlib 的人脸检测器比 OpenCV 的人脸检测器慢得多。但是人脸标志点的检测速度很快,实际上只需要几毫秒。程序中的人脸检测需要花费很多时间。您可以通过在各个点获取时间戳来查看这一点,然后您会看到人脸检测步骤需要花费大量时间。 【参考方案1】:在假设 Dlib 很慢之前,您可以采取一些措施来让 Dlib 运行得更快。您只需阅读更多文档并尝试。
Dlib 能够在非常小的区域(80x80 像素)中检测人脸。您可能以大约 1280x720 的分辨率发送原始网络摄像头帧,这不是必需的。根据我的经验,我建议将帧减少大约原始分辨率的四分之一。是的,320x180 适合 Dlib。结果,您将获得 4 倍的速度。
如 cmets 中所述,通过在构建 Dlib 时开启编译优化,您将获得显着的速度提升。
Dlib 处理灰度图像的速度更快。您不需要网络摄像头框架上的颜色。您可以使用 OpenCV 将之前缩小的帧转换为灰度。
Dlib 会花时间寻找人脸,但在人脸上寻找地标的速度非常快。只有当您的网络摄像头提供高帧率 (24-30fps) 时,您才能跳过一些帧,因为面部通常不会移动太多。
鉴于这些优化,我相信您将获得至少 12 倍的检测速度。
【讨论】:
320x180 is fine for Dlib
我的相机捕捉到 1080。如果我让它以 1920x1080 分辨率录制,它会从很远的地方(距离相机超过 3m)检测到我的脸。如果我调整捕获帧的大小并将其发送到 dlib 的检测器,它将不再“看到”那么远。在四分之一尺寸的框架中,我必须靠近相机才能检测到我的脸。这是预期的吗?
是的,这完全有道理,因为 Dlib 可以在小至 80x80 的区域中检测人脸。强烈建议调整大小以获得更快的检测速度。
谢谢。以及如何改变最小面积?比如说 100x100。以上是关于带有面部检测和形状预测的 Dlib 网络摄像头捕获速度很慢的主要内容,如果未能解决你的问题,请参考以下文章