24#include <opencv2/imgproc/imgproc.hpp>
41{
LFATAL(
"Not implemented in this module"); }
45{
LFATAL(
"Not implemented in this module"); }
50{
LFATAL(
"Not implemented in this module, and only available on JeVois-Pro"); }
57 if (e ==
nullptr)
LFATAL(
"My parent is not Engine -- CANNOT SEND SERIAL");
64{
throw std::runtime_error(
"Unsupported command [" + str +
']'); }
68{ os <<
"None" << std::endl; }
85 switch(serstamp::get())
87 case jevois::modul::SerStamp::None:
90 case jevois::modul::SerStamp::Frame:
91 ret = std::to_string(frameNum());
94 case jevois::modul::SerStamp::Time:
96 std::time_t t = std::time(
nullptr);
char str[100];
97 std::strftime(str,
sizeof(str),
"%T", std::localtime(&t));
98 ret = std::string(str);
102 case jevois::modul::SerStamp::FrameTime:
104 std::time_t t = std::time(
nullptr);
char str[100];
105 std::strftime(str,
sizeof(str),
"%T", std::localtime(&t));
106 ret = std::to_string(frameNum()) +
'/' + std::string(str);
110 case jevois::modul::SerStamp::FrameDateTime:
112 std::time_t t = std::time(
nullptr);
char str[100];
113 std::strftime(str,
sizeof(str),
"%F/%T", std::localtime(&t));
114 ret = std::to_string(frameNum()) +
'/' + std::string(str);
119 if (ret.empty() ==
false) ret +=
' ';
125 std::string
const & extra)
128 float const eps = std::pow(10.0F, -
float(serprec::get()));
134 sendSerialStd1Dx(x, size,
id, extra);
141 std::ostringstream oss; oss << std::fixed << std::setprecision(serprec::get());
147 switch (serstyle::get())
149 case jevois::modul::SerStyle::Terse:
153 case jevois::modul::SerStyle::Normal:
156 oss << x <<
' ' << size;
159 case jevois::modul::SerStyle::Detail:
160 case jevois::modul::SerStyle::Fine:
163 oss << x - 0.5F * size <<
' ' << x + 0.5F * size;
164 if (extra.empty() ==
false) oss <<
' ' << extra;
169 sendSerial(oss.str());
174 std::string
const & extra)
177 float const eps = std::pow(10.0F, -
float(serprec::get()));
182 sendSerialStd1Dy(y, size,
id, extra);
189 std::ostringstream oss; oss << std::fixed << std::setprecision(serprec::get());
195 switch (serstyle::get())
197 case jevois::modul::SerStyle::Terse:
201 case jevois::modul::SerStyle::Normal:
204 oss << y <<
' ' << size;
207 case jevois::modul::SerStyle::Detail:
208 case jevois::modul::SerStyle::Fine:
211 oss << y - 0.5F * size <<
' ' << y + 0.5F * size;
212 if (extra.empty() ==
false) oss <<
' ' << extra;
217 sendSerial(oss.str());
222 std::string
const &
id, std::string
const & extra)
225 float const eps = std::pow(10.0F, -
float(serprec::get()));
231 sendSerialStd2D(x, y, w,
h,
id, extra);
235 std::string
const & extra)
238 std::ostringstream oss; oss << std::fixed << std::setprecision(serprec::get());
244 switch (serstyle::get())
246 case jevois::modul::SerStyle::Terse:
247 oss <<
"T2 " << x <<
' ' << y;
250 case jevois::modul::SerStyle::Normal:
253 oss << x <<
' ' << y <<
' ' << w <<
' ' <<
h;
256 case jevois::modul::SerStyle::Detail:
259 oss << x - 0.5F * w <<
' ' << y - 0.5F *
h <<
' ';
260 oss << x + 0.5F * w <<
' ' << y - 0.5F *
h <<
' ';
261 oss << x + 0.5F * w <<
' ' << y + 0.5F *
h <<
' ';
262 oss << x + 0.5F * w <<
' ' << y - 0.5F *
h;
263 if (extra.empty() ==
false) oss <<
' ' << extra;
266 case jevois::modul::SerStyle::Fine:
270 oss << x - 0.5F * w <<
' ' << y - 0.5F *
h <<
' ';
271 oss << x + 0.5F * w <<
' ' << y - 0.5F *
h <<
' ';
272 oss << x + 0.5F * w <<
' ' << y + 0.5F *
h <<
' ';
273 oss << x + 0.5F * w <<
' ' << y - 0.5F *
h;
274 if (extra.empty() ==
false) oss <<
' ' << extra;
279 sendSerial(oss.str());
285 std::string
const &
id, std::string
const & extra)
288 switch (serstyle::get())
290 case jevois::modul::SerStyle::Terse:
293 float cx = 0.0F, cy = 0.0F;
294 for (cv::Point2f
const p : points) { cx += p.x; cy += p.y; }
295 if (points.size()) { cx /= points.size(); cy /= points.size(); }
296 sendSerialImg2D(camw, camh, cx, cy, 0.0F, 0.0F,
id, extra);
300 case jevois::modul::SerStyle::Normal:
303 cv::Rect r = cv::boundingRect(points);
304 sendSerialImg2D(camw, camh, r.x + 0.5F * r.width, r.y + 0.5F * r.height, r.width, r.height,
id, extra);
308 case jevois::modul::SerStyle::Detail:
311 cv::RotatedRect r = cv::minAreaRect(points);
314 unsigned int const prec = serprec::get();
float const eps = std::pow(10.0F, -
float(prec));
315 std::ostringstream oss; oss << std::fixed << std::setprecision(prec);
323 cv::Point2f corners[4];
328 for (
int i = 0; i < 4; ++i)
330 float x = corners[i].x, y = corners[i].y;
332 oss <<
' ' << x <<
' ' << y;
334 if (extra.empty() ==
false) oss <<
' ' << extra;
337 sendSerial(oss.str());
341 case jevois::modul::SerStyle::Fine:
344 unsigned int const prec = serprec::get();
float const eps = std::pow(10.0F, -
float(prec));
345 std::ostringstream oss; oss << std::fixed << std::setprecision(prec);
353 oss << points.size();
355 for (cv::Point2f
const p : points)
357 float x = p.x, y = p.y;
359 oss <<
' ' << x <<
' ' << y;
361 if (extra.empty() ==
false) oss <<
' ' << extra;
364 sendSerial(oss.str());
375 std::string
const &
id, std::string
const & extra);
378 std::string
const &
id, std::string
const & extra);
381 std::string
const &
id, std::string
const & extra);
386 float q1,
float q2,
float q3,
float q4,
387 std::string
const &
id, std::string
const & extra)
390 std::ostringstream oss; oss << std::fixed << std::setprecision(serprec::get());
396 switch (serstyle::get())
398 case jevois::modul::SerStyle::Terse:
399 oss <<
"T3 " << x <<
' ' << y <<
' ' << z;
402 case jevois::modul::SerStyle::Normal:
405 oss << x <<
' ' << y <<
' ' << z <<
' ' << w <<
' ' <<
h <<
' ' << d;
408 case jevois::modul::SerStyle::Detail:
411 oss << x <<
' ' << y <<
' ' << z <<
' ' << w <<
' ' <<
h <<
' ' << d <<
' '
412 << q1 <<
' ' << q2 <<
' ' << q3 <<
' ' << q4;
413 if (extra.empty() ==
false) oss <<
' ' << extra;
416 case jevois::modul::SerStyle::Fine:
420 oss << x - 0.5F * w <<
' ' << y - 0.5F *
h <<
' ' << z - 0.5F * d <<
' ';
421 oss << x + 0.5F * w <<
' ' << y - 0.5F *
h <<
' ' << z - 0.5F * d <<
' ';
422 oss << x + 0.5F * w <<
' ' << y + 0.5F *
h <<
' ' << z - 0.5F * d <<
' ';
423 oss << x + 0.5F * w <<
' ' << y - 0.5F *
h <<
' ' << z - 0.5F * d <<
' ';
424 oss << x - 0.5F * w <<
' ' << y - 0.5F *
h <<
' ' << z + 0.5F * d <<
' ';
425 oss << x + 0.5F * w <<
' ' << y - 0.5F *
h <<
' ' << z + 0.5F * d <<
' ';
426 oss << x + 0.5F * w <<
' ' << y + 0.5F *
h <<
' ' << z + 0.5F * d <<
' ';
427 oss << x + 0.5F * w <<
' ' << y - 0.5F *
h <<
' ' << z + 0.5F * d <<
' ';
428 if (extra.empty() ==
false) oss <<
' ' << extra;
433 sendSerial(oss.str());
438 std::string
const & extra)
441 switch (serstyle::get())
443 case jevois::modul::SerStyle::Terse:
446 cv::Point3f cg(0.0F, 0.0F, 0.0F);
447 for (cv::Point3f
const & p : points) cg += p;
448 if (points.size()) { cg.x /= points.size(); cg.y /= points.size(); cg.z /= points.size(); }
449 sendSerialStd3D(cg.x, cg.y, cg.z, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F,
id, extra);
453 case jevois::modul::SerStyle::Normal:
456 cv::Point3f cg(0.0F, 0.0F, 0.0F), pmin(1e30F, 1e30F, 1e30F), pmax(-1e30F, -1e30F, -1e30F);
457 for (cv::Point3f
const & p : points)
460 if (p.x < pmin.x) pmin.x = p.x;
461 if (p.y < pmin.y) pmin.y = p.y;
462 if (p.z < pmin.z) pmin.z = p.z;
463 if (p.x > pmax.x) pmax.x = p.x;
464 if (p.y > pmax.y) pmax.y = p.y;
465 if (p.z > pmax.z) pmax.z = p.z;
467 if (points.size()) { cg.x /= points.size(); cg.y /= points.size(); cg.z /= points.size(); }
468 sendSerialStd3D(cg.x, cg.y, cg.z, pmax.x - pmin.x, pmax.y - pmin.y, pmax.z - pmin.z, 0.0F, 0.0F, 0.0F, 0.0F,
473 case jevois::modul::SerStyle::Detail:
476 cv::Point3f cg(0.0F, 0.0F, 0.0F), pmin(1e30F, 1e30F, 1e30F), pmax(-1e30F, -1e30F, -1e30F);
477 for (cv::Point3f
const & p : points)
480 if (p.x < pmin.x) pmin.x = p.x;
481 if (p.y < pmin.y) pmin.y = p.y;
482 if (p.z < pmin.z) pmin.z = p.z;
483 if (p.x > pmax.x) pmax.x = p.x;
484 if (p.y > pmax.y) pmax.y = p.y;
485 if (p.z > pmax.z) pmax.z = p.z;
487 if (points.size()) { cg.x /= points.size(); cg.y /= points.size(); cg.z /= points.size(); }
489 sendSerialStd3D(cg.x, cg.y, cg.z, pmax.x - pmin.x, pmax.y - pmin.y, pmax.z - pmin.z, 0.0F, 0.0F, 0.0F, 1.0F,
494 case jevois::modul::SerStyle::Fine:
497 unsigned int const prec = serprec::get();
498 std::ostringstream oss; oss << std::fixed << std::setprecision(prec);
506 oss << points.size();
508 for (cv::Point3f
const & p : points) oss <<
' ' << p.x <<
' ' << p.y <<
' ' << p.z;
509 if (extra.empty() ==
false) oss <<
' ' << extra;
512 sendSerial(oss.str());
521 jevois::modul::SerMark
const m = sermark::get();
522 if (m == jevois::modul::SerMark::None || m == jevois::modul::SerMark::Stop)
return;
523 sendSerial(getStamp() +
"MARK START");
529 jevois::modul::SerMark
const m = sermark::get();
530 if (m == jevois::modul::SerMark::None || m == jevois::modul::SerMark::Start)
return;
531 sendSerial(getStamp() +
"MARK STOP");
537 if (res.empty())
return;
540 std::ostringstream oss; oss << std::fixed << std::setprecision(serprec::get());
546 switch (serstyle::get())
548 case jevois::modul::SerStyle::Terse:
552 case jevois::modul::SerStyle::Normal:
556 case jevois::modul::SerStyle::Detail:
561 case jevois::modul::SerStyle::Fine:
568 sendSerial(oss.str());
573 std::vector<ObjReco>
const & res)
575 if (res.empty())
return;
577 std::string best, extra; std::string * ptr = &best;
578 std::string fmt =
"%s:%." + std::to_string(serprec::get()) +
"f";
580 for (
auto const & r : res)
582 switch (serstyle::get())
584 case jevois::modul::SerStyle::Terse:
591 if (ptr == &extra) (*ptr) +=
' ';
596 if (extra.empty() ==
false) extra = extra.substr(0, extra.length() - 1);
598 sendSerialImg2D(camw, camh, x, y, w,
h, best, extra);
610 std::vector<jevois::ObjReco>
const & res = det.
reco;
611 if (res.empty())
return;
613 std::string best, extra; std::string * ptr = &best;
614 std::string fmt =
"%s:%." + std::to_string(serprec::get()) +
"f";
616 for (
auto const & r : res)
618 switch (serstyle::get())
620 case jevois::modul::SerStyle::Terse:
627 if (ptr == &extra) (*ptr) +=
' ';
632 if (extra.empty() ==
false) extra = extra.substr(0, extra.length() - 1);
634 std::vector<cv::Point2f> pts; det.
rect.points(pts);
635 sendSerialContour2D(camw, camh, pts, best, extra);
A component of a model hierarchy.
JeVois processing engine - gets images from camera sensor, processes them, and sends results over USB...
void sendSerial(std::string const &str, bool islog=false)
Send a string to all serial ports.
Helper class to assist modules in creating graphical and GUI elements.
Virtual base class for a vision processing module.
virtual void sendSerial(std::string const &str)
Send a string over the 'serout' serial port.
virtual void supportedCommands(std::ostream &os)
Human-readable description of this Module's supported custom commands.
virtual void parseSerial(std::string const &str, std::shared_ptr< UserInterface > s)
Receive a string from a serial port which contains a user command.
virtual ~Module()
Virtual destructor for safe inheritance.
virtual void process(InputFrame &&inframe, OutputFrame &&outframe)
Processing function, version that receives a frame from camera and sends a frame out over USB.
Exception-safe wrapper around a raw image to be sent over USB.
void sendSerialStd1Dx(float x, float size=0.0F, std::string const &id="", std::string const &extra="")
Send standardized 1D message for a standardized X coordinate.
void sendSerialObjDetImg2D(unsigned int camw, unsigned int camh, float x, float y, float w, float h, std::vector< ObjReco > const &res)
Send a standardized object detection + recognition message.
virtual ~StdModule()
Virtual destructor for safe inheritance.
std::string getStamp() const
Get a string with the frame/date/time stamp in it, depending on serstamp parameter.
void sendSerialStd3D(float x, float y, float z, float w=0.0F, float h=0.0F, float d=0.0F, float q1=0.0F, float q2=0.0F, float q3=0.0f, float q4=0.0F, std::string const &id="", std::string const &extra="")
Send standardized 3D message.
void sendSerialObjReco(std::vector< ObjReco > const &res)
Send a standardized object recognition message.
void sendSerialImg2D(unsigned int camw, unsigned int camh, float x, float y, float w=0.0F, float h=0.0F, std::string const &id="", std::string const &extra="")
Send standardized 2D message for image coordinates.
void sendSerialStd1Dy(float y, float size=0.0F, std::string const &id="", std::string const &extra="")
Send standardized 1D message for a standardized Y coordinate.
void sendSerialMarkStop()
Send a message MARK STOP to indicate the end of processing.
StdModule(std::string const &instance)
Constructor.
void sendSerialStd2D(float x, float y, float w=0.0F, float h=0.0F, std::string const &id="", std::string const &extra="")
Send standardized 2D message for standardized coordinates.
void sendSerialImg1Dx(unsigned int camw, float x, float size=0.0F, std::string const &id="", std::string const &extra="")
Send standardized 1D message for an X image coordinate.
void sendSerialImg1Dy(unsigned int camh, float y, float size=0.0F, std::string const &id="", std::string const &extra="")
Send standardized 1D message for an Y image coordinate.
void sendSerialMarkStart()
Send a message MARK START to indicate the beginning of processing.
void sendSerialContour2D(unsigned int camw, unsigned int camh, std::vector< cv::Point_< T > > points, std::string const &id="", std::string const &extra="")
Send standardized 2D message for polygons in image coordinates.
void imgToStdX(float &x, unsigned int const width, float const eps=0.1F)
Transform X coordinate in-place from camera to standardized, using given image width and height.
void imgToStdY(float &y, unsigned int const height, float const eps=0.1F)
Transform Y coordinate in-place from camera to standardized, using given image width and height.
void imgToStd(float &x, float &y, RawImage const &camimg, float const eps=0.1F)
Transform coordinates in-place from camera to standardized, using a RawImage to establish image size.
void imgToStdSize(float &w, float &h, unsigned int const width, unsigned int const height, float const eps=0.1F)
Transform size in-place from camera to standardized, using given image width and height.
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
std::string sformat(char const *fmt,...) __attribute__((format(__printf__
Create a string using printf style arguments.
std::string replaceWhitespace(std::string const &str, char rep='_')
Replace white space characters in a string with underscore (default) or another character.
Main namespace for all JeVois classes and functions.
A trivial struct to store object detection results, for oriented bounding boxes (OBB)
std::vector< ObjReco > reco
Recognized classes with their scores.
cv::RotatedRect rect
Oriented bounding box.
A trivial struct to store object detection results, for standard (straight up) bounding boxes.
std::vector< ObjReco > reco
Recognized classes with their scores.