| | #ifndef OPENPOSE_WRAPPER_WRAPPER_HAND_FROM_JSON_TEST_HPP |
| | #define OPENPOSE_WRAPPER_WRAPPER_HAND_FROM_JSON_TEST_HPP |
| |
|
| | |
| | #include <opencv2/opencv.hpp> |
| | |
| | #include <openpose/headers.hpp> |
| |
|
| | namespace op |
| | { |
| | template<typename TDatum, |
| | typename TDatums = std::vector<std::shared_ptr<TDatum>>, |
| | typename TWorker = std::shared_ptr<Worker<std::shared_ptr<TDatums>>>, |
| | typename TQueue = Queue<std::shared_ptr<TDatums>>> |
| | class WrapperHandFromJsonTest |
| | { |
| | public: |
| | |
| | |
| | |
| | explicit WrapperHandFromJsonTest(); |
| |
|
| | |
| | |
| | |
| | |
| | ~WrapperHandFromJsonTest(); |
| |
|
| | void configure(const WrapperStructPose& wrapperStructPose, |
| | const WrapperStructHand& wrapperStructHand, |
| | const std::shared_ptr<Producer>& producerSharedPtr, |
| | const std::string& handGroundTruth, |
| | const std::string& writeJson, |
| | const DisplayMode displayMode = DisplayMode::NoDisplay); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | void exec(); |
| |
|
| | private: |
| | ThreadManager<std::shared_ptr<TDatums>> mThreadManager; |
| | |
| | TWorker wDatumProducer; |
| | TWorker spWIdGenerator; |
| | TWorker spWScaleAndSizeExtractor; |
| | TWorker spWCvMatToOpInput; |
| | TWorker spWCvMatToOpOutput; |
| | std::vector<std::vector<TWorker>> spWPoses; |
| | std::vector<TWorker> mPostProcessingWs; |
| | std::vector<TWorker> mOutputWs; |
| | TWorker spWGui; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | void reset(); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | void configureThreadManager(); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | std::vector<TWorker> mergeWorkers(const std::vector<TWorker>& workersA, const std::vector<TWorker>& workersB); |
| |
|
| | DELETE_COPY(WrapperHandFromJsonTest); |
| | }; |
| | } |
| |
|
| |
|
| |
|
| |
|
| |
|
| | |
| | #include <openpose/core/headers.hpp> |
| | #include <openpose/face/headers.hpp> |
| | #include <openpose/filestream/headers.hpp> |
| | #include <openpose/gui/headers.hpp> |
| | #include <openpose/gpu/gpu.hpp> |
| | #include <openpose/hand/headers.hpp> |
| | #include <openpose/pose/headers.hpp> |
| | #include <openpose/producer/headers.hpp> |
| | #include <openpose/utilities/errorAndLog.hpp> |
| | #include <openpose/utilities/fileSystem.hpp> |
| | namespace op |
| | { |
| | template<typename TDatum, typename TDatums, typename TWorker, typename TQueue> |
| | WrapperHandFromJsonTest<TDatum, TDatums, TWorker, TQueue>::WrapperHandFromJsonTest() |
| | { |
| | } |
| |
|
| | template<typename TDatum, typename TDatums, typename TWorker, typename TQueue> |
| | WrapperHandFromJsonTest<TDatum, TDatums, TWorker, TQueue>::~WrapperHandFromJsonTest() |
| | { |
| | try |
| | { |
| | mThreadManager.stop(); |
| | reset(); |
| | } |
| | catch (const std::exception& e) |
| | { |
| | errorDestructor(e.what(), __LINE__, __FUNCTION__, __FILE__); |
| | } |
| | } |
| |
|
| | template<typename TDatum, typename TDatums, typename TWorker, typename TQueue> |
| | void WrapperHandFromJsonTest<TDatum, TDatums, TWorker, TQueue>::configure( |
| | const WrapperStructPose& wrapperStructPose, |
| | const WrapperStructHand& wrapperStructHand, |
| | const std::shared_ptr<Producer>& producerSharedPtr, |
| | const std::string& handGroundTruth, |
| | const std::string& writeJson, |
| | const DisplayMode displayMode) |
| | { |
| | try |
| | { |
| | opLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); |
| |
|
| | |
| | typedef std::shared_ptr<TDatums> TDatumsPtr; |
| |
|
| | |
| | if (wrapperStructPose.scaleGap <= 0.f && wrapperStructPose.scalesNumber > 1) |
| | error("The scale gap must be greater than 0 (it has no effect if the number of scales is 1).", |
| | __LINE__, __FUNCTION__, __FILE__); |
| | const std::string additionalMessage = " You could also set mThreadManagerMode = mThreadManagerMode::Asynchronous(Out)" |
| | " and/or add your own output worker class before calling this function."; |
| | const auto savingSomething = !writeJson.empty(); |
| | const auto displayGui = (displayMode != DisplayMode::NoDisplay); |
| | if (!displayGui && !savingSomething) |
| | { |
| | const auto message = "No output is selected (`--display 0`) and no results are generated (no `write_X` flags enabled). Thus," |
| | " no output would be generated." + additionalMessage; |
| | error(message, __LINE__, __FUNCTION__, __FILE__); |
| | } |
| |
|
| | |
| | auto gpuNumber = wrapperStructPose.gpuNumber; |
| | auto gpuNumberStart = wrapperStructPose.gpuNumberStart; |
| | |
| | if (gpuNumber < 0) |
| | { |
| | |
| | gpuNumber = getGpuNumber(); |
| | |
| | gpuNumberStart = 0; |
| | |
| | opLog("Auto-detecting GPUs... Detected " + std::to_string(gpuNumber) + " GPU(s), using them all.", Priority::High); |
| | } |
| |
|
| | |
| | const auto writeJsonCleaned = formatAsDirectory(writeJson); |
| |
|
| | |
| | const auto finalOutputSize = wrapperStructPose.outputSize; |
| | const Point<int> producerSize{ |
| | (int)producerSharedPtr->get(getCvCapPropFrameWidth()), |
| | (int)producerSharedPtr->get(getCvCapPropFrameHeight())}; |
| | if (finalOutputSize.x == -1 || finalOutputSize.y == -1) |
| | { |
| | const auto message = "Output resolution cannot be (-1 x -1) unless producerSharedPtr is also set."; |
| | error(message, __LINE__, __FUNCTION__, __FILE__); |
| | } |
| |
|
| | |
| | const auto datumProducer = std::make_shared<DatumProducer<TDatum>>(producerSharedPtr); |
| | wDatumProducer = std::make_shared<WDatumProducer<TDatum>>(datumProducer); |
| |
|
| | |
| | const auto scaleAndSizeExtractor = std::make_shared<ScaleAndSizeExtractor>( |
| | wrapperStructPose.netInputSize, (float)wrapperStructPose.netInputSizeDynamicBehavior, finalOutputSize, |
| | wrapperStructPose.scalesNumber, wrapperStructPose.scaleGap); |
| | spWScaleAndSizeExtractor = std::make_shared<WScaleAndSizeExtractor<TDatumsPtr>>(scaleAndSizeExtractor); |
| |
|
| | |
| | const auto cvMatToOpInput = std::make_shared<CvMatToOpInput>(wrapperStructPose.poseModel); |
| | spWCvMatToOpInput = std::make_shared<WCvMatToOpInput<TDatumsPtr>>(cvMatToOpInput); |
| | if (displayGui) |
| | { |
| | const auto cvMatToOpOutput = std::make_shared<CvMatToOpOutput>(); |
| | spWCvMatToOpOutput = std::make_shared<WCvMatToOpOutput<TDatumsPtr>>(cvMatToOpOutput); |
| | } |
| |
|
| | |
| | if (wrapperStructHand.enable) |
| | { |
| | spWPoses.resize(gpuNumber); |
| | const auto handDetector = std::make_shared<HandDetectorFromTxt>(handGroundTruth); |
| | for (auto gpuId = 0u; gpuId < spWPoses.size(); gpuId++) |
| | { |
| | |
| | |
| | if (wrapperStructHand.detector == Detector::BodyWithTracking) |
| | error("Tracking not valid for hand detector from JSON files.", __LINE__, __FUNCTION__, __FILE__); |
| | |
| | else |
| | spWPoses.at(gpuId) = {std::make_shared<WHandDetectorFromTxt<TDatumsPtr>>(handDetector)}; |
| | |
| | const auto netOutputSize = wrapperStructHand.netInputSize; |
| | const auto handExtractor = std::make_shared<HandExtractorCaffe>( |
| | wrapperStructHand.netInputSize, netOutputSize, wrapperStructPose.modelFolder.getStdString(), |
| | gpuId + gpuNumberStart, wrapperStructHand.scalesNumber, wrapperStructHand.scaleRange |
| | ); |
| | spWPoses.at(gpuId).emplace_back(std::make_shared<WHandExtractorNet<TDatumsPtr>>(handExtractor)); |
| | } |
| | } |
| |
|
| | |
| | std::vector<TWorker> cpuRenderers; |
| | if (displayGui) |
| | { |
| | |
| | const auto handRenderer = std::make_shared<HandCpuRenderer>(wrapperStructHand.renderThreshold, |
| | wrapperStructHand.alphaKeypoint, |
| | wrapperStructHand.alphaHeatMap); |
| | |
| | cpuRenderers.emplace_back(std::make_shared<WHandRenderer<TDatumsPtr>>(handRenderer)); |
| | } |
| |
|
| | |
| | mPostProcessingWs.clear(); |
| | |
| | if (spWPoses.size() > 1) |
| | mPostProcessingWs.emplace_back(std::make_shared<WQueueOrderer<TDatumsPtr>>()); |
| | |
| | if (displayGui) |
| | { |
| | mPostProcessingWs = mergeWorkers(mPostProcessingWs, cpuRenderers); |
| | const auto opOutputToCvMat = std::make_shared<OpOutputToCvMat>(); |
| | mPostProcessingWs.emplace_back(std::make_shared<WOpOutputToCvMat<TDatumsPtr>>(opOutputToCvMat)); |
| | } |
| | |
| | if (wrapperStructPose.keypointScaleMode != ScaleMode::InputResolution) |
| | error("Only wrapperStructPose.keypointScaleMode == ScaleMode::InputResolution.", |
| | __LINE__, __FUNCTION__, __FILE__); |
| |
|
| | mOutputWs.clear(); |
| | |
| | if (!writeJsonCleaned.empty()) |
| | { |
| | const auto jsonSaver = std::make_shared<PeopleJsonSaver>(writeJsonCleaned); |
| | mOutputWs.emplace_back(std::make_shared<WPeopleJsonSaver<TDatumsPtr>>(jsonSaver)); |
| | } |
| | |
| | spWGui = nullptr; |
| | if (displayGui) |
| | { |
| | const auto guiInfoAdder = std::make_shared<GuiInfoAdder>(gpuNumber, displayGui); |
| | mOutputWs.emplace_back(std::make_shared<WGuiInfoAdder<TDatumsPtr>>(guiInfoAdder)); |
| | const auto gui = std::make_shared<Gui>( |
| | finalOutputSize, false, mThreadManager.getIsRunningSharedPtr() |
| | ); |
| | spWGui = {std::make_shared<WGui<TDatumsPtr>>(gui)}; |
| | } |
| | opLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); |
| | } |
| | catch (const std::exception& e) |
| | { |
| | error(e.what(), __LINE__, __FUNCTION__, __FILE__); |
| | } |
| | } |
| |
|
| | template<typename TDatum, typename TDatums, typename TWorker, typename TQueue> |
| | void WrapperHandFromJsonTest<TDatum, TDatums, TWorker, TQueue>::exec() |
| | { |
| | try |
| | { |
| | configureThreadManager(); |
| | mThreadManager.exec(); |
| | } |
| | catch (const std::exception& e) |
| | { |
| | error(e.what(), __LINE__, __FUNCTION__, __FILE__); |
| | } |
| | } |
| |
|
| | template<typename TDatum, typename TDatums, typename TWorker, typename TQueue> |
| | void WrapperHandFromJsonTest<TDatum, TDatums, TWorker, TQueue>::reset() |
| | { |
| | try |
| | { |
| | mThreadManager.reset(); |
| | |
| | wDatumProducer = nullptr; |
| | spWScaleAndSizeExtractor = nullptr; |
| | spWCvMatToOpInput = nullptr; |
| | spWCvMatToOpOutput = nullptr; |
| | spWPoses.clear(); |
| | mPostProcessingWs.clear(); |
| | mOutputWs.clear(); |
| | spWGui = nullptr; |
| | } |
| | catch (const std::exception& e) |
| | { |
| | error(e.what(), __LINE__, __FUNCTION__, __FILE__); |
| | } |
| | } |
| |
|
| | template<typename TDatum, typename TDatums, typename TWorker, typename TQueue> |
| | void WrapperHandFromJsonTest<TDatum, TDatums, TWorker, TQueue>::configureThreadManager() |
| | { |
| | try |
| | { |
| | |
| | if (spWCvMatToOpInput == nullptr) |
| | error("Configure the WrapperHandFromJsonTest class before calling `start()`.", |
| | __LINE__, __FUNCTION__, __FILE__); |
| | if (wDatumProducer == nullptr) |
| | { |
| | const auto message = "You need to use the OpenPose default producer."; |
| | error(message, __LINE__, __FUNCTION__, __FILE__); |
| | } |
| | if (mOutputWs.empty() && spWGui == nullptr) |
| | { |
| | error("No output selected.", __LINE__, __FUNCTION__, __FILE__); |
| | } |
| |
|
| | |
| | |
| | mThreadManager.reset(); |
| | auto threadId = 0ull; |
| | auto queueIn = 0ull; |
| | auto queueOut = 1ull; |
| | |
| | spWIdGenerator = std::make_shared<WIdGenerator<std::shared_ptr<TDatums>>>(); |
| | |
| | |
| | if (spWCvMatToOpOutput == nullptr) |
| | mThreadManager.add(threadId++, {wDatumProducer, spWIdGenerator, spWScaleAndSizeExtractor, |
| | spWCvMatToOpInput}, queueIn++, queueOut++); |
| | else |
| | mThreadManager.add(threadId++, {wDatumProducer, spWIdGenerator, spWScaleAndSizeExtractor, |
| | spWCvMatToOpInput, spWCvMatToOpOutput}, queueIn++, queueOut++); |
| | |
| | |
| | if (!spWPoses.empty()) |
| | { |
| | for (auto& wPose : spWPoses) |
| | mThreadManager.add(threadId++, wPose, queueIn, queueOut); |
| | queueIn++; |
| | queueOut++; |
| | } |
| | |
| | |
| | |
| | mThreadManager.add(threadId++, mergeWorkers(mPostProcessingWs, mOutputWs), queueIn++, queueOut++); |
| | |
| | |
| | if (spWGui != nullptr) |
| | mThreadManager.add(threadId++, spWGui, queueIn++, queueOut++); |
| | opLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); |
| | } |
| | catch (const std::exception& e) |
| | { |
| | error(e.what(), __LINE__, __FUNCTION__, __FILE__); |
| | } |
| | } |
| |
|
| | template<typename TDatum, typename TDatums, typename TWorker, typename TQueue> |
| | std::vector<TWorker> WrapperHandFromJsonTest<TDatum, TDatums, TWorker, TQueue>::mergeWorkers(const std::vector<TWorker>& workersA, const std::vector<TWorker>& workersB) |
| | { |
| | try |
| | { |
| | auto workersToReturn(workersA); |
| | for (auto& worker : workersB) |
| | workersToReturn.emplace_back(worker); |
| | return workersToReturn; |
| | } |
| | catch (const std::exception& e) |
| | { |
| | error(e.what(), __LINE__, __FUNCTION__, __FILE__); |
| | return std::vector<TWorker>{}; |
| | } |
| | } |
| | } |
| |
|
| | #endif |
| |
|