通过在 c++(VS 2019)中使用 OpenCV 4.2.0 版,我创建了对给定图像执行人脸检测的项目。我使用了 Opencv 的 DNN 人脸检测器,它使用res10_300x300_ssd_iter_140000_fp16.caffemodel
模型来检测人脸。下面是该函数的代码:
//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,float 成员的简单类。
函数检测给定图像中的人脸,但是在玩这个时我正在与dlib's
HOG+SVM 人脸检测器进行比较,所以首先我通过 dlib 进行人脸检测,然后将相同的图像路径传递给这个函数。
我发现了一些图像,其中 dlib 可以很容易地在图像中找到人脸,但 opencv 没有找到一个人脸,例如看下图:
如您所见,HOG+SVM 在大约 3 秒内检测到 46 张人脸,如果我将相同的图像传递给上述函数,那么 opencv 没有在其中检测到一张人脸。为什么?我需要对上述代码进行任何增强吗?我并不是说该功能不会检测任何图像的人脸,它确实可以,但对于某些图像(如上)它不能。
参考:
我使用https://pastebin.com/9rt9reNY这个 python 程序使用 dlib 检测人脸。