Conscience Core
CscDetectorEnginePersonPose.h
Go to the documentation of this file.
1 //
2 // CscDetectorEnginePersonPose.hpp
3 // Conscience Core
4 //
5 // Created by Ilies Zaoui on 22/07/2021.
6 // Copyright © 2021 Conscience Robotics. All rights reserved.
7 //
8 
9 #ifndef CscDetectorEnginePersonPose_h
10 #define CscDetectorEnginePersonPose_h
11 
15 #include <opencv2/opencv.hpp>
16 #include <ctime>
17 #include <array>
18 
19 using std::array;
20 using namespace conscience_core::axiomes;
21 
23 
24  ENUM(CscDetectedPersonPose,
25  NonePose,
26  LyingDown,
27  StandingUp,
28  Sit
29  );
30 
32 
34  public:
35 
36  struct Configuration {
38  optional<cv::Size> minSize;
39  optional<cv::Size> maxSize;
40  Configuration(bool drawPredictionOnImage = false,
41  optional<cv::Size> minSize = {},
42  optional<cv::Size> maxSize = {}): drawPredictionOnImage(drawPredictionOnImage), minSize(minSize), maxSize(maxSize) {}
43  };
44 
45  CscDetectorEnginePersonPose(ptr<CscDNNPool> dnnPool, const Configuration &configuration = Configuration());
46 
47  ptr<DetectionResult> detectOnImage(
48  const DetectorSourceImage &image, ptr<DetectionParameters> parameters
49  ) override;
50 
51  virtual bool equals(CscDetectorEngine *) const override;
52 
53  private:
54 
55  bool drawPredictionOnImage;
56 
57  optional<cv::Size> minSize;
58  optional<cv::Size> maxSize;
59 
60  /**********/
61  // FIXME: hardcoded limits
62  static constexpr float standingPersonMaxWidth = 200;
63  static constexpr float standingPersonMinHeight = 360;
64  static constexpr float standingPersonMaxVerticalAngleRadians = .3;
65 
66  static constexpr float maxBoundingBoxArea = 600 * 500;
67 
68  static constexpr float maxDistanceBetweenDots = 320;
69  /**********/
70 
71  ptr<SafeNeuralNetwork> neuralNetwork;
72  string modelTxt;
73  string modelBin;
74 
75  const int NET_INPUT_SIZE = 368;
76 
77  std::unique_ptr<CscLogger> logger;
78 
79  struct KeyPoint{
80  KeyPoint(cv::Point point,float probability){
81  this->id = -1;
82  this->point = point;
83  this->probability = probability;
84  }
85 
86  int id;
87  cv::Point point;
88  float probability;
89  };
90 
92  struct ValidPair{
93  ValidPair(int aId,int bId,float score){
94  this->aId = aId;
95  this->bId = bId;
96  this->score = score;
97  }
98 
99  int aId;
100  int bId;
101  float score;
102  };
103 
104  struct PersonPair {
105  public:
106  const KeyPoint *pointA;
107  const KeyPoint *pointB;
108  bool invalid;
109  };
110 
111  class Person {
112  public:
113  Person(int id, const vector<PersonPair *> &pairs);
114  ~Person();
115  const int id;
116 
117  bool hasInvalidPair() const;
118 
119  optional<cv::Point> getLegsBottomPoint() const { return legsBottomPoint; }
120  optional<CscPoint2d> getTopAverage() const { return topAverage; }
121  optional<CscPoint2d> getMiddleAverage() const { return middleAverage; }
122  optional<CscPoint2d> getBottomAverage() const { return bottomAverage; }
123  optional<cv::Rect> getBoundingBox() const { return boundingBox; }
124  optional<cv::Rect> getBodyBoundingBox() const { return bodyBoundingBox; }
125  bool isBottomToMiddleLinkFound() const { return bottomToMiddleLinkFound; }
126  bool isTopToMiddleLinkFound() const { return topToMiddleLinkFound; }
127  bool getTopPointsCount() const { return topCount; }
128  bool getMiddlePointsCount() const { return middleCount; }
129  bool getBottomPointsCount() const { return bottomCount; }
130 
131  void drawPoints(Mat &imageMatrix, const cv::Scalar &color) const;
132  void registerPublicAIData(map<string, CscPublicAIData*> &skeletonPublicAIData, double imageHeight) const;
133 
134  bool areLegsParallelAndStraight() const;
135 
136  optional<double> getLegsAngle() const { return legsAngle; }
137  optional<double> getRightAnkleKneeAngle() const { return rightKneeFootAngle; }
138  optional<double> getLeftAnkleKneeAngle() const { return leftKneeFootAngle; }
139 
140  optional<double> getRightHipKneeAngle() const { return rightHipKneeAngle; }
141  optional<double> getLeftHipKneeAngle() const { return leftHipKneeAngle; }
142 
143  optional<double> getAnklesFeetAngle() const { return anklesFeetAngle; }
144  optional<double> getLegsLength() const { return legsLength; }
145  optional<double> getTorsoAngle() const { return torsoAngle; }
146  optional<double> getTorsoLength() const { return torsoLength; }
147  optional<cv::Point> getMiddleHipPoint() const;
148  optional<cv::Point> getLeftHipPoint() const;
149  optional<cv::Point> getRightHipPoint() const;
150 
151  optional<cv::Point> getTorsoTopPoint() const;
152 
153  optional<cv::Point> getLeftFootPoint() const;
154  optional<cv::Point> getRightFootPoint() const;
155 
156  optional<cv::Point> getLeftKneePoint() const;
157  optional<cv::Point> getRightKneePoint() const;
158  optional<cv::Point> getLeftWristPoint() const;
159  optional<cv::Point> getRightWristPoint() const;
160 
161  private:
162  map<string, const KeyPoint *> points;
163  const KeyPoint *getPointOrNull(const string &name) const;
164 
165  template <class ... FallbackNames>
166  const KeyPoint *getPointOrOtherOrNull(const char *name, FallbackNames ... otherNames) const {
167  const auto list = {name, otherNames...};
168 
169  for (const char *requestedName : list) {
170  const KeyPoint *result = getPointOrNull(string(requestedName));
171  if (result != nullptr) {
172  return result;
173  }
174  }
175 
176  return nullptr;
177  }
178 
179  const vector<PersonPair *> pairs;
180  bool topToMiddleLinkFound = false;
181  bool bottomToMiddleLinkFound = false;
182  bool hasInvalidPairValue = false;
183  optional<CscPoint2d> topAverage = {};
184  optional<CscPoint2d> middleAverage = {};
185  optional<CscPoint2d> bottomAverage = {};
186  optional<cv::Point> legsBottomPoint = {};
187  optional<cv::Rect> boundingBox = {};
188  optional<cv::Rect> bodyBoundingBox = {};
189  int topCount = 0;
190  int middleCount = 0;
191  int bottomCount = 0;
192 
193  optional<double> torsoAngle = {};
194  optional<double> torsoLength = {};
195 
196  optional<double> leftLegAngle = {};
197  optional<double> leftHipKneeAngle = {};
198  optional<double> hipNeckAngle = {};
199  optional<double> leftKneeFootAngle = {};
200  optional<double> leftAnkleFootAngle = {};
201  optional<double> rightAnkleFootAngle = {};
202  optional<double> anklesFeetAngle = {};
203  optional<double> rightLegAngle = {};
204  optional<double> rightHipKneeAngle = {};
205  optional<double> rightKneeFootAngle = {};
206  optional<double> legsAngle = {};
207  optional<double> legsLength = {};
208  };
209 
210  vector<cv::Mat> splitNetOutputBlobToParts(cv::Mat& netOutputBlob, const cv::Size& targetSize) const;
211  vector<vector<int>> getPersonwiseKeypoints(const std::vector<std::vector<ValidPair>>& validPairs, const std::set<int>& invalidPairs) const;
212  vector<KeyPoint *> getKeyPoints(cv::Mat& probMap, double threshold) const;
213  void getValidPairs(const vector<cv::Mat>& netOutputParts,
214  const vector<vector<KeyPoint *>>& detectedKeypoints,
215  vector<vector<ValidPair>>& validPairs,
216  std::set<int>& invalidPairs) const;
217 
218  CscDetectedPersonPose isPersonLyingOrStandingUp(const Mat &originalImage, Mat &resultingImage, Person *person, const map<string, vector<cv::Point2f>> &ignoredZones);
219 
220  };
221 }
222 
223 #endif
conscience_core::detector_engine::CscDetectorEngine
Definition: CscDetectorEngine.h:107
conscience_core::detector_engine::CscDetectorEnginePersonPose::Configuration::Configuration
Configuration(bool drawPredictionOnImage=false, optional< cv::Size > minSize={}, optional< cv::Size > maxSize={})
Definition: CscDetectorEnginePersonPose.h:40
conscience_core::detector_engine::CscDetectorEnginePersonPose::Configuration::drawPredictionOnImage
bool drawPredictionOnImage
Definition: CscDetectorEnginePersonPose.h:37
conscience_core::detector_engine::SafeNeuralNetwork
CscDNNPool::SafeNeuralNetwork SafeNeuralNetwork
Definition: CscDetectorEngineHandPose.h:25
conscience_core::axiomes
Definition: Csc2dTypes.cpp:9
conscience_core::detector_engine
Definition: ConscienceVisionDetectorRepository.cpp:30
CscDetectorEngine.h
logger
static std::unique_ptr< CscLogger > logger
Definition: gltfHelpers.cpp:6
CscWorldObject.h
conscience_core::detector_engine::CscDetectorEnginePersonPose::Configuration::maxSize
optional< cv::Size > maxSize
Definition: CscDetectorEnginePersonPose.h:39
CscDNNPool.h
conscience_core::detector_engine::CscDetectorEnginePersonPose::Configuration::minSize
optional< cv::Size > minSize
Definition: CscDetectorEnginePersonPose.h:38
conscience_core::detector_engine::Person
@ Person
Definition: CscCommonDetectorTypes.h:35
conscience_core::bridging::commands::environment_objects::optional< double >
const ptr< CscObjectModel > const string const CscPoint3d const CscPoint3d optional< double >
Definition: environmentObjectsCommands.h:367
conscience_core::detector_engine::CscDetectorEnginePersonPose::Configuration
Definition: CscDetectorEnginePersonPose.h:36
conscience_core::detector_engine::CscDetectorEnginePersonPose
Definition: CscDetectorEnginePersonPose.h:33
ptr
std::shared_ptr< T > ptr
Definition: CscCommon.h:29
conscience_utils::equals
bool equals(const map< K, V > &map1, const map< K, V > &map2)
Definition: conscience_util.h:525
conscience_core::detector_engine::ENUM
ENUM(CscDetectedPersonPose, NonePose, LyingDown, StandingUp, Sit)