JeVois  1.20
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Pipeline.H
Go to the documentation of this file.
1 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2021 by Laurent Itti, the University of Southern
4 // California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5 //
6 // This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7 // redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8 // Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10 // License for more details. You should have received a copy of the GNU General Public License along with this program;
11 // if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 //
13 // Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14 // Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16 /*! \file */
17 
18 #pragma once
19 
21 #include <jevois/GPU/GUIhelper.H>
22 #include <jevois/Debug/Timer.H>
23 #include <jevois/Types/Enum.H>
24 #include <ovxlib/vsi_nn_pub.h> // for data types and quantization types
25 
26 namespace jevois
27 {
28  class StdModule;
29  class RawImage;
30 
31  namespace dnn
32  {
33  class PreProcessor;
34  class Network;
35  class PostProcessor;
36 
37  namespace pipeline
38  {
39  static jevois::ParameterCategory const ParamCateg("DNN Pipeline Options");
40 
41  //! Parameter \relates jevois::Pipeline
42  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(zooroot, std::string, "Path where to find zoo files (.yml). "
43  "If not absolute, it is relative to this module's path",
44  JEVOIS_SHARE_PATH "/dnn", ParamCateg);
45 
46  //! Parameter \relates jevois::Pipeline
47  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(zoo, std::string, "Filename for neural network zoo file (.yml). "
48  "If not absolute, it is relative to zooroot",
49  "models.yml", ParamCateg);
50  //! Enum \relates jevois::Pipeline
51  JEVOIS_DEFINE_ENUM_CLASS(Filter, (All) (OpenCV) (TPU) (NPU) (VPU) (VPUX) (NPUX) (SPU) (ORT) );
52 
53  //! Parameter \relates jevois::Pipeline
54  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(filter, Filter, "Filter to possibly only show as options in "
55  "the 'pipe' parameter some class of models from the zoo",
56  Filter::All, Filter_Values, ParamCateg);
57 
58  //! Parameter \relates jevois::Pipeline
59  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(pipe, std::string, "Pipeline to use, which should correspond to a "
60  "top-level entry in the zoo file. Network execution types are: OpenCV: "
61  "on CPU, NPU: on JeVois NPU accelerator, TPU: on Coral Edge TPU if "
62  "available, VPU: on MyriadX VPU if available, NPUX: on NPU via TimVX "
63  "OpenCV extension, VPUX: on CPU via ARM-Compute OpenVino emulation "
64  "of VPU, and SPU: on Hailo8 SPU if available.",
65  "", ParamCateg);
66 
67  //! Enum \relates jevois::Pipeline
68  JEVOIS_DEFINE_ENUM_CLASS(PreProc, (Blob) (Python) (Custom) );
69 
70  //! Parameter \relates jevois::Pipeline
71  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(preproc, PreProc, "Pre-Processor to use, usually set automatically "
72  "by selecting a pipeline from the zoo file",
73  PreProc::Blob, PreProc_Values, ParamCateg);
74  //! Enum \relates jevois::Pipeline
75 #ifdef JEVOIS_PRO
76  JEVOIS_DEFINE_ENUM_CLASS(NetType, (OpenCV) (ORT) (NPU) (TPU) (SPU) (Python) (Custom) );
77 #else
78  JEVOIS_DEFINE_ENUM_CLASS(NetType, (OpenCV) (Python) (Custom) );
79 #endif
80 
81  //! Parameter \relates jevois::Pipeline
82  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(nettype, NetType, "Network runtime framework to use, usually set "
83  "automatically by selecting a pipeline from the zoo file",
84  NetType::OpenCV, NetType_Values, ParamCateg);
85  //! Enum \relates jevois::Pipeline
86  JEVOIS_DEFINE_ENUM_CLASS(PostProc, (Classify) (Detect) (Segment) (YuNet) (Python) (Stub) (Custom) );
87 
88  //! Parameter \relates jevois::Pipeline
89  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(postproc, PostProc, "Post-Processor to use, usually set automatically "
90  "by selecting a pipeline from the zoo file",
91  PostProc::Classify, PostProc_Values, ParamCateg);
92  //! Enum \relates jevois::Pipeline
93  JEVOIS_DEFINE_ENUM_CLASS(Processing, (Sync) (Async) );
94 
95  //! Parameter \relates jevois::Pipeline
96  JEVOIS_DECLARE_PARAMETER(processing, Processing, "Type of processing: Sync runs pre-processing, "
97  "network, and post-processing sequentially for every frame. Use for fast "
98  "networks only, otherwise it will slow down the GUI... Async runs the network in "
99  "a thread and should be used for networks slower than the camera framerate.",
100  Processing::Async, Processing_Values, ParamCateg);
101 
102  //! Parameter \relates jevois::Pipeline
103  JEVOIS_DECLARE_PARAMETER(overlay, bool, "Show some pipeline info as an overlay over output or GUI video",
104  true, ParamCateg);
105 
106  //! Parameter \relates jevois::Pipeline
107  JEVOIS_DECLARE_PARAMETER(paramwarn, bool, "Issue warning if parameters are specified in the zoo file for "
108  "a pipeline, but the pipeline's component is not using them. Warnings appear "
109  "in the console when the pipeline is loaded.",
110  true, ParamCateg);
111 
112  //! Parameter \relates jevois::Pipeline
113  JEVOIS_DECLARE_PARAMETER(statsfile, std::string, "Append pre/net/post timing statistics in HTML table format "
114  "to the specified file if not empty. If path is relative, it is to " JEVOIS_SHARE_PATH,
115  "", ParamCateg);
116 
117  //! Parameter \relates jevois::Pipeline
118  JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(benchmark, bool, "Cycle through all networks specified by filter and, "
119  "for each, run it for a while and append pre/net/post timing statistics "
120  "in HTML table format to " JEVOIS_SHARE_PATH "/benchmark.html",
121  false, ParamCateg);
122  }
123 
124  //! Neural processing pipeline
125  /*! A neural processing pipeline in JeVois consists of:
126 
127  - pre-processing an input image to extract one or more blobs used as input tensors to a deep neural network
128  - processing the input blobs through a deep network to obtain output blobs
129  - post-processing the output blobs to display results and send serial messages
130 
131  A pipeline is typically configured by parsing a YAML config file (zoo file) that determines what kind of
132  pre-processing, network, and post-processing to use, and that sets the parameters for those. \ingroup dnn */
133  class Pipeline : public jevois::Component,
134  public jevois::Parameter<pipeline::zooroot, pipeline::zoo, pipeline::filter, pipeline::pipe,
135  pipeline::processing, pipeline::preproc, pipeline::nettype,
136  pipeline::postproc, pipeline::overlay, pipeline::paramwarn,
137  pipeline::statsfile, pipeline::benchmark>
138  {
139  public:
140  //! Constructor
141  Pipeline(std::string const & instance);
142 
143  //! Destructor
144  virtual ~Pipeline();
145 
146  //! Returns true when all three of preproc, net, and postproc are ready
147  bool ready() const;
148 
149  //! Process an input image, send results to serial/image/gui
150  /*! If the network is not ready, no processing will occur. When helper is not null (i.e., using GUI display),
151  hide the information window when idle is true. This function catches all exceptions and reports them. */
152  void process(jevois::RawImage const & inimg, jevois::StdModule * mod,
153  jevois::RawImage * outimg, jevois::OptGUIhelper * helper, bool idle = false);
154 
155  //! Freeze/unfreeze parameters that users should not change while running
156  void freeze(bool doit);
157 
158  //! Set a custom pre-processor
159  /*! To create a custom pre-processor, create a new class that derives from jevois::dnn::PreProcessor and that
160  implements the pure virtual functions of that base class. Then, in your module, you should hold a
161  shared_ptr<jevois::Pipeline> which we will call itsPipeline, and in your constructor you instantiate it and
162  add it as a sub-component of your module (see constructor of \jvmod{DNN} for an example). Then proceed as
163  follows in your constructor or postInit() or parameter callback:
164 
165  \code
166  // Create an instance of our custom pre-processor and attach it as a sub-component of our pipeline
167  auto sptr = itsPipeline->addSubComponent<MyCustomPreProc>("preproc");
168  itsPipeline->setCustomPreProcessor(std::static_pointer_cast<jevois::dnn::PreProcessor>(sptr));
169  \endcode
170 
171  And you are ready to rock. */
172  void setCustomPreProcessor(std::shared_ptr<PreProcessor> pp);
173 
174  // Set a custom network type
175  /*! See doc of setCustomPreProcessor() for instructions, but use the name "network" instead of "preproc". */
176  void setCustomNetwork(std::shared_ptr<Network> n);
177 
178  // Set a custom post-processor
179  /*! See doc of setCustomPreProcessor() for instructions, but use the name "postproc" instead of "preproc". */
180  void setCustomPostProcessor(std::shared_ptr<PostProcessor> pp);
181 
182  protected:
183  void postInit() override;
184  void preUninit() override;
185  std::shared_ptr<PreProcessor> itsPreProcessor;
186  std::shared_ptr<Network> itsNetwork;
187  std::shared_ptr<PostProcessor> itsPostProcessor;
188  void reloadZoo(std::string const & root, std::string const & filt, std::string const & zoofile);
189 
190  private:
191  jevois::TimerOne itsTpre, itsTnet, itsTpost;
192 
193  bool itsZooChanged = false;
194  void onParamChange(pipeline::zooroot const & param, std::string const & val) override;
195  void onParamChange(pipeline::zoo const & param, std::string const & val) override;
196  void onParamChange(pipeline::filter const & param, pipeline::Filter const & val) override;
197  void onParamChange(pipeline::pipe const & param, std::string const & val) override;
198  void onParamChange(pipeline::nettype const & param, pipeline::NetType const & val) override;
199  void onParamChange(pipeline::preproc const & param, pipeline::PreProc const & val) override;
200  void onParamChange(pipeline::postproc const & param, pipeline::PostProc const & val) override;
201  void onParamChange(pipeline::benchmark const & param, bool const & val) override;
202 
203  std::future<std::vector<cv::Mat>> itsNetFut;
204  std::array<std::string, 3> itsProcTimes { "PreProc: -", "Network: -", "PstProc: -" };
205  std::array<double, 3> itsProcSecs { 0.0, 0.0, 0.0 };
206  std::vector<cv::Mat> itsBlobs, itsOuts;
207  std::vector<vsi_nn_tensor_attr_t> itsInputAttrs;
208  std::vector<std::string> itsNetInfo, itsAsyncNetInfo;
209  std::string itsAsyncNetworkTime = "Network: -";
210  double itsAsyncNetworkSecs = 0.0;
211  void showInfo(std::vector<std::string> const & info, jevois::StdModule * mod,
212  jevois::RawImage * outimg, jevois::OptGUIhelper * helper, bool ovl, bool idle);
213  void asyncNetWait();
214  bool checkAsyncNetComplete();
215  double itsSecsSum = 0.0, itsSecsAvg = 0.0;
216  int itsSecsSumNum = 0;
217  bool itsPipeThrew = false;
218  void scanZoo(std::filesystem::path const & zoofile, std::string const & filt, std::vector<std::string> & pipes,
219  std::string const & indent);
220  bool selectPipe(std::string const & zoofile, std::vector<std::string> const & tok);
221  void setZooParam(std::string const & name, std::string const & value, std::string const & zf,
222  cv::FileNode const & node);
223  int itsOutImgY = 0;
224 
225  std::map<std::string, size_t> itsAccelerators;
226  std::vector<double> itsPreStats, itsNetStats, itsPstStats;
227  bool itsStatsWarmup = true;
228  };
229 
230  } // namespace dnn
231 } // namespace jevois
jevois::dnn::Pipeline::preUninit
void preUninit() override
Called before all sub-Components are uninit()ed.
Definition: Pipeline.C:147
jevois::dnn::Pipeline::reloadZoo
void reloadZoo(std::string const &root, std::string const &filt, std::string const &zoofile)
jevois::dnn::Pipeline
Neural processing pipeline.
Definition: Pipeline.H:133
jevois::dnn::Pipeline::setCustomNetwork
void setCustomNetwork(std::shared_ptr< Network > n)
Definition: Pipeline.C:622
JEVOIS_DECLARE_PARAMETER
JEVOIS_DECLARE_PARAMETER(thresh1, double, "First threshold for hysteresis", 50.0, ParamCateg)
jevois::dnn::Pipeline::itsPostProcessor
std::shared_ptr< PostProcessor > itsPostProcessor
Definition: Pipeline.H:187
jevois::Component
A component of a model hierarchy.
Definition: Component.H:181
jevois::dnn::Pipeline::Pipeline
Pipeline(std::string const &instance)
Constructor.
Definition: Pipeline.C:105
jevois::dnn::Pipeline::postInit
void postInit() override
Called after all sub-Components are init()ed.
Definition: Pipeline.C:140
jevois::dnn::Pipeline::ready
bool ready() const
Returns true when all three of preproc, net, and postproc are ready.
Definition: Pipeline.C:684
jevois::RawImage
A raw image as coming from a V4L2 Camera and/or being sent out to a USB Gadget.
Definition: RawImage.H:110
jevois::ParameterCategory
A category to which multiple ParameterDef definitions can belong.
Definition: ParameterDef.H:33
jevois::TimerOne
Simple one-shot timer class.
Definition: Timer.H:69
jevois::dnn::Pipeline::~Pipeline
virtual ~Pipeline()
Destructor.
Definition: Pipeline.C:154
jevois::dnn::Pipeline::itsNetwork
std::shared_ptr< Network > itsNetwork
Definition: Pipeline.H:186
jevois::dnn::Pipeline::setCustomPostProcessor
void setCustomPostProcessor(std::shared_ptr< PostProcessor > pp)
Definition: Pipeline.C:672
jevois::GUIhelper
Helper class to assist modules in creating graphical and GUI elements.
Definition: GUIhelper.H:128
jevois
Definition: Concepts.dox:1
Component.H
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK
JEVOIS_DECLARE_PARAMETER_WITH_CALLBACK(l2grad, bool, "Use more accurate L2 gradient norm if true, L1 if false", false, ParamCateg)
jevois::dnn::Pipeline::freeze
void freeze(bool doit)
Freeze/unfreeze parameters that users should not change while running.
Definition: Pipeline.C:128
jevois::dnn::Pipeline::setCustomPreProcessor
void setCustomPreProcessor(std::shared_ptr< PreProcessor > pp)
Set a custom pre-processor.
Definition: Pipeline.C:546
Timer.H
jevois::dnn::Pipeline::process
void process(jevois::RawImage const &inimg, jevois::StdModule *mod, jevois::RawImage *outimg, jevois::OptGUIhelper *helper, bool idle=false)
Process an input image, send results to serial/image/gui.
Definition: Pipeline.C:705
jevois::JEVOIS_DEFINE_ENUM_CLASS
JEVOIS_DEFINE_ENUM_CLASS(CameraSensor,(any)(imx290)(os08a10)(ar0234))
Enum for different sensor models.
jevois::StdModule
Base class for a module that supports standardized serial messages.
Definition: Module.H:232
GUIhelper.H
jevois::dnn::Pipeline::itsPreProcessor
std::shared_ptr< PreProcessor > itsPreProcessor
Definition: Pipeline.H:185
Enum.H