Ask Your Question

Revision history [back]

DNN face detection in UWP/C++: strange output

Hello, I'm using OpenCV and Cafe to perform face detection on some images I receive from a stream. First, I tried with python:

    prototxt_file = 'deploy.prototxt'
    weights_file = 'res10_300x300_ssd_iter_140000.caffemodel'
    dnn = cv2.dnn.readNetFromCaffe(prototxt_file, weights_file)

    for image in images:
      blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), 
                                  (104.0, 177.0, 123.0))

      dnn.setInput(blob)
      detections = dnn.forward()

      for i in range(0, detections.shape[2]):
              confidence = detections[0, 0, i, 2]
              box = detections[0, 0, i, 3:7]
              if confidence > 0.5:
                    //Do something

This works quite well. Now, I want to do the same within a C++ Windows UWP App, so I compiled OpenCV from source for UWP (tried with versions 3.4.1 and 4.3.0). After going through this example I tried the following:

        std::string caffeConfigFilePath = "deploy.prototxt";
        std::string caffeWeightFilePath = "res10_300x300_ssd_iter_140000.caffemodel";
        net = cv::dnn::readNetFromCaffe(caffeConfigFilePath, caffeWeightFilePath);

        for (image in images)
        {
          cv::Mat imageResized, imageBlob;
          std::vector<cv::Mat> outs;

          cv::resize(image, imageResized, cv::Size(300, 300));
          cv::dnn::blobFromImage(imageResized, imageBlob, 1, cv::Size(300, 300),
                              (104.0, 177.0, 123.0));

          net.setInput(imageBlob, "data");
          net.forward(outs, "detection_out");

          CV_Assert(outs.size() > 0);
          for (size_t k = 0; k < outs.size(); k++)
          {
             float* data = (float*)outs[k].data;
             for (size_t i = 0; i < outs[k].total(); i += 7)
             {
                 float confidence = data[i + 2];
                 if (confidence > 0.5)
                 {
                        //Do something
                 }
             }
          }

This gives me very bad results. I get a lot of detections with a confidence of 1.0, covering the entire image. The face itself, however, is not detected. So I thought I might be reading the output wrong. I also tried the code posted with this question, but the results are the same. I checked everything I could think of (input images in right format, model correctly loaded, etc.) but could not identify the error.

Since the DNN module is usually not included in an OpenCV UWP build (I had to comment some lines in the CMake.txt, but then it compiled without errors), can it be that using it is just not possible from a UWP app? What else could be the reason the code is working in python, but an almost identical code is not working in C++?

click to hide/show revision 2
retagged

updated 2020-07-16 10:49:20 -0600

berak gravatar image

DNN face detection in UWP/C++: strange output

Hello, I'm using OpenCV and Cafe to perform face detection on some images I receive from a stream. First, I tried with python:

    prototxt_file = 'deploy.prototxt'
    weights_file = 'res10_300x300_ssd_iter_140000.caffemodel'
    dnn = cv2.dnn.readNetFromCaffe(prototxt_file, weights_file)

    for image in images:
      blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), 
                                  (104.0, 177.0, 123.0))

      dnn.setInput(blob)
      detections = dnn.forward()

      for i in range(0, detections.shape[2]):
              confidence = detections[0, 0, i, 2]
              box = detections[0, 0, i, 3:7]
              if confidence > 0.5:
                    //Do something

This works quite well. Now, I want to do the same within a C++ Windows UWP App, so I compiled OpenCV from source for UWP (tried with versions 3.4.1 and 4.3.0). After going through this example I tried the following:

        std::string caffeConfigFilePath = "deploy.prototxt";
        std::string caffeWeightFilePath = "res10_300x300_ssd_iter_140000.caffemodel";
        net = cv::dnn::readNetFromCaffe(caffeConfigFilePath, caffeWeightFilePath);

        for (image in images)
        {
          cv::Mat imageResized, imageBlob;
          std::vector<cv::Mat> outs;

          cv::resize(image, imageResized, cv::Size(300, 300));
          cv::dnn::blobFromImage(imageResized, imageBlob, 1, cv::Size(300, 300),
                              (104.0, 177.0, 123.0));

          net.setInput(imageBlob, "data");
          net.forward(outs, "detection_out");

          CV_Assert(outs.size() > 0);
          for (size_t k = 0; k < outs.size(); k++)
          {
             float* data = (float*)outs[k].data;
             for (size_t i = 0; i < outs[k].total(); i += 7)
             {
                 float confidence = data[i + 2];
                 if (confidence > 0.5)
                 {
                        //Do something
                 }
             }
          }

This gives me very bad results. I get a lot of detections with a confidence of 1.0, covering the entire image. The face itself, however, is not detected. So I thought I might be reading the output wrong. I also tried the code posted with this question, but the results are the same. I checked everything I could think of (input images in right format, model correctly loaded, etc.) but could not identify the error.

Since the DNN module is usually not included in an OpenCV UWP build (I had to comment some lines in the CMake.txt, but then it compiled without errors), can it be that using it is just not possible from a UWP app? What else could be the reason the code is working in python, but an almost identical code is not working in C++?