PosturePerfection
pipeline.h
Go to the documentation of this file.
1 
22 #ifndef SRC_PIPELINE_H_
23 #define SRC_PIPELINE_H_
24 
25 #include <CppTimer.h>
26 
27 #include <condition_variable> //NOLINT [build/c++11]
28 #include <deque>
29 #include <mutex> //NOLINT [build/c++11]
30 #include <thread> //NOLINT [build/c++11]
31 #include <vector>
32 
33 #include "iir.h"
34 #include "inference_core.h"
35 #include "opencv2/core.hpp"
36 #include "opencv2/videoio.hpp"
37 #include "post_processor.h"
38 #include "posture_estimator.h"
39 #include "pre_processor.h"
40 
41 #define FRAME_DELAY_MAX 2000
42 #define FRAME_DELAY_MIN 50
43 #define FRAME_DELAY_DEFAULT 1000
44 
49 namespace Buffer {
50 
63 template <typename T>
64 struct PopResult {
65  T value;
66  bool valid;
67 };
68 
85 template <typename T>
86 class Buffer {
87  private:
88  std::mutex lock_in;
89  std::mutex lock_out;
90  std::vector<T> queue;
91 
92  size_t front_index = 0;
93  size_t back_index = 0;
94 
102  bool* running;
103 
112  uint8_t id = -1;
113 
119  size_t size(void) {
120  int size = back_index - front_index;
121  if (size < 0) {
122  return (queue.size() + size);
123  }
124  return size;
125  }
126 
131  bool full = false;
132 
133  public:
140  explicit Buffer(bool* running_ptr, size_t max_size)
141  : running(running_ptr), queue(max_size) {}
142 
152  void push(T frame) {
153  while (*running) {
154  lock_in.lock();
155  if ((uint8_t)(id + 1) == frame.id && !full) {
156  queue.at(back_index) = frame;
157  back_index = (back_index + 1) % queue.size();
158  if (back_index == front_index) {
159  full = true;
160  }
161 
162  id++;
163  lock_in.unlock();
164  break;
165  }
166  lock_in.unlock();
167  }
168  }
169 
182  bool try_push(T frame) {
183  while (*running) {
184  // Immediately return if the queue is full
185  lock_in.lock();
186  if (full) {
187  lock_in.unlock();
188  return false;
189  }
190 
191  if ((uint8_t)(id + 1) == frame.id) {
192  queue.at(back_index) = frame;
193  back_index = (back_index + 1) % queue.size();
194  if (front_index == back_index) {
195  full = true;
196  }
197 
198  id++;
199  lock_in.unlock();
200  return true;
201  } else {
202  lock_in.unlock();
203  }
204  }
205  return false;
206  }
207 
215  PopResult<T> front = PopResult<T>{T{}, false};
216  while (*running) {
217  lock_out.lock();
218  if (size() != 0 || full) {
219  front = PopResult<T>{queue.at(front_index), true};
220  front_index = (front_index + 1) % queue.size();
221  full = false;
222 
223  lock_out.unlock();
224  break;
225  }
226  lock_out.unlock();
227  }
228  return front;
229  }
230 };
231 } // namespace Buffer
232 
240 namespace Pipeline {
241 
250  size_t frame_delay;
251 };
252 
253 // Forward declaration of `Pipeline` for use in `FramerateSettings`
254 class Pipeline;
255 
261  private:
269  std::vector<FramerateSetting> framerate_settings;
270 
275  size_t current_setting;
276 
284  Pipeline* pipeline;
285 
291  void notify_pipeline(void);
292 
293  public:
299  explicit FramerateSettings(Pipeline* pipeline);
300 
307 
312  void increase_framerate(void);
313 
318  void decrease_framerate(void);
319 };
320 
334  uint8_t id;
335  cv::Mat raw_image;
337 };
338 
343 struct RawFrame {
344  uint8_t id;
345  cv::Mat raw_image;
346 };
347 
354 class FrameGenerator : public CppTimer {
355  private:
360  cv::VideoCapture cap;
361 
374  uint8_t id = 0;
375 
382  cv::Mat current_frame;
383 
390  std::mutex mutex;
391 
397  std::condition_variable cv;
398 
410  std::thread thread;
411 
416  void thread_body(void);
417 
427  void timerEvent(void);
428 
433  bool running = true;
434 
435  public:
441  FrameGenerator(void);
442 
449  ~FrameGenerator();
450 
458  void updated_framerate(size_t new_frame_delay);
459 
465  RawFrame next_frame(void);
466 };
467 
474 struct CoreResults {
480  uint8_t id;
481  cv::Mat raw_image;
483 };
484 
494 class Pipeline {
495  private:
503  std::vector<std::thread> threads;
504 
511  bool running;
512 
513  FramerateSettings framerate_settings;
514 
515  PreProcessing::PreProcessor preprocessor;
516  PostProcessing::PostProcessor post_processor;
517  PostureEstimating::PostureEstimator posture_estimator;
518 
519  FrameGenerator frame_generator;
520  Buffer::Buffer<CoreResults> core_results;
521 
526  void core_thread_body(Inference::InferenceCore);
527 
532  void post_processing_thread_body(void);
533 
545  void (*callback)(PostureEstimating::PoseStatus, cv::Mat);
546 
547  public:
548  void updated_framerate(FramerateSetting new_settings);
549 
559  explicit Pipeline(uint8_t num_inference_core_threads,
560  void (*callback)(PostureEstimating::PoseStatus, cv::Mat));
561 
568  ~Pipeline();
569 
577  bool set_confidence_threshold(float threshold);
578 
584  float get_confidence_threshold();
585 
594  float increase_framerate(void);
595 
604  float decrease_framerate(void);
605 
611  float get_framerate(void);
612 
619  void set_ideal_posture(PostureEstimating::Pose pose);
620 
628  bool set_pose_change_threshold(float threshold);
629 
635  float get_pose_change_threshold();
636 };
637 } // namespace Pipeline
638 #endif // SRC_PIPELINE_H_
A synchronising buffer to be used as a communication mechanism between threads.
Definition: pipeline.h:86
PopResult< T > pop()
Pop the oldest element in the queue and return it.
Definition: pipeline.h:214
void push(T frame)
Push a frame to the queue.
Definition: pipeline.h:152
bool try_push(T frame)
Push a frame to the queue (doesn't block if queue is full)
Definition: pipeline.h:182
Buffer(bool *running_ptr, size_t max_size)
Construct a new Buffer object.
Definition: pipeline.h:140
A wrapper to make running inference easier.
Definition: inference_core.h:50
Class to maintain access to the cv::VideoCapture used as the input video stream. This class makes use...
Definition: pipeline.h:354
FrameGenerator(void)
Construct a new Frame Generator object.
Definition: pipeline.cpp:31
RawFrame next_frame(void)
Get the newest frame.
Definition: pipeline.cpp:77
~FrameGenerator()
Destroy the Frame Generator object.
Definition: pipeline.cpp:49
void updated_framerate(size_t new_frame_delay)
Notify the FrameGenerator that the frame rate has changed.
Definition: pipeline.cpp:54
Class to maintain the currently set frame rate and any related settings.
Definition: pipeline.h:260
void decrease_framerate(void)
Decrease the frame rate.
Definition: framerate_settings.cpp:86
void increase_framerate(void)
Increase the frame rate.
Definition: framerate_settings.cpp:93
FramerateSetting get_framerate_setting(void)
Get the currently set FramerateSetting
Definition: framerate_settings.cpp:82
FramerateSettings(Pipeline *pipeline)
Construct a new FramerateSettings object.
Definition: framerate_settings.cpp:23
Process the output of an Inference::InferenceCore
Definition: post_processor.h:51
This class handles representations of the user's pose and calculates any updates to their pose that i...
Definition: posture_estimator.h:243
Pre-process the input image before passing to Inference::InferenceCore
Definition: pre_processor.h:51
Very simple IIR filter.
Wrapper API for the TensorFlow Lite model.
A synchronising buffer and results structure.
Definition: pipeline.h:49
Components of the pipeline at the core of the system.
Definition: framerate_settings.cpp:22
Interface for post processing the output of an Inference::InferenceCore
Interface for representation of user's pose.
Interface for pre processing the input image before passing to Inference::InferenceCore
Result when calling Buffer::pop()
Definition: pipeline.h:64
T value
Actual popped result.
Definition: pipeline.h:65
bool valid
Indicates validity of the result.
Definition: pipeline.h:66
Settings for an IIR filter. Wraps the second-order section coefficients for an IIR filter.
Definition: iir.h:54
Results of running the model for all body parts.
Definition: intermediate_structures.h:199
Contains the id of the frame within the pipeline, as well as the raw image and the results of running...
Definition: pipeline.h:474
Inference::InferenceResults image_results
Definition: pipeline.h:482
uint8_t id
Every frame is assigned a unique id to ensure in-order post processing. This id must be passed throug...
Definition: pipeline.h:480
cv::Mat raw_image
Definition: pipeline.h:481
Parameters relevant to the currently set frame rate.
Definition: pipeline.h:246
size_t frame_delay
Delay in ms that represents the current frame rate.
Definition: pipeline.h:250
IIR::SmoothingSettings smoothing_settings
Definition: pipeline.h:248
Contains the id of the frame within the pipeline, as well as the raw image and the preprocessed_image...
Definition: pipeline.h:328
uint8_t id
Every frame is assigned a unique id to ensure in-order post processing. This id must be passed throug...
Definition: pipeline.h:334
cv::Mat raw_image
Definition: pipeline.h:335
PreProcessing::PreProcessedImage preprocessed_image
Definition: pipeline.h:336
A frame as returned by the FrameGenerator
Definition: pipeline.h:343
uint8_t id
Frame ordering ID.
Definition: pipeline.h:344
cv::Mat raw_image
Raw cv::Mat (OpenCV) image.
Definition: pipeline.h:345
Representation of user's pose for use by the pipeline processing.
Definition: posture_estimator.h:100
The representation of a human's pose, containing all the expected ConnectedJoint
Definition: posture_estimator.h:74
A structure of the pre processed image.
Definition: intermediate_structures.h:85