Используя OpenCV версии 4.2.0 в c ++ (VS 2019), я создал проект, который выполняет распознавание лиц на заданном изображении. Я использовал DNC детектор лица Opencv, который использует 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 , плавающие члены по мере необходимости.
Функция обнаруживает лица на данном изображении, но во время игры с этим я сравниваю с dlib's
HOG + SVM детектором лица, поэтому сначала я делаю обнаружение лица с помощью dlib, а затем передается тот же путь к изображению эта функция.
Я нашел несколько изображений, где dlib может легко найти лица на изображении, но opencv не нашел ни одного лица, например, посмотрите на изображение ниже:
Как вы видите, HOG + SVM обнаружил 46 лиц примерно за 3 секунды c. Если я передам это же изображение вышеупомянутой функции, то opencv не обнаружит в нем ни одного лица. Почему? Нужны ли какие-либо улучшения в приведенном выше коде? Я не говорю, что функция не обнаруживает лица для какого-либо изображения, но делает это для некоторых изображений (как выше).
Для ссылки:
Я использовал https://pastebin.com/9rt9reNY эта python программа для обнаружения лиц с помощью dlib.