Ask Your Question
1

dnn module - Face Detection - poor results - Open CV 3.4.3 [closed]

asked 2018-11-13 02:42:37 -0600

rc gravatar image

updated 2020-09-07 04:58:49 -0600

I am getting poor results with the DNN face detection module for images in which the Haarscard cascade works fine.

C++ Code is as follows:

#include <iostream>
#include <string>
#include <vector>
#include <stdlib.h>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/dnn.hpp>

using namespace cv;
using namespace std;
using namespace cv::dnn;

const size_t inWidth = 300;
const size_t inHeight = 300;
const double inScaleFactor = 1.0;
const float confidenceThreshold = 0.7;
const cv::Scalar meanVal(104.0, 177.0, 123.0);

#define CAFFE

const std::string caffeConfigFile = "deploy.prototxt";
const std::string caffeWeightFile = "res10_300x300_ssd_iter_140000_fp16.caffemodel";

const std::string tensorflowConfigFile = "opencv_face_detector.pbtxt";
const std::string tensorflowWeightFile = "opencv_face_detector_uint8.pb";

void detectFaceOpenCVDNN(Net net, Mat &frameOpenCVDNN)
{
    int frameHeight = frameOpenCVDNN.rows;
    int frameWidth = frameOpenCVDNN.cols;

    //resize(frameOpenCVDNN, frameOpenCVDNN, Size(300, 300));


#ifdef CAFFE
        cv::Mat inputBlob = cv::dnn::blobFromImage(frameOpenCVDNN, inScaleFactor, cv::Size(inWidth, inHeight), meanVal, false, false);
#else
        cv::Mat inputBlob = cv::dnn::blobFromImage(frameOpenCVDNN, inScaleFactor, cv::Size(inWidth, inHeight), meanVal, true, false);
#endif

    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++)
    {
        float confidence = detectionMat.at<float>(i, 2);
        cout << confidence << endl;

        if(confidence > confidenceThreshold)
        {

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

            cv::rectangle(frameOpenCVDNN, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(0, 255, 0),2, 4);
        }
    }

}


int main( int argc, const char** argv )
{
#ifdef CAFFE
  Net net = cv::dnn::readNetFromCaffe(caffeConfigFile, caffeWeightFile);
#else
  Net net = cv::dnn::readNetFromTensorflow(tensorflowWeightFile, tensorflowConfigFile);
#endif

  /*VideoCapture source;
  if (argc == 1)
      source.open(0);
  else
      source.open(argv[1]);*/
  Mat frame = imread("barry2.jpg");
  cout << "Channels: " + to_string(frame.channels()) << endl;
  //Mat resized;
  //resize(frame, resized, Size(300, 300));

  double tt_opencvDNN = 0;
  double fpsOpencvDNN = 0;
  //while(1)
  //{
      //source >> frame;
      //if(frame.empty())
          //break;
      //double t = cv::getTickCount();
      detectFaceOpenCVDNN ( net,frame);
      //tt_opencvDNN = ((double)cv::getTickCount() - t)/cv::getTickFrequency();
      //fpsOpencvDNN = 1/tt_opencvDNN;
      //putText(frame, format("OpenCV DNN ; FPS = %.2f",fpsOpencvDNN), Point(10, 50), FONT_HERSHEY_SIMPLEX, 1.4, Scalar(0, 0, 255), 4);
      imshow( "OpenCV - DNN Face Detection",frame);
      int k = waitKey(0);
    //}
}

Sample image attached for which i am failing to get results, unless i lower confidence factors down to about 0.1 (10%).

Any ideas?

Thanks

RichardC:\fakepath\barry2.jpg

edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by dkurt
close date 2018-11-14 09:48:51.154207

1 answer

Sort by ยป oldest newest most voted
1

answered 2018-11-13 03:20:13 -0600

dkurt gravatar image

This is your image after resizing to 300x300:

image description

Object detection networks can work with different input sizes. In example,

1296x864 (origin sizes):

image description

648x432 (x2):

image description

And so on...

edit flag offensive delete link more

Comments

Many thanks for the quick response. I am 100% certain that in a earlier variant of the code above I tried CV::resize with a size parameter of Size(300,300) before passing it to the function.

I believe this is shown in the commented out line

//resize(frameOpenCVDNN, frameOpenCVDNN, Size(300, 300));

I also tried reiszing it to 300 x 300 before calling the code.

Can you confirm you are using the code I posted above, as I am baffled as to what you have done differently to me! :-)

I am using the models posted at learnopencv.com. Is it possible that we are using different TF or caffemodels. Are you able to share whixh models you are using?

Thanks!

rc gravatar imagerc ( 2018-11-13 03:35:16 -0600 )edit

@rc, The results for the same Caffe's model. blobFromImage does resize internally so there is no need to call it separately.

dkurt gravatar imagedkurt ( 2018-11-13 03:49:35 -0600 )edit

Dkurt,

Thanks.

Can you confirm you are using the same code as above , the caffe model posted here: http://www.learnopencv.com/face-detec....

I am still getting no results using the code above when passing in the original unresized image unless I reduce the confidence factor to 0.1 at which point I get lots of false positives.

For the record, I am using opencv 3.4.3 on windows 8.1, not on a GPU.

I don't have the caffe or TF framworks installed, only opencv.

I am really confused!

Thanks

Richard

rc gravatar imagerc ( 2018-11-13 04:09:22 -0600 )edit

@rc, Did you try to replace cv::Size(inWidth, inHeight) which is cv::Size(300, 300) to something else?

dkurt gravatar imagedkurt ( 2018-11-13 06:47:19 -0600 )edit

Dkurt, I believe so, but I can't be certain. I am away from my development machine for the remainder of the afternoon but will try it later today and give an update. Thanks for your continued patience!

rc gravatar imagerc ( 2018-11-13 07:26:10 -0600 )edit

Apologies dkurt. The replacement of the line cv::Size(inWidth, inHeight) which is cv::Size(300, 300) with the actual original image sizes worked perfectly. I was obviously wrong when i thought i had tried that before. Many thanks for your assistance, and apologies for such a basic mistake.

rc gravatar imagerc ( 2018-11-13 18:39:09 -0600 )edit

@rc, Never mind. Nice to help you!

dkurt gravatar imagedkurt ( 2018-11-14 09:48:21 -0600 )edit

I am using almost identical code but without gui. I have tested a number of images on different resolutions. Sometimes a number of false positives is detected outside the frame! The higher the resolution (of the same image) the more false positives. I use this: cv::Mat inputBlob = cv::dnn::blobFromImage(frameOpenCVDNN, inScaleFactor, cv::Size(frameWidth, frameHeight), meanVal, false, false); in which frameWidth and frameHeight are the size of the frame.

arnov gravatar imagearnov ( 2019-02-12 12:32:33 -0600 )edit

@arnov did you solve the issue with the false positives?

sfo gravatar imagesfo ( 2019-05-09 09:09:03 -0600 )edit
sturkmen gravatar imagesturkmen ( 2020-09-07 05:02:57 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2018-11-13 02:42:37 -0600

Seen: 5,241 times

Last updated: Nov 13 '18