SSCMA-Micro CPP SDK  v2.0.0
SSCMA-Micro is a cross-platform machine learning inference framework designed for embedded devices.
refactor_required.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <memory>
5 #include <string>
6 #include <vector>
7 #include <forward_list>
8 
9 #include "core/ma_core.h"
10 #include "core/ma_debug.h"
11 #include "core/utils/ma_base64.h"
12 #include "porting/ma_porting.h"
13 #include "resource.hpp"
15 
16 namespace ma {
17 
18 #if MA_TRIGGER_USE_REAL_GPIO
19 extern bool __ma_is_trigger_gpio(int pin);
20 extern void __ma_init_gpio_level(int pin, int level);
21 extern void __ma_set_gpio_level(int pin, int level);
22 #else
23 static bool __ma_is_trigger_gpio(int pin) {
24  (void)pin;
25  MA_LOGD(MA_TAG, "GPIO pin: %d", pin);
26  return true;
27 }
28 static void __ma_init_gpio_level(int pin, int level) {
29  (void)pin;
30  (void)level;
31  MA_LOGD(MA_TAG, "GPIO pin: %d, level: %d", pin, level);
32 }
33 static void __ma_set_gpio_level(int pin, int level) {
34  (void)pin;
35  (void)level;
36  MA_LOGD(MA_TAG, "GPIO pin: %d, level: %d", pin, level);
37 }
38 #endif
39 
40 using namespace ma::model;
41 
43  if (algorithm == nullptr) {
44  return MA_EINVAL;
45  }
46 
47  switch (algorithm->getType()) {
48  case MA_MODEL_TYPE_PFLD:
49  return static_cast<PointDetector*>(algorithm)->run(&img);
50 
52  return static_cast<Classifier*>(algorithm)->run(&img);
53 
54  case MA_MODEL_TYPE_FOMO:
60  return static_cast<Detector*>(algorithm)->run(&img);
61 
64  return static_cast<PoseDetector*>(algorithm)->run(&img);
65 
66  default:
67  return MA_ENOTSUP;
68  }
69 }
70 
71 ma_err_t serializeAlgorithmOutput(Model* algorithm, Encoder* encoder, int width, int height) {
72 
73  if (algorithm == nullptr || encoder == nullptr) {
74  return MA_EINVAL;
75  }
76 
77  auto ret = MA_OK;
78 
79  switch (algorithm->getType()) {
80  case MA_MODEL_TYPE_PFLD: {
81  auto results = static_cast<PointDetector*>(algorithm)->getResults();
82  for (auto& result : results) {
83  result.x = static_cast<int>(std::round(result.x * width));
84  result.y = static_cast<int>(std::round(result.y * height));
85  result.score = static_cast<int>(std::round(result.score * 100));
86  }
87  ret = encoder->write(results);
88 
89  break;
90  }
91 
92  case MA_MODEL_TYPE_IMCLS: {
93 
94  auto results = static_cast<Classifier*>(algorithm)->getResults();
95  for (auto& result : results) {
96  result.score = static_cast<int>(std::round(result.score * 100));
97  }
98  ret = encoder->write(results);
99 
100  break;
101  }
102 
103  case MA_MODEL_TYPE_FOMO:
109  case MA_MODEL_TYPE_RTMDET: {
110 
111  auto results = static_cast<Detector*>(algorithm)->getResults();
112  MA_LOGD(MA_TAG, "Results size: %d", std::distance(results.begin(), results.end()));
113  for (auto& result : results) {
114  result.x = static_cast<int>(std::round(result.x * width));
115  result.y = static_cast<int>(std::round(result.y * height));
116  result.w = static_cast<int>(std::round(result.w * width));
117  result.h = static_cast<int>(std::round(result.h * height));
118  result.score = static_cast<int>(std::round(result.score * 100));
119  }
120  ret = encoder->write(results);
121 
122  break;
123  }
124 
127 
128  auto results = static_cast<PoseDetector*>(algorithm)->getResults();
129  for (auto& result : results) {
130  auto& box = result.box;
131  box.x = static_cast<int>(std::round(box.x * width));
132  box.y = static_cast<int>(std::round(box.y * height));
133  box.w = static_cast<int>(std::round(box.w * width));
134  box.h = static_cast<int>(std::round(box.h * height));
135  box.score = static_cast<int>(std::round(box.score * 100));
136  for (auto& pt : result.pts) {
137  pt.x = static_cast<int>(std::round(pt.x * width));
138  pt.y = static_cast<int>(std::round(pt.y * height));
139  }
140  }
141  ret = encoder->write(results);
142 
143  break;
144  }
145 
146  default:
147  ret = MA_ENOTSUP;
148  }
149 
150  if (ret != MA_OK) {
151  MA_LOGD(MA_TAG, "Failed to serialize algorithm output: %d", ret);
152  }
153 
154  return ret;
155 }
156 
157 struct TriggerRule {
158  static std::shared_ptr<TriggerRule> create(const std::string& rule_str) {
159  auto rule = std::make_shared<TriggerRule>();
160 
161  std::vector<std::string> tokens;
162  for (size_t i = 0, j = 0; i < rule_str.size(); i = j + 1) {
163  j = rule_str.find(',', i);
164  if (j == std::string::npos) {
165  j = rule_str.size();
166  }
167  tokens.push_back(rule_str.substr(i, j - i));
168  }
169  if (tokens.size() < 6) {
170  return nullptr;
171  }
172 
173  rule->class_id = std::atoi(tokens[0].c_str());
174  if (rule->class_id < 0) {
175  return nullptr;
176  }
177 
178  switch (std::atoi(tokens[1].c_str())) {
179  case 0:
180  rule->comp = std::greater<float>();
181  break;
182  case 1:
183  rule->comp = std::less<float>();
184  break;
185  case 2:
186  rule->comp = std::greater_equal<float>();
187  break;
188  case 3:
189  rule->comp = std::less_equal<float>();
190  break;
191  case 4:
192  rule->comp = std::equal_to<float>();
193  break;
194  case 5:
195  rule->comp = std::not_equal_to<float>();
196  break;
197  default:
198  return nullptr;
199  }
200 
201  rule->threshold = std::atoi(tokens[2].c_str()) / 100.0;
202  if (rule->threshold < 0 || rule->threshold > 1) {
203  return nullptr;
204  }
205 
206  rule->gpio_pin = std::atoi(tokens[3].c_str());
207  if (!__ma_is_trigger_gpio(rule->gpio_pin)) {
208  return nullptr;
209  }
210 
211  rule->default_level = std::atoi(tokens[4].c_str());
212  if (rule->default_level != 0 && rule->default_level != 1) {
213  return nullptr;
214  }
215  rule->trigger_level = std::atoi(tokens[5].c_str());
216  if (rule->trigger_level != 0 && rule->trigger_level != 1) {
217  return nullptr;
218  }
219 
220  __ma_init_gpio_level(rule->gpio_pin, rule->default_level);
221 
222  return rule;
223  }
224 
225  ~TriggerRule() = default;
226 
227  void operator()(Model* algorithm) {
228  if (algorithm == nullptr) {
229  return;
230  }
231 
232  bool fit = false;
233 
234  switch (algorithm->getType()) {
235  case MA_MODEL_TYPE_PFLD: {
236  const auto& results = static_cast<PointDetector*>(algorithm)->getResults();
237  for (const auto& result : results) {
238  if (result.target == class_id && comp(result.score, threshold)) {
239  fit = true;
240  break;
241  }
242  }
243  break;
244  }
245 
246  case MA_MODEL_TYPE_IMCLS: {
247  auto results = static_cast<Classifier*>(algorithm)->getResults();
248  for (auto& result : results) {
249  if (result.target == class_id && comp(result.score, threshold)) {
250  fit = true;
251  break;
252  }
253  }
254  break;
255  }
256 
257  case MA_MODEL_TYPE_FOMO:
263  case MA_MODEL_TYPE_RTMDET: {
264  auto results = static_cast<Detector*>(algorithm)->getResults();
265  for (auto& result : results) {
266  if (result.target == class_id && comp(result.score, threshold)) {
267  fit = true;
268  break;
269  }
270  }
271 
272  break;
273  }
274 
277  auto results = static_cast<PoseDetector*>(algorithm)->getResults();
278  for (auto& result : results) {
279  if (result.box.target == class_id && comp(result.box.score, threshold)) {
280  fit = true;
281  break;
282  }
283  }
284 
285  break;
286  }
287 
288  default:
289  break;
290  }
291 
292  if (fit) {
293  __ma_set_gpio_level(gpio_pin, trigger_level);
294  } else {
295  __ma_set_gpio_level(gpio_pin, default_level);
296  }
297  }
298 
299  TriggerRule() = default;
300 
301 private:
302  int class_id;
303  std::function<bool(float, float)> comp;
304  float threshold;
305  int gpio_pin;
306  int default_level;
307  int trigger_level;
308 };
309 
310 std::forward_list<std::shared_ptr<TriggerRule>> trigger_rules;
312 
313 } // namespace ma
Definition: ma_codec_base.h:14
virtual ma_err_t write(const std::string &key, int8_t value)=0
Encoder type for write int8_t value.
Definition: ma_model_base.h:14
ma_model_type_t getType() const
Definition: ma_model_base.cpp:73
Definition: ma_osal.h:80
Definition: ma_model_classifier.h:12
Definition: ma_model_detector.h:12
Definition: ma_model_point_detector.h:10
Definition: ma_model_pose_detector.h:10
#define MA_LOGD(TAG,...)
Definition: ma_debug.h:79
#define MA_TAG
Definition: ma_debug.h:9
@ MA_MODEL_TYPE_YOLOV5
Definition: ma_types.h:279
@ MA_MODEL_TYPE_PFLD
Definition: ma_types.h:278
@ MA_MODEL_TYPE_YOLOV8_POSE
Definition: ma_types.h:281
@ MA_MODEL_TYPE_IMCLS
Definition: ma_types.h:280
@ MA_MODEL_TYPE_FOMO
Definition: ma_types.h:277
@ MA_MODEL_TYPE_NVIDIA_DET
Definition: ma_types.h:283
@ MA_MODEL_TYPE_YOLO11_POSE
Definition: ma_types.h:286
@ MA_MODEL_TYPE_YOLO_WORLD
Definition: ma_types.h:284
@ MA_MODEL_TYPE_YOLO11
Definition: ma_types.h:285
@ MA_MODEL_TYPE_RTMDET
Definition: ma_types.h:289
@ MA_MODEL_TYPE_YOLOV8
Definition: ma_types.h:282
ma_err_t
Definition: ma_types.h:21
@ MA_ENOTSUP
Definition: ma_types.h:31
@ MA_OK
Definition: ma_types.h:23
@ MA_EINVAL
Definition: ma_types.h:28
Definition: ma_model_classifier.cpp:5
Definition: ma_cv.cpp:7
ma_err_t serializeAlgorithmOutput(Model *algorithm, Encoder *encoder, int width, int height)
Definition: refactor_required.hpp:71
ma_err_t setAlgorithmInput(Model *algorithm, ma_img_t &img)
Definition: refactor_required.hpp:42
std::forward_list< std::shared_ptr< TriggerRule > > trigger_rules
Definition: refactor_required.hpp:310
ma::Mutex trigger_rules_mutex
Definition: refactor_required.hpp:311
Definition: refactor_required.hpp:157
static std::shared_ptr< TriggerRule > create(const std::string &rule_str)
Definition: refactor_required.hpp:158
TriggerRule()=default
void operator()(Model *algorithm)
Definition: refactor_required.hpp:227
~TriggerRule()=default
Definition: ma_types.h:124