21 #include <linux/videodev2.h>
37 #include <opencv2/core/hal/interface.h>
40 using namespace std::literals;
41 using namespace std::string_literals;
42 using 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);
270 std::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 };
280 std::string
jevois::join(std::vector<std::string>
const & strings, std::string
const & delimiter)
282 if (strings.empty())
return "";
283 if (strings.size() == 1)
return strings[0];
285 std::string ret;
size_t const szm1 = strings.size() - 1;
287 for (
size_t i = 0; i < szm1; ++i) ret += strings[i] + delimiter;
288 ret += strings[szm1];
296 return (strncmp(str.c_str(), prefix.c_str(), prefix.length()) == 0);
302 std::string ret = str;
303 for (
char & c : ret)
if (std::isspace(c)) c = rep;
310 int idx = str.length() - 1;
311 while (idx >= 0 && std::isspace(str[idx])) --idx;
312 return str.substr(0, idx + 1);
316 std::string
jevois::extractString(std::string
const & str, std::string
const & startsep, std::string
const & endsep)
318 size_t idx = str.find(startsep);
319 if (idx == std::string::npos)
return std::string();
320 idx += startsep.size();
322 if (endsep.empty())
return str.substr(idx);
324 size_t idx2 = str.find(endsep, idx);
325 if (idx2 == std::string::npos)
return std::string();
326 return str.substr(idx, idx2 - idx);
333 if (from.empty())
return 0;
335 size_t start_pos = str.find(from);
336 if (start_pos == std::string::npos)
return 0;
338 str.replace(start_pos, from.length(), to);
346 if (from.empty())
return 0;
348 size_t start_pos = 0, n = 0;
349 while((start_pos = str.find(from, start_pos)) != std::string::npos)
351 str.replace(start_pos, from.length(), to);
352 start_pos += to.length();
361 std::string
jevois::replaceAll(std::string
const & str, std::string
const & from, std::string
const & to)
363 if (from.empty())
return str;
364 std::string ret = str;
366 size_t start_pos = 0;
367 while((start_pos = ret.find(from, start_pos)) != std::string::npos)
369 ret.replace(start_pos, from.length(), to);
370 start_pos += to.length();
379 std::string ret = str;
380 std::transform(ret.begin(), ret.end(), ret.begin(), [](
unsigned char c) { return std::tolower(c); });
385 std::filesystem::path
jevois::absolutePath(std::filesystem::path
const & root, std::filesystem::path
const & path)
388 if (path.empty())
return root;
391 if (path.is_absolute())
return path;
394 if (root.empty())
return path;
404 std::string vsformat(
char const * fmt, va_list ap)
407 if (fmt ==
nullptr || fmt[0] ==
'\0')
return std::string();
414 int const nchars = vsnprintf(buf, bufsize, fmt, ap);
420 LFATAL(
"vsnprintf failed for format '" << fmt <<
"' with bufsize = " << bufsize);
422 else if (nchars >= bufsize)
431 return std::string(&buf[0], nchars);
434 return std::string();
443 std::string result = vsformat(fmt, a);
451 #ifdef JEVOIS_PLATFORM_A33
452 std::ofstream ofs(
"/proc/sys/vm/drop_caches");
453 if (ofs.is_open()) ofs <<
"3" << std::endl;
454 else LERROR(
"Failed to flush cache -- ignored");
463 std::array<char, 128> buffer; std::string result;
466 if (errtoo) pip = popen((cmd +
" 2>&1").c_str(),
"r");
else pip = popen(cmd.c_str(),
"r");
467 if (pip ==
nullptr)
LFATAL(
"popen() failed for command [" << cmd <<
']');
468 while (!feof(pip))
if (fgets(buffer.data(), 128, pip) != NULL) result += buffer.data();
470 int status = pclose(pip);
471 if (status == -1 && errno == ECHILD)
LFATAL(
"Could not start command: " << cmd);
472 else if (status)
LFATAL(
"Command [" << cmd <<
"] exited with status " << status <<
":\n\n" << result);
481 else if (secs < 1.0e-3)
return jevois::sformat(
"%.2fus", secs * 1.0e6);
489 if (secs.empty())
return "0.0 +/- 0.0s";
490 double sum = 0.0, sumsq = 0.0;
491 for (
double s : secs) { sum += s; sumsq += s*s; }
492 double const avg = sum / secs.size();
493 double const std = std::sqrt(sumsq/secs.size() - avg*avg);
495 if (avg < 1.0e-6)
return jevois::sformat(
"%.1f +/- %.1f ns", avg * 1.0e9, std * 1.0e9);
496 else if (avg < 1.0e-3)
return jevois::sformat(
"%.1f +/- %.1f us", avg * 1.0e6, std * 1.0e6);
497 else if (avg < 1.0)
return jevois::sformat(
"%.1f +/- %.1f ms", avg * 1.0e3, std * 1.0e3);
504 if (secs < 1.0e-6) ss << secs * 1.0e9 <<
"ns";
505 else if (secs < 1.0e-3) ss << secs * 1.0e6 <<
"us";
506 else if (secs < 1.0) ss << secs * 1.0e3 <<
"ms";
507 else ss << secs <<
's';
528 if (n < 1.0e3) ss << n;
529 else if (n < 1.0e6) ss << n / 1.0e3 <<
'K';
530 else if (n < 1.0e9) ss << n / 1.0e6 <<
'M';
531 else if (n < 1.0e12) ss << n / 1.0e9 <<
'G';
532 else if (n < 1.0e15) ss << n / 1.0e12 <<
'T';
533 else if (n < 1.0e18) ss << n / 1.0e15 <<
'P';
534 else if (n < 1.0e21) ss << n / 1.0e18 <<
'E';
535 else if (n < 1.0e24) ss << n / 1.0e21 <<
'Z';
536 else if (n < 1.0e27) ss << n / 1.0e24 <<
'Y';
543 std::ifstream ifs(fname);
544 if (ifs.is_open() ==
false)
throw std::runtime_error(
"Cannot read file: "s + fname);
546 while (skip-- >= 0) std::getline(ifs, str);