46#include <opencv2/core/utils/filesystem.hpp>
62 void set(cv::FileNode
const & item, std::string
const & zf, cv::FileNode
const & node)
64 std::string k = item.name();
68 case cv::FileNode::INT: v = std::to_string((
int)item);
break;
69 case cv::FileNode::REAL: v = std::to_string((
float)item);
break;
70 case cv::FileNode::STRING: v = (std::string)item;
break;
73 LFATAL(
"Invalid global zoo parameter " << k <<
" type " << item.type() <<
" in " << zf);
75 LFATAL(
"Invalid zoo parameter " << k <<
" type " << item.type() <<
" in " << zf <<
" node " << node.name());
79 for (
auto & p : params) if (p.first == k) { p.second = v;
return; }
80 params.emplace_back(std::make_pair(k, v));
85 std::string pget(cv::FileNode & item, std::string
const & subname)
87 std::string
const v = (std::string)item[subname];
88 if (v.empty() ==
false)
return v;
89 for (
auto const & p : params) if (p.first == subname) return p.second;
95 void unset(std::string
const & name)
97 for (
auto itr = params.begin(); itr != params.end(); ++itr)
98 if (itr->first == name) { params.erase(itr);
return; }
102 std::vector<std::pair<std::string , std::string >> params;
108 jevois::
Component(instance), itsTpre(
"PreProc"), itsTnet(
"Network"), itsTpost(
"PstProc")
114 itsAccelerators[
"OpenCV"] = 1;
115 itsAccelerators[
"ORT"] = 1;
116 itsAccelerators[
"Python"] = 1;
117#ifdef JEVOIS_PLATFORM_PRO
118 itsAccelerators[
"VPUX"] = 1;
120 itsAccelerators[
"NPUX"] = 1;
123 itsAccelerators[
"NPU"] <<
" JeVois-Pro NPUs, " <<
124 itsAccelerators[
"SPU"] <<
" Hailo8 SPUs, " <<
125 itsAccelerators[
"TPU"] <<
" Coral TPUs, " <<
126 itsAccelerators[
"VPU"] <<
" Myriad-X VPUs.");
132 preproc::freeze(doit);
133 nettype::freeze(doit);
134 postproc::freeze(doit);
136 if (itsPreProcessor) itsPreProcessor->freeze(doit);
137 if (itsNetwork) itsNetwork->freeze(doit);
138 if (itsPostProcessor) itsPostProcessor->freeze(doit);
166 return pp->latestRecognitions();
168 LFATAL(
"Cannot get recognition results if post-processor is not of type Classify");
175 return pp->latestDetections();
178 return pp->latestDetections();
180 LFATAL(
"Cannot get detection results if post-processor is not of type Detect or Pose");
187 return pp->latestDetectionsOBB();
189 LFATAL(
"Cannot get detection results if post-processor is not of type DetectOBB");
196 return pp->latestSkeletons();
198 LFATAL(
"Cannot get pose skeleton results if post-processor is not of type Pose");
205 if (itsNetFut.valid())
208 if (itsNetFut.wait_for(std::chrono::seconds(5)) == std::future_status::timeout)
209 LERROR(
"Still waiting for network to finish running...");
213 try { itsNetFut.get(); }
catch (...) { }
223 if (val != filter::get()) itsZooChanged =
true;
231 if (val.empty() ==
false && val != zooroot::get()) itsZooChanged =
true;
239 statsfile::set(
"benchmark.html");
240 statsfile::freeze(
true);
244 statsfile::freeze(
false);
253 if (val != extramodels::get()) itsZooChanged =
true;
260 itsZooChanged =
false;
263 std::vector<std::string> pipes;
265 LINFO(
"Found a total of " << pipes.size() <<
" valid pipelines.");
268 if (pipes.empty())
LFATAL(
"No pipeline available with zoo file " << val <<
" and filter " << filter::strget());
272 "by the current filter",
273 pipes[0], pipes, jevois::dnn::pipeline::ParamCateg);
274 pipe::changeParameterDef(newdef);
281void jevois::dnn::Pipeline::scanZoo(std::filesystem::path
const & zoofile, std::string
const & filt,
282 std::vector<std::string> & pipes, std::string
const & indent)
284 LINFO(indent <<
"Scanning model zoo file " << zoofile <<
" with filter [" << filt <<
"]...");
285 int ntot = 0, ngood = 0;
286 bool skipextra = (extramodels::get() ==
false);
288 bool has_vpu =
false;
289 auto itr = itsAccelerators.find(
"VPU");
290 if (itr != itsAccelerators.end() && itr->second > 0) has_vpu =
true;
293 cv::FileStorage fs(zoofile, cv::FileStorage::READ);
294 if (fs.isOpened() ==
false)
LFATAL(
"Could not open zoo file " << zoofile);
295 cv::FileNode fn = fs.root();
298 for (cv::FileNodeIterator fit = fn.begin(); fit != fn.end(); ++fit)
300 cv::FileNode item = *fit;
303 if (item.name() ==
"include")
308 else if (item.name() ==
"includedir")
311 for (
auto const & dent : std::filesystem::recursive_directory_iterator(dir))
312 if (dent.is_regular_file())
314 std::filesystem::path
const path = dent.path();
315 std::filesystem::path
const ext = path.extension();
316 if (ext ==
".yml" || ext ==
".yaml") scanZoo(path, filt, pipes, indent +
" ");
320 else if (item.name() ==
"unset")
322 ph.unset((std::string)item);
325 else if (! item.isMap())
327 ph.set(item, zoofile, item);
335 std::string
const isextrastr = ph.pget(item,
"extramodel");
336 if (isextrastr.empty() ==
false)
339 if (isextra)
continue;
351 std::string typ = ph.pget(item,
"nettype");
355 std::string backend = ph.pget(item,
"backend");
356 std::string target = ph.pget(item,
"target");
358 if (backend ==
"InferenceEngine")
360 if (target ==
"Myriad")
362 if (has_vpu) typ =
"VPU";
363#ifdef JEVOIS_PLATFORM_PRO
369 else if (target ==
"CPU") typ =
"VPUX";
371 else if (backend ==
"TimVX" && target ==
"NPU") typ =
"NPUX";
375 bool has_accel =
false;
376 itr = itsAccelerators.find(typ);
377 if (itr != itsAccelerators.end() && itr->second > 0) has_accel =
true;
380 if ((filt ==
"All" || typ == filt) && has_accel)
382 std::string
const postproc = ph.pget(item,
"postproc");
383 pipes.emplace_back(typ +
':' + postproc +
':' + item.name());
389 LINFO(indent <<
"Found " << ntot <<
" pipelines, " << ngood <<
" passed the filter.");
397 itsShowDataPeek =
false;
398 itsDataPeekOutIdx = 0;
399 itsDataPeekFreeze =
false;
400 itsDataPeekStr.clear();
403 if (val.empty())
return;
404 itsPipeThrew =
false;
413 if (selectPipe(z, tok) ==
false)
414 LFATAL(
"Could not find pipeline entry [" << val <<
"] in zoo file " << z <<
" and its includes");
420bool jevois::dnn::Pipeline::selectPipe(std::string
const & zoofile, std::vector<std::string>
const & tok)
423 processing::freeze(
false);
424 processing::set(jevois::dnn::pipeline::Processing::Async);
427 bool has_vpu =
false;
428 auto itr = itsAccelerators.find(
"VPU");
429 if (itr != itsAccelerators.end() && itr->second > 0) has_vpu =
true;
430 bool vpu_emu =
false;
433 itsPreStats.clear(); itsNetStats.clear(); itsPstStats.clear();
434 itsStatsWarmup =
true;
437 cv::FileStorage fs(zoofile, cv::FileStorage::READ);
438 if (fs.isOpened() ==
false)
LFATAL(
"Could not open zoo file " << zoofile);
442 cv::FileNode fn = fs.root(), node;
444 for (cv::FileNodeIterator fit = fn.begin(); fit != fn.end(); ++fit)
446 cv::FileNode item = *fit;
449 if (item.name() ==
"include")
455 else if (item.name() ==
"includedir")
458 for (
auto const & dent : std::filesystem::recursive_directory_iterator(dir))
459 if (dent.is_regular_file())
461 std::filesystem::path
const path = dent.path();
462 std::filesystem::path
const ext = path.extension();
463 if (ext ==
".yml" || ext ==
".yaml")
if (selectPipe(path, tok))
return true;
468 else if (item.name() ==
"unset")
470 ph.unset((std::string)item);
473 else if (! item.isMap())
475 ph.set(item, zoofile, node);
480 if (item.name() != tok.back())
continue;
481 if (tok.size() == 1) { node = item;
break; }
485 std::string postproc = ph.pget(item,
"postproc");
486 if (postproc != tok[1] && postproc::strget() != tok[1])
continue;
488 std::string nettype = ph.pget(item,
"nettype");
489 std::string backend = ph.pget(item,
"backend");
490 std::string target = ph.pget(item,
"target");
494 if (nettype ==
"OpenCV" && backend ==
"InferenceEngine" && target ==
"Myriad")
495 { node = item;
break; }
497 else if (tok[0] ==
"VPUX")
499 if (nettype ==
"OpenCV" && backend ==
"InferenceEngine")
501 if (target ==
"Myriad" && has_vpu ==
false) { vpu_emu =
true; node = item;
break; }
502 else if (target ==
"CPU") { node = item;
break; }
505 else if (tok[0] ==
"NPUX")
507 if (nettype ==
"OpenCV" && backend ==
"TimVX" && target ==
"NPU")
508 { node = item;
break; }
512 if (nettype == tok[0])
513 { node = item;
break; }
519 if (node.empty())
return false;
523 itsPreProcessor.reset(); removeSubComponent(
"preproc",
false);
524 itsNetwork.reset(); removeSubComponent(
"network",
false);
525 itsPostProcessor.reset(); removeSubComponent(
"postproc",
false);
528 for (cv::FileNodeIterator fit = node.begin(); fit != node.end(); ++fit)
529 ph.set(*fit, zoofile, node);
531 for (
auto const & pp : ph.params)
533 if (vpu_emu && pp.first ==
"target") setZooParam(pp.first,
"CPU", zoofile, node);
534 else setZooParam(pp.first, pp.second, zoofile, node);
543 if (processing::get() != jevois::dnn::pipeline::Processing::Sync)
545 LERROR(
"Network of type Python cannot run Async if pre- or post- processor are also Python "
546 "-- FORCING Sync processing");
547 processing::set(jevois::dnn::pipeline::Processing::Sync);
549 processing::freeze(
true);
556void jevois::dnn::Pipeline::setZooParam(std::string
const & k, std::string
const & v,
557 std::string
const & zf, cv::FileNode
const & node)
560 if (k ==
"extramodel")
return;
564 bool hasparam =
false;
565 try { getParamStringUnique(k); hasparam =
true; }
catch (...) { }
569 LINFO(
"Setting ["<<k<<
"] to ["<<v<<
']');
571 try { setParamStringUnique(k, v); }
572 catch (std::exception
const & e)
573 {
LFATAL(
"While parsing [" << node.name() <<
"] in model zoo file " << zf <<
": " << e.what()); }
575 {
LFATAL(
"While parsing [" << node.name() <<
"] in model zoo file " << zf <<
": unknown error"); }
577 else if (paramwarn::get())
578 engine()->
reportError(
"WARNING: Unused parameter [" + k +
"] in " + zf +
" node [" + node.name() +
"]");
584 itsPreProcessor.reset(); removeSubComponent(
"preproc",
false);
588 case jevois::dnn::pipeline::PreProc::Blob:
589 itsPreProcessor = addSubComponent<jevois::dnn::PreProcessorBlob>(
"preproc");
592 case jevois::dnn::pipeline::PreProc::Python:
593 itsPreProcessor = addSubComponent<jevois::dnn::PreProcessorPython>(
"preproc");
597 if (itsPreProcessor)
LINFO(
"Instantiated pre-processor of type " << itsPreProcessor->className());
598 else LINFO(
"No pre-processor");
606 itsNetwork.reset(); removeSubComponent(
"network",
false);
610 case jevois::dnn::pipeline::NetType::OpenCV:
611 itsNetwork = addSubComponent<jevois::dnn::NetworkOpenCV>(
"network");
616 case jevois::dnn::pipeline::NetType::ORT:
617 itsNetwork = addSubComponent<jevois::dnn::NetworkONNX>(
"network");
620 case jevois::dnn::pipeline::NetType::NPU:
621#ifdef JEVOIS_PLATFORM
622 itsNetwork = addSubComponent<jevois::dnn::NetworkNPU>(
"network");
624 LFATAL(
"NPU network is only supported on JeVois-Pro Platform");
628 case jevois::dnn::pipeline::NetType::SPU:
629 itsNetwork = addSubComponent<jevois::dnn::NetworkHailo>(
"network");
632 case jevois::dnn::pipeline::NetType::TPU:
633 itsNetwork = addSubComponent<jevois::dnn::NetworkTPU>(
"network");
637 case jevois::dnn::pipeline::NetType::Python:
638 itsNetwork = addSubComponent<jevois::dnn::NetworkPython>(
"network");
642 if (itsNetwork)
LINFO(
"Instantiated network of type " << itsNetwork->className());
643 else LINFO(
"No network");
648 itsInputAttrs.clear();
650 itsNetInfo.emplace_back(
"* Input Tensors");
651 itsNetInfo.emplace_back(
"Initializing network...");
652 itsNetInfo.emplace_back(
"* Network");
653 itsNetInfo.emplace_back(
"Initializing network...");
654 itsNetInfo.emplace_back(
"* Output Tensors");
655 itsNetInfo.emplace_back(
"Initializing network...");
656 itsAsyncNetInfo = itsNetInfo;
657 itsAsyncNetworkTime =
"Network: -";
658 itsAsyncNetworkSecs = 0.0;
666 itsPostProcessor.reset(); removeSubComponent(
"postproc",
false);
670 case jevois::dnn::pipeline::PostProc::Classify:
671 itsPostProcessor = addSubComponent<jevois::dnn::PostProcessorClassify>(
"postproc");
673 case jevois::dnn::pipeline::PostProc::Detect:
674 itsPostProcessor = addSubComponent<jevois::dnn::PostProcessorDetect>(
"postproc");
676 case jevois::dnn::pipeline::PostProc::DetectOBB:
677 itsPostProcessor = addSubComponent<jevois::dnn::PostProcessorDetectOBB>(
"postproc");
679 case jevois::dnn::pipeline::PostProc::Segment:
680 itsPostProcessor = addSubComponent<jevois::dnn::PostProcessorSegment>(
"postproc");
682 case jevois::dnn::pipeline::PostProc::YuNet:
683 itsPostProcessor = addSubComponent<jevois::dnn::PostProcessorYuNet>(
"postproc");
685 case jevois::dnn::pipeline::PostProc::Pose:
686 itsPostProcessor = addSubComponent<jevois::dnn::PostProcessorPose>(
"postproc");
688 case jevois::dnn::pipeline::PostProc::Python:
689 itsPostProcessor = addSubComponent<jevois::dnn::PostProcessorPython>(
"postproc");
691 case jevois::dnn::pipeline::PostProc::Stub:
692 itsPostProcessor = addSubComponent<jevois::dnn::PostProcessorStub>(
"postproc");
696 if (itsPostProcessor)
LINFO(
"Instantiated post-processor of type " << itsPostProcessor->className());
697 else LINFO(
"No post-processor");
703 return itsPreProcessor && itsNetwork && itsNetwork->ready() && itsPostProcessor;
709 if (itsNetFut.valid() && itsNetFut.wait_for(std::chrono::milliseconds(2)) == std::future_status::ready)
711 itsOuts = itsNetFut.get();
713 std::swap(itsNetInfo, itsAsyncNetInfo);
714 itsProcTimes[1] = itsAsyncNetworkTime;
715 itsProcSecs[1] = itsAsyncNetworkSecs;
726 if (itsZooChanged) zoo::set(zoo::get());
730 if (itsPipeThrew)
return;
732 bool const ovl = overlay::get();
734 bool refresh_data_peek =
false;
738 if (helper && idle ==
false)
741 ImGui::SetNextWindowPos(ImVec2(24, 159), ImGuiCond_FirstUseEver);
742 ImGui::SetNextWindowSize(ImVec2(464, 877), ImGuiCond_FirstUseEver);
745 ImGui::Begin((instanceName() +
':' + getParamStringUnique(
"pipe")).c_str());
762 if (helper) helper->
itext(instanceName() +
':' + getParamStringUnique(
"pipe"));
770 if (ready() ==
false)
772 char const * msg = itsNetwork ?
"Loading network..." :
"No network selected...";
783 if (idle ==
false) ImGui::TextUnformatted(msg);
784 if (ovl) helper->
itext(msg);
788 itsProcTimes = {
"PreProc: -",
"Network: -",
"PstProc: -" };
789 itsProcSecs = { 0.0, 0.0, 0.0 };
794 switch (processing::get())
797 case jevois::dnn::pipeline::Processing::Sync:
803 if (itsInputAttrs.empty()) itsInputAttrs = itsNetwork->inputShapes();
804 itsBlobs = itsPreProcessor->process(inimg, itsInputAttrs);
805 itsProcTimes[0] = itsTpre.stop(&itsProcSecs[0]);
806 itsPreProcessor->sendreport(mod, outimg, helper, ovl, idle);
811 itsOuts = itsNetwork->process(itsBlobs, itsNetInfo);
812 itsProcTimes[1] = itsTnet.stop(&itsProcSecs[1]);
815 showInfo(itsNetInfo, mod, outimg, helper, ovl, idle);
819 itsPostProcessor->process(itsOuts, itsPreProcessor.get());
820 itsProcTimes[2] = itsTpost.stop(&itsProcSecs[2]);
821 itsPostProcessor->report(mod, outimg, helper, ovl, idle);
822 refresh_data_peek =
true;
827 case jevois::dnn::pipeline::Processing::Async:
834 bool needpost = checkAsyncNetComplete();
837 if (itsNetFut.valid() ==
false)
841 if (itsInputAttrs.empty()) itsInputAttrs = itsNetwork->inputShapes();
842 itsBlobs = itsPreProcessor->process(inimg, itsInputAttrs);
843 itsProcTimes[0] = itsTpre.stop(&itsProcSecs[0]);
850 std::vector<cv::Mat> outs = itsNetwork->process(itsBlobs, itsAsyncNetInfo);
851 itsAsyncNetworkTime = itsTnet.stop(&itsAsyncNetworkSecs);
858 std::vector<cv::Mat> outscopy;
859 for (cv::Mat
const & m : outs) outscopy.emplace_back(m.clone());
865 itsPreProcessor->sendreport(mod, outimg, helper, ovl, idle);
868 showInfo(itsNetInfo, mod, outimg, helper, ovl, idle);
871 if (needpost && itsOuts.empty() ==
false)
874 itsPostProcessor->process(itsOuts, itsPreProcessor.get());
875 itsProcTimes[2] = itsTpost.stop(&itsProcSecs[2]);
876 refresh_data_peek =
true;
880 itsPostProcessor->report(mod, outimg, helper, ovl, idle);
886 itsSecsSum += itsProcSecs[0] + itsProcSecs[1] + itsProcSecs[2];
887 if (++itsSecsSumNum == 20) { itsSecsAvg = itsSecsSum / itsSecsSumNum; itsSecsSum = 0.0; itsSecsSumNum = 0; }
890 if (statsfile::get().empty() ==
false && itsOuts.empty() ==
false)
892 static std::vector<std::string> pipelines;
893 static bool statswritten =
false;
894 static bool write_separator =
false;
895 static size_t benchpipe = 0;
896 size_t constexpr numwarmup = 25;
897 size_t constexpr numbench = 100;
899 if (benchmark::get())
902 if (helper && ImGui::Begin(
"Benchmarking in progress"))
904 ImGui::TextUnformatted(pipe::strget().c_str());
905 if (itsStatsWarmup) ImGui::Text(
"Warmup %zu / %zu", itsPreStats.size(), numwarmup);
906 else ImGui::Text(
"Iteration %zu / %zu", itsPreStats.size(), numbench);
911 if (pipelines.empty())
915 std::string pipes = pipe::def().validValuesString();
916 size_t const idx = pipes.find(
'[');
917 pipes = pipes.substr(idx + 1, pipes.length() - idx - 2);
920 statswritten =
false;
921 pipe::set(pipelines[benchpipe]);
922 processing::freeze(
false);
923 processing::set(jevois::dnn::pipeline::Processing::Sync);
930 std::string oldaccel = pipelines[benchpipe].substr(0, pipelines[benchpipe].find(
':'));
932 statswritten =
false;
933 if (benchpipe >= pipelines.size())
936 benchmark::set(
false);
937 LINFO(
"Benchmark complete.");
941 if (oldaccel != pipelines[benchpipe].substr(0, pipelines[benchpipe].find(
':'))) write_separator =
true;
942 pipe::set(pipelines[benchpipe]);
943 processing::freeze(
false);
944 processing::set(jevois::dnn::pipeline::Processing::Sync);
949 else pipelines.clear();
951 itsPreStats.push_back(itsProcSecs[0]);
952 itsNetStats.push_back(itsProcSecs[1]);
953 itsPstStats.push_back(itsProcSecs[2]);
956 if (itsStatsWarmup && itsPreStats.size() == numwarmup)
957 { itsStatsWarmup =
false; itsPreStats.clear(); itsNetStats.clear(); itsPstStats.clear(); }
959 if (itsPreStats.size() == numbench)
962 std::vector<double> tot;
963 for (
size_t i = 0; i < itsPreStats.size(); ++i)
964 tot.emplace_back(itsPreStats[i] + itsNetStats[i] + itsPstStats[i]);
968 std::ofstream ofs(fn, std::ios_base::app);
973 ofs <<
"<tr><td colspan=8></td></tr><tr><td colspan=8></td></tr>" << std::endl;
974 write_separator =
false;
977 ofs <<
"<tr><td class=jvpipe>" << pipe::get() <<
" </td>";
979 std::vector<std::string> insizes;
980 for (cv::Mat
const & m : itsBlobs)
982 ofs <<
"<td class=jvnetin>" <<
jevois::join(insizes,
", ") <<
"</td>";
984 std::vector<std::string> outsizes;
985 for (cv::Mat
const & m : itsOuts)
987 ofs <<
"<td class=jvnetout>" <<
jevois::join(outsizes,
", ") <<
"</td>";
997 for (
double t : tot) avg += t;
999 if (avg) avg = 1.0 / avg;
1000 ofs <<
"<td class=jvfps>" << std::fixed << std::showpoint << std::setprecision(1) <<
1001 avg <<
" fps</td></tr>" << std::endl;
1004 itsPreStats.clear();
1005 itsNetStats.clear();
1006 itsPstStats.clear();
1007 LINFO(
"Network stats appended to " << fn);
1008 statswritten =
true;
1016 itsPipeThrew =
true;
1036 if (ImGui::CollapsingHeader(
"Processing Times", ImGuiTreeNodeFlags_DefaultOpen))
1038 for (std::string
const & s : itsProcTimes) ImGui::TextUnformatted(s.c_str());
1039 ImGui::Text(
"OVERALL: %s/inference", total.c_str());
1044 if (ImGui::Button(
"Peek output data")) itsShowDataPeek =
true;
1050 showDataPeekWindow(helper, refresh_data_peek);
1055 for (std::string
const & s : itsProcTimes) helper->
itext(s);
1056 helper->
itext(
"OVERALL: " + total +
"/inference");
1060 (void)refresh_data_peek;
1066 for (std::string
const & s : itsProcTimes)
1083 for (std::string
const & s : info)
1087 if (helper && idle ==
false)
1091 show = ImGui::CollapsingHeader(s.c_str() + 2, ImGuiTreeNodeFlags_DefaultOpen);
1096 else ImGui::TextUnformatted(s.c_str());
1100 (void)idle; (void)show; (void)helper;
1116 if (itsShowDataPeek ==
false)
return;
1119 ImGui::SetNextWindowPos(ImVec2(100, 50), ImGuiCond_FirstUseEver);
1120 ImGui::SetNextWindowSize(ImVec2(900, 600), ImGuiCond_FirstUseEver);
1123 ImGui::PushStyleColor(ImGuiCol_WindowBg, 0xf0ffe0e0);
1126 ImGui::Begin(
"DNN Output Peek", &itsShowDataPeek, ImGuiWindowFlags_HorizontalScrollbar);
1129 std::vector<std::string> outspecs;
1130 for (
size_t i = 0; cv::Mat
const & out : itsOuts)
1132 if (helper->
combo(
"##dataPeekOutSelect", outspecs, itsDataPeekOutIdx)) itsDataPeekFreeze =
false;
1134 ImGui::SameLine(); ImGui::TextUnformatted(
" "); ImGui::SameLine();
1139 if ( (itsDataPeekFreeze && itsDataPeekStr.empty() ==
false) || refresh ==
false)
1140 ImGui::TextUnformatted(itsDataPeekStr.c_str());
1144 cv::Mat
const & out = itsOuts[itsDataPeekOutIdx];
1145 std::vector<int> newsz;
1146 cv::MatSize
const & ms = out.size;
int const nd = ms.dims();
1147 for (
int i = 0; i < nd; ++i)
if (ms[i] > 1) newsz.emplace_back(ms[i]);
1148 cv::Mat
const out2(newsz, out.type(), out.data);
1152 std::ostringstream oss;
1153 if (newsz.size() > 3)
1154 throw "too many dims";
1155 else if (newsz.size() == 3)
1157 cv::Range ranges[3];
1158 ranges[2] = cv::Range::all();
1159 ranges[1] = cv::Range::all();
1160 for (
int i = 0; i < newsz[0]; ++i)
1162 oss <<
"-------------------------------------------------------------------------------\n";
1163 oss <<
"Third dimension index = " << i <<
":\n";
1164 oss <<
"-------------------------------------------------------------------------------\n\n";
1165 ranges[0] = cv::Range(i, i+1);
1166 cv::Mat slice = out2(ranges);
1167 cv::Mat slice2d(cv::Size(newsz[2], newsz[1]), slice.type(), slice.data);
1168 oss << slice2d <<
"\n\n";
1174 itsDataPeekStr = oss.str();
1176 catch (...) { itsDataPeekStr =
"Sorry, cannot display this type of tensor..."; }
1178 ImGui::TextUnformatted(itsDataPeekStr.c_str());
1180 if (out2.total() > 10000)
1182 helper->
reportError(
"Large data peek - Freezing data display\n"
1183 "Click the Freeze button to refresh once");
1184 itsDataPeekFreeze =
true;
1190 ImGui::PopStyleColor();
#define JEVOIS_SHARE_PATH
Base path for shared files (e.g., neural network weights, etc)
A component of a model hierarchy.
void clearErrors()
Clear all errors currently displayed in the JeVois-Pro GUI.
void reportError(std::string const &err)
Helper class to assist modules in creating graphical and GUI elements.
bool combo(std::string const &name, std::vector< std::string > const &items, int &selected_index)
Helper to draw a combobox from a vector of strings.
void reportAndIgnoreException(std::string const &prefix="")
Report current exception in a modal dialog, then ignore it.
void reportError(std::string const &err)
Report an error in an overlay window.
void itext(char const *txt, ImU32 const &col=IM_COL32_BLACK_TRANS, int line=-1)
Draw some overlay text on top of an image.
bool toggleButton(char const *name, bool *val)
Helper to draw a toggle button.
A raw image as coming from a V4L2 Camera and/or being sent out to a USB Gadget.
Base class for a module that supports standardized serial messages.
Wrapper around an OpenCV DNN neural network.
Wrapper around an DNN neural network invoked through python.
std::vector< ObjDetectOBB > const & latestDetectionsOBB() const
Get the latest oriented bounded box (OBB) detection results, use with caution, not thread-safe.
bool checkAsyncNetComplete()
void showInfo(std::vector< std::string > const &info, jevois::StdModule *mod, jevois::RawImage *outimg, jevois::OptGUIhelper *helper, bool ovl, bool idle)
void preUninit() override
Called before all sub-Components are uninit()ed.
void showDataPeekWindow(jevois::GUIhelper *helper, bool refresh)
std::vector< ObjReco > const & latestRecognitions() const
Get the latest recognition results, use with caution, not thread-safe.
void process(jevois::RawImage const &inimg, jevois::StdModule *mod, jevois::RawImage *outimg, jevois::OptGUIhelper *helper, bool idle=false)
Process an input image, send results to serial/image/gui.
void onParamChange(pipeline::zooroot const ¶m, std::string const &val) override
virtual ~Pipeline()
Destructor.
bool ready() const
Returns true when all three of preproc, net, and postproc are ready.
Pipeline(std::string const &instance)
Constructor.
void freeze(bool doit)
Freeze/unfreeze parameters that users should not change while running.
std::vector< PoseSkeleton > const & latestSkeletons() const
Get the latest skeletons, use with caution, not thread-safe.
std::vector< ObjDetect > const & latestDetections() const
Get the latest detection results, use with caution, not thread-safe.
void postInit() override
Called after all sub-Components are init()ed.
Post-Processor for neural network pipeline.
Post-Processor for neural network pipeline for oriented bounding box (OBB) object detection.
Post-Processor for neural network pipeline.
Post-Processor for neural network pipeline, for human/animal/other pose detection (skeleton)
Post-Processor for neural network pipeline.
Pre-Processor for neural network pipeline written in python.
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
std::string warnAndIgnoreException(std::string const &prefix="")
Convenience function to catch an exception, issue some LERROR (depending on type),...
#define LERROR(msg)
Convenience macro for users to print out console or syslog messages, ERROR level.
#define LINFO(msg)
Convenience macro for users to print out console or syslog messages, INFO level.
std::string shapestr(cv::Mat const &m)
Get a string of the form: "nD AxBxC... TYPE" from an n-dimensional cv::Mat with data type TYPE.
void writeText(RawImage &img, std::string const &txt, int x, int y, unsigned int col, Font font=Font6x10)
Write some text in an image.
void paramStringToVal(std::string const &valstring, T &result)
Machine-readable conversion from string to T, for use in jevois::Parameter.
std::future< std::invoke_result_t< std::decay_t< Function >, std::decay_t< Args >... > > async(Function &&f, Args &&... args)
Async execution using a thread pool.
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 join(std::vector< T > const &tokens, std::string const &delimiter)
Concatenate a vector of tokens into a string.
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::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...
std::string replaceAll(std::string const &str, std::string const &from, std::string const &to)
Replace all instances of 'from' with 'to'.
unsigned short constexpr White
YUYV color value.
Main namespace for all JeVois classes and functions.
size_t getNumInstalledVPUs()
Get the number of Myriad-X VPUs present on this system.
size_t getNumInstalledNPUs()
Get the number of JeVois-Pro NPUs present on this system.
size_t getNumInstalledTPUs()
Get the number of Coral TPUs present on this system.
size_t getNumInstalledSPUs()
Get the number of Hailo8 SPUs present on this system.