1 #ifndef OPENPOSE_WRAPPER_WRAPPER_HPP
2 #define OPENPOSE_WRAPPER_WRAPPER_HPP
30 template<
typename TDatums,
31 typename TDatumsSP = std::shared_ptr<TDatums>,
32 typename TWorker = std::shared_ptr<Worker<TDatumsSP>>,
33 typename TQueue = Queue<TDatumsSP>>
66 void setWorkerInput(
const TWorker& worker,
const bool workerOnNewThread =
true);
82 void setWorkerOutput(
const TWorker& worker,
const bool workerOnNewThread =
true);
179 bool tryPush(
const TDatumsSP& tDatums);
196 bool tryPop(TDatumsSP& tDatums);
210 const std::shared_ptr<std::pair<std::atomic<bool>, std::atomic<int>>> spVideoSeek;
213 bool mUserInputWsOnNewThread;
214 bool mUserPostProcessingWsOnNewThread;
215 bool mUserOutputWsOnNewThread;
216 unsigned long long mThreadId;
217 bool mMultiThreadEnabled;
219 std::vector<TWorker> mUserInputWs;
220 TWorker wDatumProducer;
221 TWorker spWScaleAndSizeExtractor;
222 TWorker spWCvMatToOpInput;
223 TWorker spWCvMatToOpOutput;
224 std::vector<std::vector<TWorker>> spWPoseExtractors;
225 std::vector<std::vector<TWorker>> spWPoseTriangulations;
226 std::vector<std::vector<TWorker>> spWJointAngleEstimations;
227 std::vector<TWorker> mPostProcessingWs;
228 std::vector<TWorker> mUserPostProcessingWs;
229 std::vector<TWorker> mOutputWs;
231 std::vector<TWorker> mUserOutputWs;
247 void configureThreadManager();
256 unsigned long long threadIdPP();
282 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
284 mThreadManagerMode{threadManagerMode},
285 spVideoSeek{std::make_shared<std::pair<std::atomic<bool>, std::atomic<int>>>()},
287 mThreadManager{threadManagerMode},
288 mMultiThreadEnabled{
true}
293 spVideoSeek->first =
false;
294 spVideoSeek->second = 0;
296 catch (
const std::exception& e)
298 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
302 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
310 catch (
const std::exception& e)
312 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
316 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
321 mMultiThreadEnabled =
false;
323 catch (
const std::exception& e)
325 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
329 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
331 const bool workerOnNewThread)
335 mUserInputWs.clear();
336 if (worker ==
nullptr)
337 error(
"Your worker is a nullptr.", __LINE__, __FILE__, __FUNCTION__);
338 mUserInputWs.emplace_back(worker);
339 mUserInputWsOnNewThread = {workerOnNewThread};
341 catch (
const std::exception& e)
343 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
347 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
349 const bool workerOnNewThread)
353 mUserPostProcessingWs.clear();
354 if (worker ==
nullptr)
355 error(
"Your worker is a nullptr.", __LINE__, __FILE__, __FUNCTION__);
356 mUserPostProcessingWs.emplace_back(worker);
357 mUserPostProcessingWsOnNewThread = {workerOnNewThread};
359 catch (
const std::exception& e)
361 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
365 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
367 const bool workerOnNewThread)
371 mUserOutputWs.clear();
372 if (worker ==
nullptr)
373 error(
"Your worker is a nullptr.", __LINE__, __FILE__, __FUNCTION__);
374 mUserOutputWs.emplace_back(worker);
375 mUserOutputWsOnNewThread = {workerOnNewThread};
377 catch (
const std::exception& e)
379 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
383 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
393 catch (
const std::exception& e)
395 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
399 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
410 catch (
const std::exception& e)
412 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
416 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
427 catch (
const std::exception& e)
429 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
433 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
443 auto wrapperStructPose = wrapperStructPoseTemp;
450 const auto renderOutputGpu = wrapperStructPose.renderMode ==
RenderMode::Gpu
458 const auto userOutputWsEmpty = mUserOutputWs.empty();
460 wrapperStructInput, wrapperStructOutput, renderOutput, userOutputWsEmpty,
464 auto numberThreads = wrapperStructPose.gpuNumber;
465 auto gpuNumberStart = wrapperStructPose.gpuNumberStart;
469 numberThreads = (wrapperStructPose.gpuNumber == 0 ? 0 : 1);
474 disableMultiThreading();
482 if (numberThreads < 0)
484 if (totalGpuNumber <= gpuNumberStart)
485 error(
"Number of initial GPU (`--number_gpu_start`) must be lower than the total number of"
486 " used GPUs (`--number_gpu`)", __LINE__, __FUNCTION__, __FILE__);
487 numberThreads = totalGpuNumber - gpuNumberStart;
490 log(
"Auto-detecting all available GPUs... Detected " + std::to_string(totalGpuNumber)
491 +
" GPU(s), using " + std::to_string(numberThreads) +
" of them starting at GPU "
495 if (gpuNumberStart + numberThreads > totalGpuNumber)
496 error(
"Initial GPU selected (`--number_gpu_start`) + number GPUs to use (`--number_gpu`) must"
497 " be lower or equal than the total number of GPUs in your machine ("
498 + std::to_string(gpuNumberStart) +
" + "
499 + std::to_string(numberThreads) +
" vs. "
500 + std::to_string(totalGpuNumber) +
").",
501 __LINE__, __FUNCTION__, __FILE__);
512 auto finalOutputSize = wrapperStructPose.outputSize;
520 wrapperStructInput.
producerSharedPtr->setProducerFpsMode(displayProducerFpsMode);
529 if (finalOutputSize.x == -1 || finalOutputSize.y == -1)
530 finalOutputSize = producerSize;
536 const auto datumProducer = std::make_shared<DatumProducer<TDatums>>(
540 wDatumProducer = std::make_shared<WDatumProducer<TDatumsSP, TDatums>>(datumProducer);
543 wDatumProducer =
nullptr;
545 std::vector<std::shared_ptr<PoseExtractorNet>> poseExtractorNets;
546 std::vector<std::shared_ptr<FaceExtractorNet>> faceExtractorNets;
547 std::vector<std::shared_ptr<HandExtractorNet>> handExtractorNets;
548 std::vector<std::shared_ptr<PoseGpuRenderer>> poseGpuRenderers;
549 std::shared_ptr<PoseCpuRenderer> poseCpuRenderer;
550 if (numberThreads > 0)
553 const auto scaleAndSizeExtractor = std::make_shared<ScaleAndSizeExtractor>(
554 wrapperStructPose.netInputSize, finalOutputSize, wrapperStructPose.scalesNumber,
555 wrapperStructPose.scaleGap
557 spWScaleAndSizeExtractor = std::make_shared<WScaleAndSizeExtractor<TDatumsSP>>(scaleAndSizeExtractor);
560 const auto cvMatToOpInput = std::make_shared<CvMatToOpInput>(wrapperStructPose.poseModel);
561 spWCvMatToOpInput = std::make_shared<WCvMatToOpInput<TDatumsSP>>(cvMatToOpInput);
564 const auto cvMatToOpOutput = std::make_shared<CvMatToOpOutput>();
565 spWCvMatToOpOutput = std::make_shared<WCvMatToOpOutput<TDatumsSP>>(cvMatToOpOutput);
569 std::vector<TWorker> cpuRenderers;
570 spWPoseExtractors.clear();
571 spWPoseExtractors.resize(numberThreads);
572 if (wrapperStructPose.enable)
575 for (
auto gpuId = 0; gpuId < numberThreads; gpuId++)
576 poseExtractorNets.emplace_back(std::make_shared<PoseExtractorCaffe>(
577 wrapperStructPose.poseModel, modelFolder, gpuId + gpuNumberStart,
578 wrapperStructPose.heatMapTypes, wrapperStructPose.heatMapScale,
579 wrapperStructPose.addPartCandidates, wrapperStructPose.enableGoogleLogging
583 if (renderOutputGpu || wrapperStructPose.renderMode ==
RenderMode::Cpu)
587 const auto alphaKeypoint = (wrapperStructPose.renderMode !=
RenderMode::None
588 ? wrapperStructPose.alphaKeypoint : 0.f);
590 ? wrapperStructPose.alphaHeatMap : 0.f);
594 for (
const auto& poseExtractorNet : poseExtractorNets)
596 poseGpuRenderers.emplace_back(std::make_shared<PoseGpuRenderer>(
597 wrapperStructPose.poseModel, poseExtractorNet, wrapperStructPose.renderThreshold,
598 wrapperStructPose.blendOriginalFrame, alphaKeypoint,
599 alphaHeatMap, wrapperStructPose.defaultPartToRender
606 poseCpuRenderer = std::make_shared<PoseCpuRenderer>(
607 wrapperStructPose.poseModel, wrapperStructPose.renderThreshold,
608 wrapperStructPose.blendOriginalFrame, alphaKeypoint, alphaHeatMap,
609 wrapperStructPose.defaultPartToRender);
616 spWPoseExtractors.resize(poseExtractorNets.size());
618 ? std::make_shared<PersonIdExtractor>() :
nullptr);
625 const auto keepTopNPeople = (wrapperStructPose.numberPeopleMax > 0 ?
626 std::make_shared<KeepTopNPeople>(wrapperStructPose.numberPeopleMax)
629 auto personTrackers = std::make_shared<std::vector<std::shared_ptr<PersonTracker>>>();
630 if (wrapperStructExtra.
tracking > -1)
631 personTrackers->emplace_back(
632 std::make_shared<PersonTracker>(wrapperStructExtra.
tracking == 0));
633 for (
auto i = 0u; i < spWPoseExtractors.size(); i++)
637 const auto poseExtractor = std::make_shared<PoseExtractor>(
638 poseExtractorNets.at(i), keepTopNPeople, personIdExtractor, personTrackers,
639 wrapperStructPose.numberPeopleMax, wrapperStructExtra.
tracking);
640 spWPoseExtractors.at(i) = {std::make_shared<WPoseExtractor<TDatumsSP>>(poseExtractor)};
662 if (wrapperStructFace.
enable)
666 if (wrapperStructPose.enable)
668 const auto faceDetector = std::make_shared<FaceDetector>(wrapperStructPose.poseModel);
669 for (
auto& wPose : spWPoseExtractors)
675 log(
"Body keypoint detection is disabled. Hence, using OpenCV face detector (much less"
677 for (
auto& wPose : spWPoseExtractors)
680 const auto faceDetectorOpenCV = std::make_shared<FaceDetectorOpenCV>(modelFolder);
687 for (
auto gpu = 0u; gpu < spWPoseExtractors.size(); gpu++)
690 const auto netOutputSize = wrapperStructFace.
netInputSize;
691 const auto faceExtractorNet = std::make_shared<FaceExtractorCaffe>(
692 wrapperStructFace.
netInputSize, netOutputSize, modelFolder,
693 gpu + gpuNumberStart, wrapperStructPose.heatMapTypes, wrapperStructPose.heatMapScale,
694 wrapperStructPose.enableGoogleLogging
696 faceExtractorNets.emplace_back(faceExtractorNet);
697 spWPoseExtractors.at(gpu).emplace_back(
703 if (wrapperStructHand.
enable)
705 const auto handDetector = std::make_shared<HandDetector>(wrapperStructPose.poseModel);
706 for (
auto gpu = 0u; gpu < spWPoseExtractors.size(); gpu++)
711 spWPoseExtractors.at(gpu).emplace_back(
716 spWPoseExtractors.at(gpu).emplace_back(
719 const auto netOutputSize = wrapperStructHand.
netInputSize;
720 const auto handExtractorNet = std::make_shared<HandExtractorCaffe>(
721 wrapperStructHand.
netInputSize, netOutputSize, modelFolder,
723 wrapperStructPose.heatMapTypes, wrapperStructPose.heatMapScale,
724 wrapperStructPose.enableGoogleLogging
726 handExtractorNets.emplace_back(handExtractorNet);
727 spWPoseExtractors.at(gpu).emplace_back(
732 spWPoseExtractors.at(gpu).emplace_back(
739 if (!poseGpuRenderers.empty())
740 for (
auto i = 0u; i < spWPoseExtractors.size(); i++)
742 poseGpuRenderers.at(i)
752 const auto faceRenderer = std::make_shared<FaceCpuRenderer>(wrapperStructFace.
renderThreshold,
761 for (
auto i = 0u; i < spWPoseExtractors.size(); i++)
764 const auto faceRenderer = std::make_shared<FaceGpuRenderer>(
769 if (!poseGpuRenderers.empty())
771 const bool isLastRenderer = !renderHandGpu;
773 poseGpuRenderers.at(i)
779 spWPoseExtractors.at(i).emplace_back(
784 error(
"Unknown RenderMode.", __LINE__, __FUNCTION__, __FILE__);
794 const auto handRenderer = std::make_shared<HandCpuRenderer>(wrapperStructHand.
renderThreshold,
803 for (
auto i = 0u; i < spWPoseExtractors.size(); i++)
806 const auto handRenderer = std::make_shared<HandGpuRenderer>(
811 if (!poseGpuRenderers.empty())
813 const bool isLastRenderer =
true;
815 poseGpuRenderers.at(i)
821 spWPoseExtractors.at(i).emplace_back(
826 error(
"Unknown RenderMode.", __LINE__, __FUNCTION__, __FILE__);
830 spWPoseTriangulations.clear();
834 spWPoseTriangulations.resize(
fastMax(1,
int(spWPoseExtractors.size() / 4)));
835 for (
auto i = 0u ; i < spWPoseTriangulations.size() ; i++)
837 const auto poseTriangulation = std::make_shared<PoseTriangulation>(
839 spWPoseTriangulations.at(i) = {std::make_shared<WPoseTriangulation<TDatumsSP>>(
844 mPostProcessingWs.clear();
856 mPostProcessingWs =
mergeVectors(mPostProcessingWs, cpuRenderers);
857 const auto opOutputToCvMat = std::make_shared<OpOutputToCvMat>();
865 (finalOutputSize == producerSize || finalOutputSize.x <= 0 || finalOutputSize.y <= 0))
868 && producerSize == wrapperStructPose.netInputSize))
871 auto keypointScaler = std::make_shared<KeypointScaler>(wrapperStructPose.keypointScale);
880 spWJointAngleEstimations.clear();
881 #ifdef USE_3D_ADAM_MODEL
884 spWJointAngleEstimations.resize(wrapperStructExtra.
ikThreads);
886 for (
auto i = 0u; i < spWJointAngleEstimations.size(); i++)
888 const auto jointAngleEstimation = std::make_shared<JointAngleEstimation>(displayAdam);
889 spWJointAngleEstimations.at(i) = {std::make_shared<WJointAngleEstimation<TDatumsSP>>(
890 jointAngleEstimation)};
898 #ifdef USE_3D_ADAM_MODEL
899 if (!wrapperStructOutput.
udpHost.empty() && !wrapperStructOutput.
udpPort.empty())
901 const auto udpSender = std::make_shared<UdpSender>(wrapperStructOutput.
udpHost,
907 if (!writeKeypointCleaned.empty())
909 const auto keypointSaver = std::make_shared<KeypointSaver>(writeKeypointCleaned,
912 if (wrapperStructFace.
enable)
914 if (wrapperStructHand.
enable)
919 if (!writeJsonCleaned.empty())
921 const auto peopleJsonSaver = std::make_shared<PeopleJsonSaver>(writeJsonCleaned);
928 const auto humanFormat =
true;
929 const auto cocoJsonSaver = std::make_shared<CocoJsonSaver>(wrapperStructOutput.
writeCocoJson,
937 const auto humanFormat =
true;
938 const auto cocoJsonSaver = std::make_shared<CocoJsonSaver>(wrapperStructOutput.
writeCocoFootJson,
943 if (!writeImagesCleaned.empty())
945 const auto imageSaver = std::make_shared<ImageSaver>(writeImagesCleaned,
952 const auto originalVideoFps = (wrapperStructOutput.
writeVideoFps > 0 ?
958 error(
"Video file can only be recorded inside `wrapper/wrapper.hpp` if the producer"
959 " is one of the default ones (e.g. video, webcam, ...).",
960 __LINE__, __FUNCTION__, __FILE__);
961 if (finalOutputSize.x <= 0 || finalOutputSize.y <= 0)
962 error(
"Video can only be recorded if outputSize is fixed (e.g. video, webcam, IP camera),"
963 "but not for a image directory.", __LINE__, __FUNCTION__, __FILE__);
964 const auto videoSaver = std::make_shared<VideoSaver>(
965 wrapperStructOutput.
writeVideo, CV_FOURCC(
'M',
'J',
'P',
'G'), originalVideoFps, finalOutputSize
970 #ifdef USE_3D_ADAM_MODEL
971 if (!wrapperStructOutput.
writeBvh.empty())
973 const auto bvhSaver = std::make_shared<BvhSaver>(
974 wrapperStructOutput.
writeBvh, JointAngleEstimation::getTotalModel(), originalVideoFps
976 mOutputWs.emplace_back(std::make_shared<WBvhSaver<TDatumsSP>>(bvhSaver));
980 if (!writeHeatMapsCleaned.empty())
982 const auto heatMapSaver = std::make_shared<HeatMapSaver>(writeHeatMapsCleaned,
990 if (wrapperStructOutput.
guiVerbose && (guiEnabled || !mUserOutputWs.empty()
994 const auto guiInfoAdder = std::make_shared<GuiInfoAdder>(numberThreads, guiEnabled);
1002 std::vector<std::shared_ptr<Renderer>> renderers;
1004 renderers.emplace_back(std::static_pointer_cast<Renderer>(poseCpuRenderer));
1006 for (
const auto& poseGpuRenderer : poseGpuRenderers)
1007 renderers.emplace_back(std::static_pointer_cast<Renderer>(poseGpuRenderer));
1012 #ifdef USE_3D_ADAM_MODEL
1014 const auto gui = std::make_shared<GuiAdam>(
1015 finalOutputSize, wrapperStructOutput.
fullScreen, mThreadManager.getIsRunningSharedPtr(),
1016 spVideoSeek, poseExtractorNets, faceExtractorNets, handExtractorNets, renderers,
1017 wrapperStructOutput.
displayMode, JointAngleEstimation::getTotalModel(),
1021 spWGui = {std::make_shared<WGuiAdam<TDatumsSP>>(gui)};
1029 const auto gui = std::make_shared<Gui3D>(
1030 finalOutputSize, wrapperStructOutput.
fullScreen, mThreadManager.getIsRunningSharedPtr(),
1031 spVideoSeek, poseExtractorNets, faceExtractorNets, handExtractorNets, renderers,
1032 wrapperStructPose.poseModel, wrapperStructOutput.
displayMode
1035 spWGui = {std::make_shared<WGui3D<TDatumsSP>>(gui)};
1041 const auto gui = std::make_shared<Gui>(
1042 finalOutputSize, wrapperStructOutput.
fullScreen, mThreadManager.getIsRunningSharedPtr(),
1043 spVideoSeek, poseExtractorNets, faceExtractorNets, handExtractorNets, renderers
1046 spWGui = {std::make_shared<WGui<TDatumsSP>>(gui)};
1049 error(
"Unknown DisplayMode.", __LINE__, __FUNCTION__, __FILE__);
1055 catch (
const std::exception& e)
1057 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
1061 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
1066 configureThreadManager();
1068 mThreadManager.exec();
1070 catch (
const std::exception& e)
1072 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
1076 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
1081 configureThreadManager();
1083 mThreadManager.start();
1085 catch (
const std::exception& e)
1087 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
1091 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
1096 mThreadManager.stop();
1098 catch (
const std::exception& e)
1100 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
1104 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
1109 return mThreadManager.isRunning();
1111 catch (
const std::exception& e)
1113 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
1118 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
1123 if (!mUserInputWs.empty())
1124 error(
"Emplace cannot be called if an input worker was already selected.",
1125 __LINE__, __FUNCTION__, __FILE__);
1126 return mThreadManager.tryEmplace(tDatums);
1128 catch (
const std::exception& e)
1130 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
1135 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
1140 if (!mUserInputWs.empty())
1141 error(
"Emplace cannot be called if an input worker was already selected.",
1142 __LINE__, __FUNCTION__, __FILE__);
1143 return mThreadManager.waitAndEmplace(tDatums);
1145 catch (
const std::exception& e)
1147 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
1152 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
1157 if (!mUserInputWs.empty())
1158 error(
"Push cannot be called if an input worker was already selected.",
1159 __LINE__, __FUNCTION__, __FILE__);
1160 return mThreadManager.tryPush(tDatums);
1162 catch (
const std::exception& e)
1164 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
1169 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
1174 if (!mUserInputWs.empty())
1175 error(
"Push cannot be called if an input worker was already selected.",
1176 __LINE__, __FUNCTION__, __FILE__);
1177 return mThreadManager.waitAndPush(tDatums);
1179 catch (
const std::exception& e)
1181 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
1186 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
1191 if (!mUserOutputWs.empty())
1192 error(
"Pop cannot be called if an output worker was already selected.",
1193 __LINE__, __FUNCTION__, __FILE__);
1194 return mThreadManager.tryPop(tDatums);
1196 catch (
const std::exception& e)
1198 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
1203 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
1208 if (!mUserOutputWs.empty())
1209 error(
"Pop cannot be called if an output worker was already selected.",
1210 __LINE__, __FUNCTION__, __FILE__);
1211 return mThreadManager.waitAndPop(tDatums);
1213 catch (
const std::exception& e)
1215 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
1220 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
1225 mConfigured =
false;
1226 mThreadManager.reset();
1229 mUserInputWs.clear();
1230 wDatumProducer =
nullptr;
1231 spWScaleAndSizeExtractor =
nullptr;
1232 spWCvMatToOpInput =
nullptr;
1233 spWCvMatToOpOutput =
nullptr;
1234 spWPoseExtractors.clear();
1235 spWPoseTriangulations.clear();
1236 spWJointAngleEstimations.clear();
1237 mPostProcessingWs.clear();
1238 mUserPostProcessingWs.clear();
1241 mUserOutputWs.clear();
1243 catch (
const std::exception& e)
1245 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
1249 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
1250 void Wrapper<TDatums, TDatumsSP, TWorker, TQueue>::configureThreadManager()
1258 error(
"Configure the Wrapper class before calling `start()`.", __LINE__, __FUNCTION__, __FILE__);
1259 if ((wDatumProducer ==
nullptr) == (mUserInputWs.empty())
1263 const auto message =
"You need to have 1 and only 1 producer selected. You can introduce your own"
1264 " producer by using setWorkerInput() or use the OpenPose default producer by"
1265 " configuring it in the configure function) or use the"
1266 " ThreadManagerMode::Asynchronous(In) mode.";
1267 error(message, __LINE__, __FUNCTION__, __FILE__);
1269 if (mOutputWs.empty() && mUserOutputWs.empty() && spWGui ==
nullptr
1273 error(
"No output selected.", __LINE__, __FUNCTION__, __FILE__);
1278 mThreadManager.reset();
1280 auto queueIn = 0ull;
1281 auto queueOut = 1ull;
1284 const auto wIdGenerator = std::make_shared<WIdGenerator<TDatumsSP>>();
1285 std::vector<TWorker> workersAux{wIdGenerator};
1287 if (spWScaleAndSizeExtractor !=
nullptr)
1288 workersAux =
mergeVectors(workersAux, {spWScaleAndSizeExtractor});
1289 if (spWCvMatToOpInput !=
nullptr)
1290 workersAux =
mergeVectors(workersAux, {spWCvMatToOpInput});
1292 if (spWCvMatToOpOutput !=
nullptr)
1293 workersAux =
mergeVectors(workersAux, {spWCvMatToOpOutput});
1297 if (!mUserInputWs.empty() && mUserInputWsOnNewThread)
1301 mThreadManager.add(mThreadId, mUserInputWs, queueIn++, queueOut++);
1305 else if (!mUserInputWs.empty())
1308 else if (wDatumProducer !=
nullptr)
1309 workersAux =
mergeVectors({wDatumProducer}, workersAux);
1313 error(
"No input selected.", __LINE__, __FUNCTION__, __FILE__);
1316 mThreadManager.add(mThreadId, workersAux, queueIn++, queueOut++);
1322 if (!spWPoseExtractors.empty())
1324 if (mMultiThreadEnabled)
1326 for (
auto& wPose : spWPoseExtractors)
1329 mThreadManager.add(mThreadId, wPose, queueIn, queueOut);
1335 if (spWPoseExtractors.size() > 1u)
1337 const auto wQueueOrderer = std::make_shared<WQueueOrderer<TDatumsSP>>();
1339 mThreadManager.add(mThreadId, wQueueOrderer, queueIn++, queueOut++);
1345 if (spWPoseExtractors.size() > 1)
1346 log(
"Multi-threading disabled, only 1 thread running. All GPUs have been disabled but the"
1347 " first one, which is defined by gpuNumberStart (e.g. in the OpenPose demo, it is set"
1350 mThreadManager.add(mThreadId, spWPoseExtractors.at(0), queueIn++, queueOut++);
1354 const auto wQueueAssembler = std::make_shared<WQueueAssembler<TDatumsSP, TDatums>>();
1356 if (!spWPoseTriangulations.empty())
1360 mThreadManager.add(mThreadId, wQueueAssembler, queueIn++, queueOut++);
1363 if (mMultiThreadEnabled)
1365 for (
auto& wPoseTriangulations : spWPoseTriangulations)
1368 mThreadManager.add(mThreadId, wPoseTriangulations, queueIn, queueOut);
1374 if (spWPoseTriangulations.size() > 1u)
1376 const auto wQueueOrderer = std::make_shared<WQueueOrderer<TDatumsSP>>();
1378 mThreadManager.add(mThreadId, wQueueOrderer, queueIn++, queueOut++);
1384 if (spWPoseTriangulations.size() > 1)
1385 log(
"Multi-threading disabled, only 1 thread running for 3-D triangulation.",
1388 mThreadManager.add(mThreadId, spWPoseTriangulations.at(0), queueIn++, queueOut++);
1392 mPostProcessingWs =
mergeVectors({wQueueAssembler}, mPostProcessingWs);
1394 if (!spWJointAngleEstimations.empty())
1396 if (mMultiThreadEnabled)
1398 for (
auto& wJointAngleEstimator : spWJointAngleEstimations)
1401 mThreadManager.add(mThreadId, wJointAngleEstimator, queueIn, queueOut);
1407 if (spWJointAngleEstimations.size() > 1)
1409 const auto wQueueOrderer = std::make_shared<WQueueOrderer<TDatumsSP>>();
1411 mThreadManager.add(mThreadId, wQueueOrderer, queueIn++, queueOut++);
1417 if (spWJointAngleEstimations.size() > 1)
1418 log(
"Multi-threading disabled, only 1 thread running for joint angle estimation.",
1421 mThreadManager.add(mThreadId, spWJointAngleEstimations.at(0), queueIn++, queueOut++);
1425 if (!mPostProcessingWs.empty())
1428 mOutputWs =
mergeVectors(mPostProcessingWs, mOutputWs);
1435 if (!mUserPostProcessingWs.empty())
1438 if (mUserPostProcessingWsOnNewThread)
1441 mThreadManager.add(mThreadId, mUserPostProcessingWs, queueIn++, queueOut++);
1447 mOutputWs =
mergeVectors(mOutputWs, mUserPostProcessingWs);
1450 if (!mOutputWs.empty())
1454 mThreadManager.add(mThreadId, mOutputWs, queueIn++, queueOut++);
1459 if (!mUserOutputWs.empty())
1461 if (mUserOutputWsOnNewThread)
1464 mThreadManager.add(mThreadId, mUserOutputWs, queueIn++, queueOut++);
1470 mThreadManager.add(mThreadId-1, mUserOutputWs, queueIn++, queueOut++);
1474 if (spWGui !=
nullptr)
1478 mThreadManager.add(mThreadId, spWGui, queueIn++, queueOut++);
1483 catch (
const std::exception& e)
1485 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
1489 template<
typename TDatums,
typename TDatumsSP,
typename TWorker,
typename TQueue>
1490 unsigned long long Wrapper<TDatums, TDatumsSP, TWorker, TQueue>::threadIdPP()
1494 if (mMultiThreadEnabled)
1498 catch (
const std::exception& e)
1500 error(e.what(), __LINE__, __FUNCTION__, __FILE__);
1505 extern template class Wrapper<DATUM_BASE_NO_PTR>;
1508 #endif // OPENPOSE_WRAPPER_WRAPPER_HPP
Definition: wHandDetectorTracking.hpp:11
Definition: wGuiInfoAdder.hpp:11
Wrapper(const ThreadManagerMode threadManagerMode=ThreadManagerMode::Synchronous)
Definition: wrapper.hpp:283
float alphaHeatMap
Definition: wrapperStructFace.hpp:45
bool guiVerbose
Definition: wrapperStructOutput.hpp:31
std::string writeHeatMapsFormat
Definition: wrapperStructOutput.hpp:106
Definition: wPoseSaver.hpp:12
Definition: wrapperStructPose.hpp:17
void start()
Definition: wrapper.hpp:1077
std::string writeKeypoint
Definition: wrapperStructOutput.hpp:44
float alphaKeypoint
Definition: wrapperStructFace.hpp:39
Definition: wFaceSaver.hpp:12
float alphaKeypoint
Definition: wrapperStructHand.hpp:59
void exec()
Definition: wrapper.hpp:1062
Definition: wPeopleJsonSaver.hpp:11
Definition: wHandRenderer.hpp:11
double writeVideoFps
Definition: wrapperStructOutput.hpp:111
Definition: wImageSaver.hpp:11
std::string udpPort
Definition: wrapperStructOutput.hpp:135
std::string writeImages
Definition: wrapperStructOutput.hpp:78
void stop()
Definition: wrapper.hpp:1092
T fastMax(const T a, const T b)
Definition: fastMath.hpp:70
float alphaHeatMap
Definition: wrapperStructHand.hpp:65
Definition: wKeypointScaler.hpp:11
std::string writeHeatMaps
Definition: wrapperStructOutput.hpp:100
std::string writeCocoJson
Definition: wrapperStructOutput.hpp:67
Definition: wFaceDetector.hpp:11
void setWorkerPostProcessing(const TWorker &worker, const bool workerOnNewThread=true)
Definition: wrapper.hpp:348
bool waitAndPush(const TDatumsSP &tDatums)
Definition: wrapper.hpp:1170
Definition: wrapperStructFace.hpp:15
OP_API void error(const std::string &message, const int line=-1, const std::string &function="", const std::string &file="")
bool fullScreen
Definition: wrapperStructOutput.hpp:37
std::string udpHost
Definition: wrapperStructOutput.hpp:130
DataFormat writeKeypointFormat
Definition: wrapperStructOutput.hpp:51
std::string writeCocoFootJson
Definition: wrapperStructOutput.hpp:72
Definition: wrapper.hpp:34
float scaleRange
Definition: wrapperStructHand.hpp:40
OP_API GpuMode getGpuMode()
RenderMode renderMode
Definition: wrapperStructFace.hpp:33
bool tracking
Definition: wrapperStructHand.hpp:47
bool enable
Definition: wrapperStructFace.hpp:20
Definition: wFaceDetectorOpenCV.hpp:11
Definition: wVideoSaver.hpp:11
Definition: wUdpSender.hpp:11
Definition: wOpOutputToCvMat.hpp:11
bool waitAndEmplace(TDatumsSP &tDatums)
Definition: wrapper.hpp:1136
OP_API std::string formatAsDirectory(const std::string &directoryPathString)
bool tryPush(const TDatumsSP &tDatums)
Definition: wrapper.hpp:1153
Definition: wHandDetectorUpdate.hpp:11
void configure(const WrapperStructPose &wrapperStructPose, const WrapperStructInput &wrapperStructInput, const WrapperStructOutput &wrapperStructOutput=WrapperStructOutput{})
Definition: wrapper.hpp:384
bool waitAndPop(TDatumsSP &tDatums)
Definition: wrapper.hpp:1204
bool tryPop(TDatumsSP &tDatums)
Definition: wrapper.hpp:1187
Definition: wHandExtractorNet.hpp:11
std::string writeBvh
Definition: wrapperStructOutput.hpp:125
Definition: wFaceRenderer.hpp:11
bool tryEmplace(TDatumsSP &tDatums)
Definition: wrapper.hpp:1119
Definition: wPoseRenderer.hpp:11
std::string writeJson
Definition: wrapperStructOutput.hpp:61
OP_API void log(const std::string &message, const Priority priority=Priority::Max, const int line=-1, const std::string &function="", const std::string &file="")
Definition: wCocoJsonSaver.hpp:11
Definition: wrapperStructHand.hpp:15
float renderThreshold
Definition: wrapperStructHand.hpp:72
Definition: poseGpuRenderer.hpp:13
Definition: wHandDetector.hpp:11
std::string writeVideoAdam
Definition: wrapperStructOutput.hpp:118
std::vector< T > mergeVectors(const std::vector< T > &vectorA, const std::vector< T > &vectorB)
Definition: standard.hpp:40
Definition: wHandSaver.hpp:12
std::string writeVideo
Definition: wrapperStructOutput.hpp:93
DisplayMode displayMode
Definition: wrapperStructOutput.hpp:25
Point< int > netInputSize
Definition: wrapperStructFace.hpp:27
void setSharedParametersAndIfLast(const std::tuple< std::shared_ptr< float * >, std::shared_ptr< bool >, std::shared_ptr< std::atomic< unsigned int >>, std::shared_ptr< std::atomic< unsigned long long >>, std::shared_ptr< const unsigned int >> &tuple, const bool isLast)
Definition: wHeatMapSaver.hpp:11
bool enable
Definition: wrapperStructHand.hpp:20
ThreadManagerMode
Definition: enumClasses.hpp:9
void setWorkerInput(const TWorker &worker, const bool workerOnNewThread=true)
Definition: wrapper.hpp:330
OP_API void wrapperConfigureSecurityChecks(WrapperStructPose &wrapperStructPose, const WrapperStructFace &wrapperStructFace, const WrapperStructHand &wrapperStructHand, const WrapperStructExtra &wrapperStructExtra, const WrapperStructInput &wrapperStructInput, const WrapperStructOutput &wrapperStructOutput, const bool renderOutput, const bool userOutputWsEmpty, const ThreadManagerMode threadManagerMode)
float renderThreshold
Definition: wrapperStructFace.hpp:52
std::string writeImagesFormat
Definition: wrapperStructOutput.hpp:86
bool isRunning() const
Definition: wrapper.hpp:1105
Definition: wrapperStructOutput.hpp:14
void disableMultiThreading()
Definition: wrapper.hpp:317
OP_API int getGpuNumber()
Point< int > netInputSize
Definition: wrapperStructHand.hpp:27
~Wrapper()
Definition: wrapper.hpp:303
void setWorkerOutput(const TWorker &worker, const bool workerOnNewThread=true)
Definition: wrapper.hpp:366
int scalesNumber
Definition: wrapperStructHand.hpp:34
RenderMode renderMode
Definition: wrapperStructHand.hpp:53