首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么基于Opencv DNN (caffe)的人脸检测器找不到人脸?

为什么基于Opencv DNN (caffe)的人脸检测器找不到人脸?
EN

Stack Overflow用户
提问于 2020-01-29 15:10:06
回答 2查看 1.8K关注 0票数 1

通过在c++ (VS 2019)中使用OpenCV版本4.2.0,我创建了一个对给定图像执行人脸检测的项目。我使用了Opencv的DNN人脸检测器,它使用res10_300x300_ssd_iter_140000_fp16.caffemodel模型来检测人脸。下面是该函数的代码:

代码语言:javascript
运行
复制
//variables which are used in function
const double inScaleFactor = 1.0;
const cv::Scalar meanVal = cv::Scalar(104.0, 177.0, 123.0);
const size_t inWidth = 300;
const size_t inHeight = 300;

std::vector<FaceDetectionResult> namespace_name::FaceDetection::detectFaceByOpenCVDNN(std::string filename, FaceDetectionModel model)
{        

    Net net;        
    cv::Mat frame = cv::imread(filename);
    cv::Mat inputBlob;
    std::vector<FaceDetectionResult> vec;


    if (frame.empty())
        throw std::exception("provided image file is not found or unable to open.");

    int frameHeight = frame.rows;
    int frameWidth = frame.cols;

    if (model == FaceDetectionModel::CAFFE)
    {            
        net = cv::dnn::readNetFromCaffe(caffeConfigFile, caffeWeightFile);
        inputBlob = cv::dnn::blobFromImage(frame, inScaleFactor, cv::Size(inWidth, inHeight), meanVal, false, false);
    }
    else
    {            
        net = cv::dnn::readNetFromTensorflow(tensorflowWeightFile, tensorflowConfigFile);
        inputBlob = cv::dnn::blobFromImage(frame, inScaleFactor, cv::Size(inWidth, inHeight), meanVal, true, false);
    }

    net.setInput(inputBlob, "data");
    cv::Mat detection = net.forward("detection_out");

    cv::Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr<float>());

    for (int i = 0; i < detectionMat.rows; i++)
    {            
        if (detectionMat.at<float>(i, 2) >= 0.5)
        {
            FaceDetectionResult res;
            res.faceDetected = true;
            res.confidence = detectionMat.at<float>(i, 2);

            res.x1 = static_cast<int>(detectionMat.at<float>(i, 3) * frameWidth);
            res.y1 = static_cast<int>(detectionMat.at<float>(i, 4) * frameHeight);
            res.x2 = static_cast<int>(detectionMat.at<float>(i, 5) * frameWidth);
            res.y2 = static_cast<int>(detectionMat.at<float>(i, 6) * frameHeight);

            vec.push_back(res);
        }
#ifdef aDEBUG
        else
        {

            cout << detectionMat.at<float>(i, 2) << endl;

        }
#endif
    }                
    return vec;
}

在上面的代码中,在人脸检测之后,我在自定义类FaceDetectionResult中分配了检测到的人脸的置信度和坐标,这是一个具有bool和int的简单类,根据需要浮动成员。

函数检测给定图像中的人脸,但在玩这个游戏时,我正在与dlib's HOG+SVM人脸检测器进行比较,所以首先我使用dlib进行人脸检测,然后将相同的图像路径传递给此函数。

我找到了一些图片,其中dlib可以很容易地找到图像中的人脸,但opencv找不到一个单独的人脸,例如查看下面的图像:

正如你所看到的,HOG+SVM在大约3秒内检测到了46个人脸,如果我将同样的图像传递给上面的函数,那么opencv没有检测到其中的一个人脸。为什么?我需要在上面的代码中进行任何增强吗?我并不是说函数不能检测任何图像的人脸,它确实可以,但对于一些图像(如上面的图像),它不能。

参考:

我使用https://pastebin.com/9rt9reNY这个python程序通过dlib检测人脸。

EN

回答 2

Stack Overflow用户

发布于 2020-01-29 18:00:16

经过深入的搜索,不幸的是我找不到一个很好的解释来解释这个问题。我尝试裁剪图像的原因是我假设可以有一个最大检测到的人脸数量限制。它也不是关于遮挡。

我尝试了一些图像示例,其中包括20多个(appx.)面孔和结果是相同的,但当我裁剪这些图像(减少面孔的数量)时,程序能够发现faces.This也与图像的分辨率(大小)无关,因为我尝试的图像具有不同的大小。

我还更改并尝试了所有参数(迭代次数、confidentThreshold等)。但结果仍然不是理想的结果。

我的假设是,但不是答案:

如果图像包含的最大数目超过最大值(大约20个),则程序不允许查找人脸

作为这个问题的解决方案,我们可以将源图像分成两部分,并找到每个部分的矩形,然后可以粘贴到源图像上。

注:在互联网上深入挖掘后,我找不到与这个问题相关的主题。我也很好奇导致这个问题的主要原因,所以任何帮助都将不胜感激。这篇文章只包含我的经验和假设。

票数 1
EN

Stack Overflow用户

发布于 2020-03-06 02:21:47

更改此行:

代码语言:javascript
运行
复制
inputBlob = cv::dnn::blobFromImage(frame, inScaleFactor, cv::Size(inWidth, inHeight), meanVal, false, false);

在这一行中:

代码语言:javascript
运行
复制
frameHeightinputBlob = cv::dnn::blobFromImage(frame, inScaleFactor, cv::Size(inWidth, inHeight), meanVal, false, false);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59962053

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档