age-gender-detection.cpp
Go to the documentation of this file.
1 // Copyright (C) 2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 
7 #include <easylogging++.h>
8 
9 using namespace InferenceEngine;
10 
11 
13 {
14  age_gender_detection::age_gender_detection(
15  const std::string &pathToModel,
16  bool isAsync,
17  int maxBatch, bool isBatchDynamic,
18  bool doRawOutputMessages
19  )
20  : base_detection( "age/gender", pathToModel, maxBatch, isBatchDynamic, isAsync, doRawOutputMessages)
21  , _n_enqued_frames(0)
22  {
23  }
24 
25 
27  {
28  if( !_n_enqued_frames )
29  return;
30  _n_enqued_frames = 0;
32  }
33 
34 
35  void age_gender_detection::enqueue( const cv::Mat &face )
36  {
37  if( !enabled() )
38  return;
39  if( !_request )
40  _request = net.CreateInferRequestPtr();
41 
42  Blob::Ptr inputBlob = _request->GetBlob( input );
43  matU8ToBlob<uint8_t>( face, inputBlob, _n_enqued_frames );
44 
46  }
47 
48 
50  {
51  Blob::Ptr genderBlob = _request->GetBlob( outputGender );
52  Blob::Ptr ageBlob = _request->GetBlob( outputAge );
53 
55  ageBlob->buffer().as<float*>()[idx] * 100,
56  genderBlob->buffer().as<float*>()[idx * 2 + 1]
57  };
59  LOG(DEBUG) << "element" << idx << ", male prob = " << r.maleProb << ", age = " << r.age;
60 
61  return r;
62  }
63 
64 
66  {
67  LOG(INFO) << "Loading " << topoName << " model from: " << pathToModel;
68 
69  CNNNetwork network;
70 
71 #ifdef OPENVINO2019
72  CNNNetReader netReader;
73 
75  netReader.ReadNetwork( pathToModel );
76  network = netReader.getNetwork();
77 
79  std::string binFileName = remove_ext( pathToModel ) + ".bin";
80  netReader.ReadWeights( binFileName );
81 #else
82  InferenceEngine::Core ie;
84  network = ie.ReadNetwork(pathToModel);
85 #endif
86 
88  //LOG(DEBUG) << "Batch size is set to " << maxBatch;
89  network.setBatchSize(maxBatch);
90 
91  // Age/Gender Recognition network should have one input and two outputs
92 
93  LOG(DEBUG) << "Checking Age/Gender Recognition network inputs";
94  InputsDataMap inputInfo(network.getInputsInfo());
95  if (inputInfo.size() != 1)
96  throw std::logic_error("Age/Gender Recognition network should have only one input");
97  InputInfo::Ptr& inputInfoFirst = inputInfo.begin()->second;
98  inputInfoFirst->setPrecision(Precision::U8);
99  input = inputInfo.begin()->first;
100 
101  LOG(DEBUG) << "Checking Age/Gender Recognition network outputs";
102  OutputsDataMap outputInfo(network.getOutputsInfo());
103  if (outputInfo.size() != 2)
104  throw std::logic_error("Age/Gender Recognition network should have two output layers");
105  auto it = outputInfo.begin();
106 
107  DataPtr ptrAgeOutput = (it++)->second;
108  DataPtr ptrGenderOutput = (it++)->second;
109 
110  if (!ptrAgeOutput)
111  throw std::logic_error("Age output data pointer is not valid");
112  if (!ptrGenderOutput)
113  throw std::logic_error("Gender output data pointer is not valid");
114 
115 
116 #ifdef OPENVINO2019
117  auto genderCreatorLayer = ptrGenderOutput->getCreatorLayer().lock();
118  auto ageCreatorLayer = ptrAgeOutput->getCreatorLayer().lock();
119 
120  if (!ageCreatorLayer)
121  throw std::logic_error("Age creator layer pointer is not valid");
122  if (!genderCreatorLayer)
123  throw std::logic_error("Gender creator layer pointer is not valid");
124 
125  // if gender output is convolution, it can be swapped with age
126  if (genderCreatorLayer->type == "Convolution")
127  std::swap(ptrAgeOutput, ptrGenderOutput);
128 
129  if (ptrAgeOutput->getCreatorLayer().lock()->type != "Convolution")
130  throw std::logic_error("In Age/Gender Recognition network, age layer (" + ageCreatorLayer->name +
131  ") should be a Convolution, but was: " + ageCreatorLayer->type);
132 
133  if (ptrGenderOutput->getCreatorLayer().lock()->type != "SoftMax")
134  throw std::logic_error("In Age/Gender Recognition network, gender layer (" + genderCreatorLayer->name +
135  ") should be a SoftMax, but was: " + genderCreatorLayer->type);
136 
138  {
139  LOG(DEBUG) << "Age layer: " << ageCreatorLayer->name;
140  LOG(DEBUG) << "Gender layer: " << genderCreatorLayer->name;
141  }
142 #else
143 #ifdef OPENVINO_NGRAPH
144  if (auto ngraphFunction = network.getFunction())
145  {
146  // Looking for the age and gender nodes in the ngraph: the age layer node should be Convolution type.
147  // If we find ptrGenderOutput is with Convolution type, swap them.
148  for (const auto& op : ngraphFunction->get_ops())
149  {
150  std::string friendly_name = op->get_friendly_name();
151  std::string output_type = op->get_type_name();
152 
153  if ((friendly_name.find(ptrGenderOutput->getName()) != std::string::npos) && (output_type == "Convolution"))
154  {
155  std::swap(ptrAgeOutput, ptrGenderOutput);
156  break;
157  }
158  }
159 
160  bool outputAgeOk = false;
161 
162  for (const auto& op : ngraphFunction->get_ops())
163  {
164  std::string friendly_name = op->get_friendly_name();
165  std::string output_type = op->get_type_name();
166 
167  if ((friendly_name.find(ptrAgeOutput->getName()) != std::string::npos) && (output_type == "Convolution")) {
168  outputAgeOk = true;
169  break;
170  }
171  }
172 
173  if (!outputAgeOk)
174  {
175  throw std::logic_error("In Age/Gender Recognition network, Age layer (" + ptrAgeOutput->getName() + ") should be a Convolution");
176  }
177 
178  bool outputGenderOk = false;
179 
180  for (const auto& op : ngraphFunction->get_ops()) {
181  std::string friendly_name = op->get_friendly_name();
182  std::string output_type = op->get_type_name();
183 
184  if ((friendly_name.find(ptrGenderOutput->getName()) != std::string::npos) && (output_type == "Softmax")) {
185  outputGenderOk = true;
186  break;
187  }
188  }
189 
190  if (!outputGenderOk)
191  {
192  throw std::logic_error("In Age/Gender Recognition network, Gender layer (" + ptrGenderOutput->getName() + ") should be a Softmax");
193  }
194  }
195 
197  {
198  LOG(DEBUG) << "Age layer: " << ptrAgeOutput->getName();
199  LOG(DEBUG) << "Gender layer: " << ptrGenderOutput->getName();
200  }
201 #endif
202 #endif
203 
204  outputAge = ptrAgeOutput->getName();
205  outputGender = ptrGenderOutput->getName();
206 
207  _enabled = true;
208  return network;
209  }
210 }
InferenceEngine::InferRequest::Ptr _request
std::string remove_ext(const std::string &filepath)
InferenceEngine::ExecutableNetwork net
LOG(INFO)<< "Log message to default logger"
GLdouble GLdouble r
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.hpp:24397
#define op
static auto it
#define INFO(msg)
Definition: catch.hpp:17429
InferenceEngine::CNNNetwork read_network() override
std::array< float3, 4 > face
Definition: model-views.h:450


librealsense2
Author(s): LibRealSense ROS Team
autogenerated on Thu Dec 22 2022 03:41:41