JeVois  1.22
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Loading...
Searching...
No Matches
PreProcessorPython.C
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
21#include <jevois/Core/Engine.H>
22#include <jevois/DNN/Utils.H>
23
24// ####################################################################################################
25namespace jevois
26{
27 namespace dnn
28 {
30 {
31 public:
33 void loadpy(std::string const & pypath);
35 void freeze(bool doit);
36 std::vector<cv::Mat> process(cv::Mat const & img, bool swaprb, std::vector<vsi_nn_tensor_attr_t> const & attrs,
37 std::vector<cv::Rect> & crops);
38 void report(jevois::StdModule * mod, jevois::RawImage * outimg = nullptr,
39 jevois::OptGUIhelper * helper = nullptr, bool overlay = true, bool idle = false);
40 };
41 }
42}
43
44// ####################################################################################################
45// ####################################################################################################
50
51// ####################################################################################################
56
57// ####################################################################################################
58void jevois::dnn::PreProcessorPythonImpl::loadpy(std::string const & pypath)
59{
60 // Load the code and instantiate the python object:
62 LINFO("Loaded " << pypath);
63
64 // Now that we are fully up and ready, call python module's init() function if implemented:
66}
67
68// ####################################################################################################
69std::vector<cv::Mat> jevois::dnn::PreProcessorPythonImpl::process(cv::Mat const & img, bool swaprb,
70 std::vector<vsi_nn_tensor_attr_t> const & attrs,
71 std::vector<cv::Rect> & crops)
72{
73 if (jevois::python::hasattr(PythonWrapper::pyinst(), "process") == false)
74 LFATAL("No process() method provided. It is required, please add it to your Python pre-processor.");
75
76 // Convert the attrs to a list of strings:
77 boost::python::list alist;
78 for (vsi_nn_tensor_attr_t const & a : attrs) alist.append(jevois::dnn::attrstr(a));
79
80 // Run the python code:
81 boost::python::object ret = PythonWrapper::pyinst().attr("process")(img, swaprb, alist);
82
83 // We expect a tuple with first a vector of blobs, then a vector of crops:
84 if (boost::python::len(ret) != 2)
85 throw std::invalid_argument("Expected two return lists for blobs,crops but received " +
86 std::to_string(boost::python::len(ret)));
87
88 // For the crops, we want cv::Rect but they are not exposing it to python it seems. So let's just accept tuples
89 // ( (x,y), (w,h) )
90#define CROPERR "PreProcessorPython::process: crops should be ( (x,y), (w,h) )"
91
92 crops.clear();
93 boost::python::list cl = boost::python::extract<boost::python::list>(ret[1]);
94 for (ssize_t i = 0; i < boost::python::len(cl); ++i)
95 {
96 boost::python::tuple tup = boost::python::extract<boost::python::tuple>(cl[i]);
97 if (boost::python::len(tup) != 2) throw std::runtime_error(CROPERR);
98 boost::python::tuple xy = boost::python::extract<boost::python::tuple>(tup[0]);
99 if (boost::python::len(xy) != 2) throw std::runtime_error(CROPERR);
100 boost::python::tuple wh = boost::python::extract<boost::python::tuple>(tup[1]);
101 if (boost::python::len(wh) != 2) throw std::runtime_error(CROPERR);
102
103 float x = boost::python::extract<float>(xy[0]);
104 float y = boost::python::extract<float>(xy[1]);
105 float w = boost::python::extract<float>(wh[0]);
106 float h = boost::python::extract<float>(wh[1]);
107 crops.emplace_back(cv::Rect(x, y, w, h));
108 }
109
110 // For the blobs, we have a converter:
111 boost::python::list ml = boost::python::extract<boost::python::list>(ret[0]);
112 return jevois::python::pyListToVec<cv::Mat>(ml);
113}
114
115// ####################################################################################################
117 jevois::OptGUIhelper * helper, bool overlay, bool idle)
118{
119 if (jevois::python::hasattr(PythonWrapper::pyinst(), "report") == false)
120 LFATAL("No process() method provided. It is required, please add it to your Python pre-processor.");
121
122 // default constructed boost::python::object is None on the python side
123 if (outimg)
124 {
125#ifdef JEVOIS_PRO
126 if (helper)
127 {
128 jevois::GUIhelperPython helperpy(helper);
129 PythonWrapper::pyinst().attr("report")(boost::ref(*outimg), boost::ref(helperpy), overlay, idle);
130 }
131 else
132#endif
133 PythonWrapper::pyinst().attr("report")(boost::ref(*outimg), boost::python::object(), overlay, idle);
134 }
135 else
136 {
137#ifdef JEVOIS_PRO
138 if (helper)
139 {
140 jevois::GUIhelperPython helperpy(helper);
141 PythonWrapper::pyinst().attr("report")(boost::python::object(), boost::ref(helperpy), overlay, idle);
142 }
143 else
144#endif
145 PythonWrapper::pyinst().attr("report")(boost::python::object(), boost::python::object(), overlay, idle);
146 }
147
148#ifndef JEVOIS_PRO
149 (void)helper; // avoid compiler warning
150#endif
151}
152
153// ####################################################################################################
154// ####################################################################################################
156 jevois::dnn::PreProcessor(instance)
157{
158 itsImpl = addSubComponent<jevois::dnn::PreProcessorPythonImpl>("pypre");
159}
160
161// ####################################################################################################
164
165// ####################################################################################################
167{
168 // First our own params:
169 pypre::freeze(doit);
170
171 // Then our python params:
172 itsImpl->freeze(doit);
173}
174
175// ####################################################################################################
176void jevois::dnn::PreProcessorPython::onParamChange(jevois::dnn::preprocessor::pypre const &,
177 std::string const & newval)
178{
179 if (newval.empty() == false) itsImpl->loadpy(newval);
180}
181
182// ####################################################################################################
183std::vector<cv::Mat> jevois::dnn::PreProcessorPython::process(cv::Mat const & img, bool swaprb,
184 std::vector<vsi_nn_tensor_attr_t> const & attrs,
185 std::vector<cv::Rect> & crops)
186{ return itsImpl->process(img, swaprb, attrs, crops); }
187
188// ####################################################################################################
190 jevois::OptGUIhelper * helper, bool overlay, bool idle)
191{ itsImpl->report(mod, outimg, helper, overlay, idle); }
192
#define JEVOIS_SHARE_PATH
Base path for shared files (e.g., neural network weights, etc)
Definition Config.H:82
int h
Definition GUIhelper.C:2520
#define CROPERR
A component of a model hierarchy.
Definition Component.H:182
void unRegisterPythonComponent(Component *comp)
Unregister a component as linked to some python code, used by dynamic params created in python.
Definition Engine.C:3016
Wrapper around GUIhelper to be used by Python.
Helper class to assist modules in creating graphical and GUI elements.
Definition GUIhelper.H:133
friend class Component
Allow Component and DynamicParameter to access our registry data, everyone else is locked out.
Helper class to run python code from C++.
void pythonload(std::string const &path)
Init from path if default constructor was used.
boost::python::object & pyinst()
Get the python class pyinst, or throw if construction error occurred (e.g., file not found)
A raw image as coming from a V4L2 Camera and/or being sent out to a USB Gadget.
Definition RawImage.H:111
Base class for a module that supports standardized serial messages.
Definition Module.H:234
void report(jevois::StdModule *mod, jevois::RawImage *outimg=nullptr, jevois::OptGUIhelper *helper=nullptr, bool overlay=true, bool idle=false)
std::vector< cv::Mat > process(cv::Mat const &img, bool swaprb, std::vector< vsi_nn_tensor_attr_t > const &attrs, std::vector< cv::Rect > &crops)
void loadpy(std::string const &pypath)
void report(jevois::StdModule *mod, jevois::RawImage *outimg=nullptr, jevois::OptGUIhelper *helper=nullptr, bool overlay=true, bool idle=false) override
Report what happened in last process() to console/output video/GUI.
std::shared_ptr< PreProcessorPythonImpl > itsImpl
std::vector< cv::Mat > process(cv::Mat const &img, bool swaprb, std::vector< vsi_nn_tensor_attr_t > const &attrs, std::vector< cv::Rect > &crops) override
Extract blobs from input image.
virtual ~PreProcessorPython()
Destructor.
void freeze(bool doit) override
Freeze/unfreeze parameters that users should not change while running.
PreProcessorPython(std::string const &instance)
Constructor.
void onParamChange(preprocessor::pypre const &param, std::string const &newval) override
Pre-Processor for neural network pipeline.
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
Definition Log.H:230
#define LINFO(msg)
Convenience macro for users to print out console or syslog messages, INFO level.
Definition Log.H:194
std::string attrstr(vsi_nn_tensor_attr_t const &attr)
Get a string describing the specs of a tensor, including quantification specs (not provided by shapes...
Definition Utils.C:536
bool hasattr(boost::python::object &o, char const *name)
Check whether a boost::python::object has an attribute.
Main namespace for all JeVois classes and functions.
Definition Concepts.dox:2