JeVois  1.8
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
PythonModule.C
Go to the documentation of this file.
1 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2016 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 
20 
21 // ####################################################################################################
22 // ####################################################################################################
23 // ####################################################################################################
24 
26 { }
27 
29 {
30  if (itsInputFrame == nullptr) LFATAL("Internal error");
31  return itsInputFrame->get(casync);
32 }
33 
35 {
36  if (itsInputFrame == nullptr) LFATAL("Internal error");
37  return itsInputFrame->get();
38 }
39 
41 {
42  if (itsInputFrame == nullptr) LFATAL("Internal error");
43  itsInputFrame->done();
44 }
45 
46 cv::Mat jevois::InputFramePython::getCvGRAY1(bool casync) const
47 {
48  if (itsInputFrame == nullptr) LFATAL("Internal error");
49  return itsInputFrame->getCvGRAY(casync);
50 }
51 
53 {
54  if (itsInputFrame == nullptr) LFATAL("Internal error");
55  return itsInputFrame->getCvGRAY();
56 }
57 
58 cv::Mat jevois::InputFramePython::getCvBGR1(bool casync) const
59 {
60  if (itsInputFrame == nullptr) LFATAL("Internal error");
61  return itsInputFrame->getCvBGR(casync);
62 }
63 
65 {
66  if (itsInputFrame == nullptr) LFATAL("Internal error");
67  return itsInputFrame->getCvBGR();
68 }
69 
70 cv::Mat jevois::InputFramePython::getCvRGB1(bool casync) const
71 {
72  if (itsInputFrame == nullptr) LFATAL("Internal error");
73  return itsInputFrame->getCvRGB(casync);
74 }
75 
77 {
78  if (itsInputFrame == nullptr) LFATAL("Internal error");
79  return itsInputFrame->getCvRGB();
80 }
81 
82 cv::Mat jevois::InputFramePython::getCvRGBA1(bool casync) const
83 {
84  if (itsInputFrame == nullptr) LFATAL("Internal error");
85  return itsInputFrame->getCvRGBA(casync);
86 }
87 
89 {
90  if (itsInputFrame == nullptr) LFATAL("Internal error");
91  return itsInputFrame->getCvRGBA();
92 }
93 
94 // ####################################################################################################
95 // ####################################################################################################
96 // ####################################################################################################
98 { }
99 
101 {
102  if (itsOutputFrame == nullptr) LFATAL("Internal error");
103  return itsOutputFrame->get();
104 }
105 
107 {
108  if (itsOutputFrame == nullptr) LFATAL("Internal error");
109  itsOutputFrame->send();
110 }
111 
112 void jevois::OutputFramePython::sendCv1(cv::Mat const & img, int quality) const
113 {
114  if (itsOutputFrame == nullptr) LFATAL("Internal error");
115  itsOutputFrame->sendCv(img, quality);
116 }
117 
118 void jevois::OutputFramePython::sendCv(cv::Mat const & img) const
119 {
120  if (itsOutputFrame == nullptr) LFATAL("Internal error");
121  itsOutputFrame->sendCv(img);
122 }
123 
124 void jevois::OutputFramePython::sendCvGRAY1(cv::Mat const & img, int quality) const
125 {
126  if (itsOutputFrame == nullptr) LFATAL("Internal error");
127  itsOutputFrame->sendCvGRAY(img, quality);
128 }
129 
130 void jevois::OutputFramePython::sendCvGRAY(cv::Mat const & img) const
131 {
132  if (itsOutputFrame == nullptr) LFATAL("Internal error");
133  itsOutputFrame->sendCvGRAY(img);
134 }
135 
136 void jevois::OutputFramePython::sendCvBGR1(cv::Mat const & img, int quality) const
137 {
138  if (itsOutputFrame == nullptr) LFATAL("Internal error");
139  itsOutputFrame->sendCvBGR(img, quality);
140 }
141 
142 void jevois::OutputFramePython::sendCvBGR(cv::Mat const & img) const
143 {
144  if (itsOutputFrame == nullptr) LFATAL("Internal error");
145  itsOutputFrame->sendCvBGR(img);
146 }
147 
148 void jevois::OutputFramePython::sendCvRGB1(cv::Mat const & img, int quality) const
149 {
150  if (itsOutputFrame == nullptr) LFATAL("Internal error");
151  itsOutputFrame->sendCvRGB(img, quality);
152 }
153 
154 void jevois::OutputFramePython::sendCvRGB(cv::Mat const & img) const
155 {
156  if (itsOutputFrame == nullptr) LFATAL("Internal error");
157  itsOutputFrame->sendCvRGB(img);
158 }
159 
160 void jevois::OutputFramePython::sendCvRGBA1(cv::Mat const & img, int quality) const
161 {
162  if (itsOutputFrame == nullptr) LFATAL("Internal error");
163  itsOutputFrame->sendCvRGBA(img, quality);
164 }
165 
166 void jevois::OutputFramePython::sendCvRGBA(cv::Mat const & img) const
167 {
168  if (itsOutputFrame == nullptr) LFATAL("Internal error");
169  itsOutputFrame->sendCvRGBA(img);
170 }
171 
172 void jevois::OutputFramePython::sendScaledCvGRAY1(cv::Mat const & img, int quality) const
173 {
174  if (itsOutputFrame == nullptr) LFATAL("Internal error");
175  itsOutputFrame->sendScaledCvGRAY(img, quality);
176 }
177 
178 void jevois::OutputFramePython::sendScaledCvGRAY(cv::Mat const & img) const
179 {
180  if (itsOutputFrame == nullptr) LFATAL("Internal error");
181  itsOutputFrame->sendScaledCvGRAY(img);
182 }
183 
184 void jevois::OutputFramePython::sendScaledCvBGR1(cv::Mat const & img, int quality) const
185 {
186  if (itsOutputFrame == nullptr) LFATAL("Internal error");
187  itsOutputFrame->sendScaledCvBGR(img, quality);
188 }
189 
190 void jevois::OutputFramePython::sendScaledCvBGR(cv::Mat const & img) const
191 {
192  if (itsOutputFrame == nullptr) LFATAL("Internal error");
193  itsOutputFrame->sendScaledCvBGR(img);
194 }
195 
196 void jevois::OutputFramePython::sendScaledCvRGB1(cv::Mat const & img, int quality) const
197 {
198  if (itsOutputFrame == nullptr) LFATAL("Internal error");
199  itsOutputFrame->sendScaledCvRGB(img, quality);
200 }
201 
202 void jevois::OutputFramePython::sendScaledCvRGB(cv::Mat const & img) const
203 {
204  if (itsOutputFrame == nullptr) LFATAL("Internal error");
205  itsOutputFrame->sendScaledCvRGB(img);
206 }
207 
208 void jevois::OutputFramePython::sendScaledCvRGBA1(cv::Mat const & img, int quality) const
209 {
210  if (itsOutputFrame == nullptr) LFATAL("Internal error");
211  itsOutputFrame->sendScaledCvRGBA(img, quality);
212 }
213 
214 void jevois::OutputFramePython::sendScaledCvRGBA(cv::Mat const & img) const
215 {
216  if (itsOutputFrame == nullptr) LFATAL("Internal error");
217  itsOutputFrame->sendScaledCvRGBA(img);
218 }
219 
220 
221 // ####################################################################################################
222 namespace
223 {
224  // from https://stackoverflow.com/questions/39924912/finding-if-member-function-exists-in-a-boost-pythonobject
225  bool hasattr(boost::python::object & o, char const * name) { return PyObject_HasAttrString(o.ptr(), name); }
226 }
227 
228 // ####################################################################################################
229 // ####################################################################################################
230 // ####################################################################################################
232  jevois::Module(m.modulename)
233 {
234  if (m.ispython == false) LFATAL("Passed video mapping is not for a python module");
235 
236  // Get the python interpreter going:
237  itsMainModule = boost::python::import("__main__");
238  itsMainNamespace = itsMainModule.attr("__dict__");
239 
240  // Import the module. Note that we import the whole directory:
241  std::string const pypath = m.sopath();
242  std::string const pydir = pypath.substr(0, pypath.rfind('/'));
243  std::string const execstr =
244  "import sys\n"
245  "sys.path.append(\"/usr/lib\")\n" // To find libjevois module in /usr/lib
246  "sys.path.append(\"" JEVOIS_OPENCV_PYTHON_PATH "\")\n" // To find cv2 module
247  "sys.path.append(\"" + pydir + "\")\n" +
248  "import " + m.modulename + "\n" +
249  "import importlib\n" +
250  "importlib.reload(" + m.modulename + ")\n"; // reload so we are always fresh if file changed on SD card
251 
252  boost::python::exec(execstr.c_str(), itsMainNamespace, itsMainNamespace);
253 
254  // Create an instance of the python class defined in the module:
255  itsInstance = boost::python::eval((m.modulename + "." + m.modulename + "()").c_str(),
256  itsMainNamespace, itsMainNamespace);
257 }
258 
259 // ####################################################################################################
261 {
262  // Call python module's uninit() function if implemented:
263  if (hasattr(itsInstance, "uninit")) itsInstance.attr("uninit")();
264 }
265 
266 // ####################################################################################################
268 { }
269 
270 // ####################################################################################################
272 {
273  jevois::InputFramePython inframepy(&inframe);
274  jevois::OutputFramePython outframepy(&outframe);
275  itsInstance.attr("process")(boost::ref(inframepy), boost::ref(outframepy));
276 }
277 
278 // ####################################################################################################
280 {
281  jevois::InputFramePython inframepy(&inframe);
282  itsInstance.attr("processNoUSB")(boost::ref(inframepy));
283 }
284 
285 // ####################################################################################################
286 void jevois::PythonModule::parseSerial(std::string const & str, std::shared_ptr<UserInterface> s)
287 {
288  if (hasattr(itsInstance, "parseSerial"))
289  {
290  boost::python::object ret = itsInstance.attr("parseSerial")(str);
291  std::string retstr = boost::python::extract<std::string>(ret);
292  if (retstr.empty() == false) s->writeString(retstr);
293  }
294  else jevois::Module::parseSerial(str, s);
295 }
296 
297 // ####################################################################################################
299 {
300  if (hasattr(itsInstance, "supportedCommands"))
301  {
302  boost::python::object ret = itsInstance.attr("supportedCommands")();
303  std::string retstr = boost::python::extract<std::string>(ret);
304  if (retstr.empty() == false) os << retstr;
306 }
void sendCvGRAY1(cv::Mat const &img, int quality) const
Shorthand to send a GRAY cv::Mat after converting it to the current output format.
Definition: PythonModule.C:124
void sendScaledCvRGBA1(cv::Mat const &img, int quality) const
Shorthand to send a RGBA cv::Mat after scaling/converting it to the current output format...
Definition: PythonModule.C:208
Exception-safe wrapper around a raw camera input frame.
Definition: Module.H:56
Wrapper around OutputFrame to be used by Python.
Definition: PythonModule.H:97
virtual void supportedCommands(std::ostream &os) override
Human-readable description of this Module&#39;s supported custom commands.
Definition: PythonModule.C:298
void sendCvRGB1(cv::Mat const &img, int quality) const
Shorthand to send a RGB cv::Mat after converting it to the current output format. ...
Definition: PythonModule.C:148
cv::Mat getCvRGBA(bool casync=false) const
Shorthand to get the input image as a RGBA cv::Mat and release the raw buffer.
Definition: Module.C:94
void sendScaledCvRGB(cv::Mat const &img, int quality=75) const
Shorthand to send a RGB cv::Mat after converting it to the current output format. ...
Definition: Module.C:213
void sendScaledCvGRAY1(cv::Mat const &img, int quality) const
Shorthand to send a GRAY cv::Mat after scaling/converting it to the current output format...
Definition: PythonModule.C:172
PythonModule(VideoMapping const &m)
Constructor needs the full path to a Python source code file.
Definition: PythonModule.C:231
void sendScaledCvBGR(cv::Mat const &img, int quality=75) const
Shorthand to send a BGR cv::Mat after converting it to the current output format. ...
Definition: Module.C:205
void sendCvRGBA(cv::Mat const &img, int quality=75) const
Shorthand to send a RGBA cv::Mat after converting it to the current output format.
Definition: Module.C:184
void sendCvBGR1(cv::Mat const &img, int quality) const
Shorthand to send a BGR cv::Mat after converting it to the current output format. ...
Definition: PythonModule.C:136
cv::Mat getCvRGBA1(bool casync) const
Shorthand to get the input image as a RGBA cv::Mat and release the raw buffer.
Definition: PythonModule.C:82
virtual void parseSerial(std::string const &str, std::shared_ptr< UserInterface > s) override
Receive a string from a serial port which contains a user command.
Definition: PythonModule.C:286
void send() const
Send an image out over USB to the host computer.
Definition: Module.C:141
void sendCvRGB(cv::Mat const &img, int quality=75) const
Shorthand to send a RGB cv::Mat after converting it to the current output format. ...
Definition: Module.C:176
void sendCv(cv::Mat const &img, int quality=75) const
Shorthand to send a cv::Mat after converting / scaling it to the current output format.
Definition: Module.C:149
RawImage const & get(bool casync=false) const
Get the next captured camera image.
Definition: Module.C:51
void sendCvGRAY(cv::Mat const &img, int quality=75) const
Shorthand to send a GRAY cv::Mat after converting it to the current output format.
Definition: Module.C:161
virtual void supportedCommands(std::ostream &os)
Human-readable description of this Module&#39;s supported custom commands.
Definition: Module.C:263
void sendCv1(cv::Mat const &img, int quality) const
Shorthand to send a cv::Mat after scaling/converting it to the current output format.
Definition: PythonModule.C:112
std::string modulename
Name of the Module that will process this mapping.
Definition: VideoMapping.H:58
void sendCvGRAY(cv::Mat const &img) const
Shorthand to send a GRAY cv::Mat after converting it to the current output format.
Definition: PythonModule.C:130
void sendCvRGB(cv::Mat const &img) const
Shorthand to send a RGB cv::Mat after converting it to the current output format. ...
Definition: PythonModule.C:154
void sendCvRGBA(cv::Mat const &img) const
Shorthand to send a RGBA cv::Mat after converting it to the current output format.
Definition: PythonModule.C:166
RawImage const & get() const
Get the next captured camera image, thin wrapper for default arg value.
Definition: PythonModule.C:34
RawImage const & get1(bool casync) const
Get the next captured camera image, thin wrapper for default arg value.
Definition: PythonModule.C:28
void sendScaledCvRGBA(cv::Mat const &img, int quality=75) const
Shorthand to send a RGBA cv::Mat after converting it to the current output format.
Definition: Module.C:222
void sendCvBGR(cv::Mat const &img, int quality=75) const
Shorthand to send a BGR cv::Mat after converting it to the current output format. ...
Definition: Module.C:169
void send() const
Indicate that user processing is done with the image previously obtained via get() ...
Definition: PythonModule.C:106
A raw image as coming from a V4L2 Camera and/or being sent out to a USB Gadget.
Definition: RawImage.H:110
std::string sopath() const
Return the full absolute path and file name of the module&#39;s .so or .py file.
Definition: VideoMapping.C:30
RawImage const & get() const
Get the next captured camera image.
Definition: PythonModule.C:100
cv::Mat getCvRGB(bool casync=false) const
Shorthand to get the input image as a RGB cv::Mat and release the raw buffer.
Definition: Module.C:85
InputFramePython()=default
Default constructor to keep boost::python happy, object is not operational.
#define o
Definition: Font10x20.C:6
Simple struct to hold video mapping definitions for the processing Engine.
Definition: VideoMapping.H:41
void sendScaledCvBGR1(cv::Mat const &img, int quality) const
Shorthand to send a BGR cv::Mat after scaling/converting it to the current output format...
Definition: PythonModule.C:184
cv::Mat getCvBGR1(bool casync) const
Shorthand to get the input image as a BGR cv::Mat and release the raw buffer.
Definition: PythonModule.C:58
void sendCv(cv::Mat const &img) const
Shorthand to send a cv::Mat after scaling/converting it to the current output format.
Definition: PythonModule.C:118
cv::Mat getCvGRAY() const
Shorthand to get the input image as a GRAY cv::Mat and release the raw buffer.
Definition: PythonModule.C:52
void sendCvBGR(cv::Mat const &img) const
Shorthand to send a BGR cv::Mat after converting it to the current output format. ...
Definition: PythonModule.C:142
Wrapper around InputFrame to be used by Python.
Definition: PythonModule.H:45
cv::Mat getCvGRAY(bool casync=false) const
Shorthand to get the input image as a GRAY cv::Mat and release the raw buffer.
Definition: Module.C:67
void sendScaledCvBGR(cv::Mat const &img) const
Shorthand to send a BGR cv::Mat after scaling/converting it to the current output format...
Definition: PythonModule.C:190
cv::Mat getCvGRAY1(bool casync) const
Shorthand to get the input image as a GRAY cv::Mat and release the raw buffer.
Definition: PythonModule.C:46
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level. ...
Definition: Log.H:212
void sendCvRGBA1(cv::Mat const &img, int quality) const
Shorthand to send a RGBA cv::Mat after converting it to the current output format.
Definition: PythonModule.C:160
virtual void process(InputFrame &&inframe, OutputFrame &&outframe) override
Processing function, version that receives a frame from camera and sends a frame out over USB...
Definition: PythonModule.C:271
void done() const
Indicate that user processing is done with the image previously obtained via get() ...
Definition: PythonModule.C:40
cv::Mat getCvRGB1(bool casync) const
Shorthand to get the input image as a RGB cv::Mat and release the raw buffer.
Definition: PythonModule.C:70
void sendScaledCvRGB(cv::Mat const &img) const
Shorthand to send a RGB cv::Mat after scaling/converting it to the current output format...
Definition: PythonModule.C:202
virtual void parseSerial(std::string const &str, std::shared_ptr< UserInterface > s)
Receive a string from a serial port which contains a user command.
Definition: Module.C:258
OutputFramePython()=default
Default constructor to keep boost::python happy, object is not operational.
Virtual base class for a vision processing module.
Definition: Module.H:335
void sendScaledCvGRAY(cv::Mat const &img, int quality=75) const
Shorthand to send a GRAY cv::Mat after converting it to the current output format.
Definition: Module.C:196
cv::Mat getCvBGR() const
Shorthand to get the input image as a BGR cv::Mat and release the raw buffer.
Definition: PythonModule.C:64
Exception-safe wrapper around a raw image to be sent over USB.
Definition: Module.H:144
void postUninit() override
Optionally call uninit() python module function, if implemented.
Definition: PythonModule.C:260
void sendScaledCvRGBA(cv::Mat const &img) const
Shorthand to send a RGBA cv::Mat after scaling/converting it to the current output format...
Definition: PythonModule.C:214
void sendScaledCvGRAY(cv::Mat const &img) const
Shorthand to send a GRAY cv::Mat after scaling/converting it to the current output format...
Definition: PythonModule.C:178
bool ispython
True if the module is written in Python; affects behavior of sopath() only.
Definition: VideoMapping.H:60
RawImage const & get() const
Get a pre-allocated image so that we can fill the pixel data and later send out over USB using send()...
Definition: Module.C:133
virtual ~PythonModule()
Virtual destructor for safe inheritance.
Definition: PythonModule.C:267
cv::Mat getCvBGR(bool casync=false) const
Shorthand to get the input image as a BGR cv::Mat and release the raw buffer.
Definition: Module.C:76
void done() const
Indicate that user processing is done with the image previously obtained via get() ...
Definition: Module.C:60
void sendScaledCvRGB1(cv::Mat const &img, int quality) const
Shorthand to send a RGB cv::Mat after scaling/converting it to the current output format...
Definition: PythonModule.C:196
cv::Mat getCvRGB() const
Shorthand to get the input image as a RGB cv::Mat and release the raw buffer.
Definition: PythonModule.C:76
cv::Mat getCvRGBA() const
Shorthand to get the input image as a RGBA cv::Mat and release the raw buffer.
Definition: PythonModule.C:88