21#include <linux/videodev2.h>
37#include <opencv2/core/hal/interface.h>
40using namespace std::literals;
41using namespace std::string_literals;
42using namespace std::literals::string_literals;
47 if (fcc == 0)
return "NONE";
50 ret[0] =
static_cast<char>(fcc & 0xff);
51 ret[1] =
static_cast<char>((fcc >> 8) & 0xff);
52 ret[2] =
static_cast<char>((fcc >> 16) & 0xff);
53 ret[3] =
static_cast<char>((fcc >> 24) & 0xff);
63 uchar depth = cvtype & CV_MAT_DEPTH_MASK;
64 uchar chans = 1 + (cvtype >> CV_CN_SHIFT);
68 case CV_8U: r =
"8U";
break;
69 case CV_8S: r =
"8S";
break;
70 case CV_16U: r =
"16U";
break;
71 case CV_16S: r =
"16S";
break;
72 case CV_16F: r =
"16F";
break;
73 case CV_32S: r =
"32S";
break;
74 case CV_32F: r =
"32F";
break;
75 case CV_64F: r =
"64F";
break;
76 default: r =
"User";
break;
82 if (chans < 10) r += (chans +
'0');
else r += std::to_string(chans);
91 uchar depth = cvtype & CV_MAT_DEPTH_MASK;
92 uchar chans = 1 + (cvtype >> CV_CN_SHIFT);
96 case CV_8U: r = 1;
break;
97 case CV_8S: r = 1;
break;
98 case CV_16U: r = 2;
break;
99 case CV_16S: r = 2;
break;
100 case CV_16F: r = 2;
break;
101 case CV_32S: r = 4;
break;
102 case CV_32F: r = 4;
break;
103 case CV_64F: r = 4;
break;
104 default:
LFATAL(
"Unsupported OpenCV type " << cvtype);
113 if (str ==
"BAYER")
return V4L2_PIX_FMT_SRGGB8;
114 else if (str ==
"YUYV")
return V4L2_PIX_FMT_YUYV;
115 else if (str ==
"GREY" || str ==
"GRAY")
return V4L2_PIX_FMT_GREY;
116 else if (str ==
"MJPG")
return V4L2_PIX_FMT_MJPEG;
117 else if (str ==
"RGB565")
return V4L2_PIX_FMT_RGB565;
118 else if (str ==
"BGR24")
return V4L2_PIX_FMT_BGR24;
119 else if (str ==
"RGB3")
return V4L2_PIX_FMT_RGB24;
120 else if (str ==
"BGR3")
return V4L2_PIX_FMT_BGR24;
123 else if (str ==
"RGB24")
return V4L2_PIX_FMT_RGB24;
124 else if (str ==
"RGB32")
return V4L2_PIX_FMT_RGB32;
125 else if (str ==
"UYVY")
return V4L2_PIX_FMT_UYVY;
127 else if (str ==
"BGGR16")
return V4L2_PIX_FMT_SBGGR16;
128 else if (str ==
"GRBG16")
return V4L2_PIX_FMT_SGRBG16;
130 else if (str ==
"NV12")
return V4L2_PIX_FMT_NV12;
131 else if (str ==
"YUV444")
return V4L2_PIX_FMT_YUV444;
136 else if (str ==
"NONE")
return 0;
137 else throw std::runtime_error(
"Invalid pixel format " + str);
145 case V4L2_PIX_FMT_YUYV:
return 2U;
146 case V4L2_PIX_FMT_GREY:
return 1U;
147 case V4L2_PIX_FMT_SRGGB8:
return 1U;
148 case V4L2_PIX_FMT_RGB565:
return 2U;
149 case V4L2_PIX_FMT_MJPEG:
return 2U;
150 case V4L2_PIX_FMT_BGR24:
return 3U;
151 case V4L2_PIX_FMT_RGB24:
return 3U;
152 case V4L2_PIX_FMT_RGB32:
return 4U;
153 case V4L2_PIX_FMT_UYVY:
return 2U;
155 case V4L2_PIX_FMT_SBGGR16:
return 2U;
156 case V4L2_PIX_FMT_SGRBG16:
return 2U;
158 case V4L2_PIX_FMT_NV12:
return 2U;
159 case V4L2_PIX_FMT_YUV444:
return 3U;
176 case V4L2_PIX_FMT_YUYV:
return 0x8000;
177 case V4L2_PIX_FMT_GREY:
return 0;
178 case V4L2_PIX_FMT_SRGGB8:
return 0;
179 case V4L2_PIX_FMT_RGB565:
return 0;
180 case V4L2_PIX_FMT_MJPEG:
return 0;
181 case V4L2_PIX_FMT_BGR24:
return 0;
182 case V4L2_PIX_FMT_RGB24:
return 0;
183 case V4L2_PIX_FMT_RGB32:
return 0;
184 case V4L2_PIX_FMT_UYVY:
return 0x8000;
186 case V4L2_PIX_FMT_SBGGR16:
return 0;
187 case V4L2_PIX_FMT_SGRBG16:
return 0;
189 case V4L2_PIX_FMT_NV12:
return 0;
190 case V4L2_PIX_FMT_YUV444:
return 0x008080;
201 case V4L2_PIX_FMT_YUYV:
return 0x80ff;
202 case V4L2_PIX_FMT_GREY:
return 0xff;
203 case V4L2_PIX_FMT_SRGGB8:
return 0xff;
204 case V4L2_PIX_FMT_RGB565:
return 0xffff;
205 case V4L2_PIX_FMT_MJPEG:
return 0xff;
206 case V4L2_PIX_FMT_BGR24:
return 0xffffff;
207 case V4L2_PIX_FMT_RGB24:
return 0xffffff;
208 case V4L2_PIX_FMT_RGB32:
return 0xffffffff;
209 case V4L2_PIX_FMT_UYVY:
return 0xff80;
211 case V4L2_PIX_FMT_SBGGR16:
return 0xffff;
212 case V4L2_PIX_FMT_SGRBG16:
return 0xffff;
214 case V4L2_PIX_FMT_NV12:
return 0xffff;
215 case V4L2_PIX_FMT_YUV444:
return 0xff8080;
223 unsigned int const winw,
unsigned int const winh,
bool noalias)
225 if (imw == 0 || imh == 0 || winw == 0 || winh == 0)
LFATAL(
"Cannot handle zero width or height");
230 double const facw = double(winw) / imw, fach = double(winh) / imh;
231 double const minfac = std::min(facw, fach);
235 unsigned int const ifac = minfac;
236 imw *= ifac; imh *= ifac;
241 double const maxfac = std::max(facw, fach);
242 unsigned int const ifac = 1.0 / maxfac;
243 imw /= ifac; imh /= ifac;
249 double const ia = double(imw) / double (imh);
250 double const wa = double(winw) / double (winh);
257 imh = (
unsigned int)(imw / ia + 0.4999999);
264 imw = (
unsigned int)(imh * ia + 0.4999999);
270std::vector<std::string>
jevois::split(std::string
const & input, std::string
const & regex)
274 std::regex re(regex);
275 std::sregex_token_iterator first{input.begin(), input.end(), re, -1}, last;
276 return { first, last };
283 if (tokens.empty())
return "";
284 if (tokens.size() == 1)
return tokens[0];
286 std::string ret;
size_t const szm1 = tokens.size() - 1;
288 for (
size_t i = 0; i < szm1; ++i) ret += tokens[i] + delimiter;
297 return (strncmp(str.c_str(), prefix.c_str(), prefix.length()) == 0);
303 std::string ret = str;
304 for (
char & c : ret)
if (std::isspace(c)) c = rep;
311 int idx = str.length() - 1;
312 while (idx >= 0 && std::isspace(str[idx])) --idx;
313 return str.substr(0, idx + 1);
319 size_t idx = str.find(startsep);
320 if (idx == std::string::npos)
return std::string();
321 idx += startsep.size();
323 if (endsep.empty())
return str.substr(idx);
325 size_t idx2 = str.find(endsep, idx);
326 if (idx2 == std::string::npos)
return std::string();
327 return str.substr(idx, idx2 - idx);
334 if (from.empty())
return 0;
336 size_t start_pos = str.find(from);
337 if (start_pos == std::string::npos)
return 0;
339 str.replace(start_pos, from.length(), to);
347 if (from.empty())
return 0;
349 size_t start_pos = 0, n = 0;
350 while((start_pos = str.find(from, start_pos)) != std::string::npos)
352 str.replace(start_pos, from.length(), to);
353 start_pos += to.length();
362std::string
jevois::replaceAll(std::string
const & str, std::string
const & from, std::string
const & to)
364 if (from.empty())
return str;
365 std::string ret = str;
367 size_t start_pos = 0;
368 while((start_pos = ret.find(from, start_pos)) != std::string::npos)
370 ret.replace(start_pos, from.length(), to);
371 start_pos += to.length();
380 std::string ret = str;
381 std::transform(ret.begin(), ret.end(), ret.begin(), [](
unsigned char c) { return std::tolower(c); });
386std::filesystem::path
jevois::absolutePath(std::filesystem::path
const & root, std::filesystem::path
const & path)
389 if (path.empty())
return root;
392 if (path.is_absolute())
return path;
395 if (root.empty())
return path;
405 std::string vsformat(
char const * fmt, va_list ap)
408 if (fmt ==
nullptr || fmt[0] ==
'\0')
return std::string();
415 int const nchars = vsnprintf(buf, bufsize, fmt, ap);
421 LFATAL(
"vsnprintf failed for format '" << fmt <<
"' with bufsize = " << bufsize);
423 else if (nchars >= bufsize)
432 return std::string(&buf[0], nchars);
435 return std::string();
444 std::string result = vsformat(fmt, a);
452#ifdef JEVOIS_PLATFORM_A33
453 std::ofstream ofs(
"/proc/sys/vm/drop_caches");
454 if (ofs.is_open()) ofs <<
"3" << std::endl;
455 else LERROR(
"Failed to flush cache -- ignored");
464 std::array<char, 128> buffer; std::string result;
467 if (errtoo) pip = popen((cmd +
" 2>&1").c_str(),
"r");
else pip = popen(cmd.c_str(),
"r");
468 if (pip ==
nullptr)
LFATAL(
"popen() failed for command [" << cmd <<
']');
469 while (!feof(pip))
if (fgets(buffer.data(), 128, pip) != NULL) result += buffer.data();
471 int status = pclose(pip);
472 if (status == -1 && errno == ECHILD)
LFATAL(
"Could not start command: " << cmd);
473 else if (status)
LFATAL(
"Command [" << cmd <<
"] exited with status " << status <<
":\n\n" << result);
482 else if (secs < 1.0e-3)
return jevois::sformat(
"%.2fus", secs * 1.0e6);
490 if (secs.empty())
return "0.0 +/- 0.0s";
491 double sum = 0.0, sumsq = 0.0;
492 for (
double s : secs) { sum += s; sumsq += s*s; }
493 double const avg = sum / secs.size();
494 double const std = std::sqrt(sumsq/secs.size() - avg*avg);
496 if (avg < 1.0e-6)
return jevois::sformat(
"%.1f +/- %.1f ns", avg * 1.0e9, std * 1.0e9);
497 else if (avg < 1.0e-3)
return jevois::sformat(
"%.1f +/- %.1f us", avg * 1.0e6, std * 1.0e6);
498 else if (avg < 1.0)
return jevois::sformat(
"%.1f +/- %.1f ms", avg * 1.0e3, std * 1.0e3);
505 if (secs < 1.0e-6) ss << secs * 1.0e9 <<
"ns";
506 else if (secs < 1.0e-3) ss << secs * 1.0e6 <<
"us";
507 else if (secs < 1.0) ss << secs * 1.0e3 <<
"ms";
508 else ss << secs <<
's';
529 if (n < 1.0e3) ss << n;
530 else if (n < 1.0e6) ss << n / 1.0e3 <<
'K';
531 else if (n < 1.0e9) ss << n / 1.0e6 <<
'M';
532 else if (n < 1.0e12) ss << n / 1.0e9 <<
'G';
533 else if (n < 1.0e15) ss << n / 1.0e12 <<
'T';
534 else if (n < 1.0e18) ss << n / 1.0e15 <<
'P';
535 else if (n < 1.0e21) ss << n / 1.0e18 <<
'E';
536 else if (n < 1.0e24) ss << n / 1.0e21 <<
'Z';
537 else if (n < 1.0e27) ss << n / 1.0e24 <<
'Y';
544 std::ifstream ifs(fname);
545 if (ifs.is_open() ==
false)
throw std::runtime_error(
"Cannot read file: "s + fname);
547 while (skip-- >= 0) std::getline(ifs, str);
#define JEVOISPRO_FMT_GUI
JeVois-Pro zero-copy display of camera input frame (to be used as output mode in VideoMapping)
#define ISP_V4L2_PIX_FMT_META
Metadata V4L2 format used by Amlogic A311D camera ISP.
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
#define LERROR(msg)
Convenience macro for users to print out console or syslog messages, ERROR level.
std::string join< std::string >(std::vector< std::string > const &tokens, std::string const &delimiter)
Concatenate a vector of string tokens into a string.
unsigned int cvBytesPerPix(unsigned int cvtype)
Return the number of bytes per pixel for a given OpenCV pixel type.
std::string strip(std::string const &str)
Strip white space (including CR, LF, tabs, etc) from the end of a string.
size_t replaceStringFirst(std::string &str, std::string const &from, std::string const &to)
Replace first instance of 'from' with 'to'.
unsigned int strfcc(std::string const &str)
Convert a JeVois video format string to V4L2 four-cc code (V4L2_PIX_FMT_...)
void flushcache()
Flush the caches, may sometimes be useful when running the camera in turbo mode.
std::string num2str(double n)
Report a number with variable multipliers (K, M, G, T, P, E, Z, Y), with precision of 2 decimal point...
std::string extractString(std::string const &str, std::string const &startsep, std::string const &endsep)
Extract a portion of a string between two delimiters.
unsigned int v4l2BytesPerPix(unsigned int fcc)
Return the number of bytes per pixel for a given V4L2_PIX_FMT_...
std::string tolower(std::string const &str)
Convert string to lowercase.
std::string secs2str(double secs)
Report a duration given in seconds with variable units (ns, us, ms, or s), with precision of 2 decima...
std::string getFileString(char const *fname, int skip=0)
Read one line from a file and return it as a string.
std::string cvtypestr(unsigned int cvtype)
Convert cv::Mat::type() code to to a string (e.g., CV_8UC1, CV_32SC3, etc)
std::string system(std::string const &cmd, bool errtoo=true)
Execute a command and grab stdout output to a string.
unsigned int whiteColor(unsigned int fcc)
Return a value that corresponds to white for the given video format.
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.
size_t replaceStringAll(std::string &str, std::string const &from, std::string const &to)
Replace all instances of 'from' with 'to'.
std::filesystem::path absolutePath(std::filesystem::path const &root, std::filesystem::path const &path)
Compute an absolute path from two paths.
bool stringStartsWith(std::string const &str, std::string const &prefix)
Return true if str starts with prefix (including if both strings are equal)
std::string fccstr(unsigned int fcc)
Convert a V4L2 four-cc code (V4L2_PIX_FMT_...) to a 4-char string.
std::vector< std::string > split(std::string const &input, std::string const ®ex="\\s+")
Split string into vector of tokens using a regex to specify what to split on; default regex splits by...
void applyLetterBox(unsigned int &imw, unsigned int &imh, unsigned int const winw, unsigned int const winh, bool noalias)
Apply a letterbox resizing to fit an image into a window.
unsigned int blackColor(unsigned int fcc)
Return a value that corresponds to black for the given video format.
unsigned int v4l2ImageSize(unsigned int fcc, unsigned int width, unsigned int height)
Return the image size in bytes for a given V4L2_PIX_FMT_..., width, height.
std::string replaceAll(std::string const &str, std::string const &from, std::string const &to)
Replace all instances of 'from' with 'to'.