mirror of
https://github.com/gosticks/openpose.git
synced 2026-08-12 04:10:28 +00:00
Wrapper template simplified
This commit is contained in:
@@ -8,7 +8,7 @@ In order to add a new module, these are the recommended steps in order to develo
|
||||
2. Implement all the functionality in one `Worker`. I.e., inherit from `Worker` and implement all the functionality on that class (copy the examples from any Worker subclass).
|
||||
1. The first letter of the class name should be `W` (e.g., `WHairExtractor`).
|
||||
2. To initially simplify development:
|
||||
1. Optionally (higher debug info), you might initially create the Worker as a non-templated class, assuming it uses std::shared_ptr<std::vector<op::Datum>> instead of directly using a template class (following the `examples/tutorial_api_cpp` synchronous examples). While developing, templates provide more confusing debugging info. Turn the class into a template after being initially developed.
|
||||
1. Optionally (higher debug info), you might initially create the Worker as a non-templated class, assuming it uses std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>> instead of directly using a template class (following the `examples/tutorial_api_cpp` synchronous examples). While developing, templates provide more confusing debugging info. Turn the class into a template after being initially developed.
|
||||
2. Optionally (for development speed), use op::Datum as unique argument of your auxiliary functions within that worker.
|
||||
3. Use the OpenPose Wrapper class in ThreadManagerMode::SingleThread mode (e.g., it allows you to directly use cv::imshow).
|
||||
4. If you are using your own custom Caffe -> initially change the Caffe for your version. It should directly work.
|
||||
|
||||
@@ -70,8 +70,8 @@ The `Datum` class has all the variables that our Workers need to share to each o
|
||||
UserDatum : public op::Datum {/* op::Datum + extra variables */}
|
||||
|
||||
// Worker and ThreadManager example initialization
|
||||
op::WGui<std::shared_ptr<std::vector<UserDatum>> userGUI(/* constructor arguments */);
|
||||
op::ThreadManager<std::shared_ptr<std::vector<UserDatum>> userThreadManager;
|
||||
op::WGui<std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>> userGUI(/* constructor arguments */);
|
||||
op::ThreadManager<std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>> userThreadManager;
|
||||
```
|
||||
|
||||
Since `UserDatum` inherits from `op::Datum`, all the original OpenPose code will compile and run with your inherited version of `op::Datum`.
|
||||
@@ -83,7 +83,7 @@ Since `UserDatum` inherits from `op::Datum`, all the original OpenPose code will
|
||||
It manages and automates the multi-threading configuration and execution. The user just needs to add the desired Worker<T> classes to be executed and the parallelization mode, and this class will take care of it.
|
||||
|
||||
#### Constructor
|
||||
Just call `op::ThreadManager<TypedefDatums> threadManager`.
|
||||
Just call `op::ThreadManager<TypedefDatumsSP> threadManager`.
|
||||
|
||||
#### Adding a Worker Sequence
|
||||
There are 4 ways to add sequence of workers:
|
||||
@@ -171,7 +171,7 @@ All Workers wrap and call a non-Worker non-template equivalent which actually pe
|
||||
|
||||
By separating functionality and their `Worker<T>` wrappers, we get the good of both points, eliminating the cons. In this way, the user is able to:
|
||||
|
||||
1. Change `std::shared_ptr<std::vector<op::Datum>>` for a custom class, implementing his own `Worker` templates, but using the already implemented functionality to create new custom `Worker` templates.
|
||||
1. Change `std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>` for a custom class, implementing his own `Worker` templates, but using the already implemented functionality to create new custom `Worker` templates.
|
||||
|
||||
2. Create a `Worker` which wraps several non-`Worker`s classes.
|
||||
|
||||
|
||||
@@ -316,6 +316,7 @@ OpenPose Library - Release Notes
|
||||
10. Renamed `--camera_parameter_folder` as `--camera_parameter_path` because it could also take a whole XML file path rather than its parent folder.
|
||||
11. Default value of flag `--scale_gap` changed from 0.3 to 0.25.
|
||||
12. Moved most sh scripts into the `scripts/` folder. Only models/getModels.sh and the *.bat files are kept under `models/` and `3rdparty/windows`.
|
||||
13. For Python compatibility and scalability increase, template `TDatums` used for `include/openpose/wrapper/wrapper.hpp` has changed from `std::vector<Datum>` to `std::vector<std::shared_ptr<Datum>>`, including the respective changes in all the worker classes. In addition, some template classes have been simplified to only take 1 template parameter for user simplicity.
|
||||
3. Main bugs fixed:
|
||||
1. CMake-GUI was forcing to Release mode, allowed Debug modes too.
|
||||
2. NMS returns in index 0 the number of found peaks. However, while the number of peaks was truncated to a maximum of 127, this index 0 was saving the real number instead of the truncated one.
|
||||
|
||||
@@ -49,7 +49,7 @@ int handFromJsonTest()
|
||||
|
||||
// OpenPose wrapper
|
||||
op::log("Configuring OpenPose...", op::Priority::High);
|
||||
op::WrapperHandFromJsonTest<std::vector<op::Datum>> opWrapper;
|
||||
op::WrapperHandFromJsonTest<op::Datum> opWrapper;
|
||||
// Pose configuration (use WrapperStructPose{} for default and recommended configuration)
|
||||
op::WrapperStructPose wrapperStructPose{false, op::flagsToPoint("656x368"), op::flagsToPoint("1280x720"),
|
||||
op::ScaleMode::InputResolution, FLAGS_num_gpu, FLAGS_num_gpu_start,
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
namespace op
|
||||
{
|
||||
template<typename TDatums,
|
||||
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
|
||||
@@ -95,13 +96,13 @@ namespace op
|
||||
#include <openpose/utilities/fileSystem.hpp>
|
||||
namespace op
|
||||
{
|
||||
template<typename TDatums, typename TWorker, typename TQueue>
|
||||
WrapperHandFromJsonTest<TDatums, TWorker, TQueue>::WrapperHandFromJsonTest()
|
||||
template<typename TDatum, typename TDatums, typename TWorker, typename TQueue>
|
||||
WrapperHandFromJsonTest<TDatum, TDatums, TWorker, TQueue>::WrapperHandFromJsonTest()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TWorker, typename TQueue>
|
||||
WrapperHandFromJsonTest<TDatums, TWorker, TQueue>::~WrapperHandFromJsonTest()
|
||||
template<typename TDatum, typename TDatums, typename TWorker, typename TQueue>
|
||||
WrapperHandFromJsonTest<TDatum, TDatums, TWorker, TQueue>::~WrapperHandFromJsonTest()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -114,13 +115,14 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TWorker, typename TQueue>
|
||||
void WrapperHandFromJsonTest<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)
|
||||
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
|
||||
{
|
||||
@@ -172,8 +174,8 @@ namespace op
|
||||
}
|
||||
|
||||
// Producer
|
||||
const auto datumProducer = std::make_shared<DatumProducer<TDatums>>(producerSharedPtr);
|
||||
wDatumProducer = std::make_shared<WDatumProducer<TDatumsPtr, TDatums>>(datumProducer);
|
||||
const auto datumProducer = std::make_shared<DatumProducer<TDatum>>(producerSharedPtr);
|
||||
wDatumProducer = std::make_shared<WDatumProducer<TDatum>>(datumProducer);
|
||||
|
||||
// Get input scales and sizes
|
||||
const auto scaleAndSizeExtractor = std::make_shared<ScaleAndSizeExtractor>(
|
||||
@@ -269,8 +271,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TWorker, typename TQueue>
|
||||
void WrapperHandFromJsonTest<TDatums, TWorker, TQueue>::exec()
|
||||
template<typename TDatum, typename TDatums, typename TWorker, typename TQueue>
|
||||
void WrapperHandFromJsonTest<TDatum, TDatums, TWorker, TQueue>::exec()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -283,8 +285,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TWorker, typename TQueue>
|
||||
void WrapperHandFromJsonTest<TDatums, TWorker, TQueue>::reset()
|
||||
template<typename TDatum, typename TDatums, typename TWorker, typename TQueue>
|
||||
void WrapperHandFromJsonTest<TDatum, TDatums, TWorker, TQueue>::reset()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -305,8 +307,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TWorker, typename TQueue>
|
||||
void WrapperHandFromJsonTest<TDatums, TWorker, TQueue>::configureThreadManager()
|
||||
template<typename TDatum, typename TDatums, typename TWorker, typename TQueue>
|
||||
void WrapperHandFromJsonTest<TDatum, TDatums, TWorker, TQueue>::configureThreadManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -365,8 +367,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TWorker, typename TQueue>
|
||||
std::vector<TWorker> WrapperHandFromJsonTest<TDatums, TWorker, TQueue>::mergeWorkers(const std::vector<TWorker>& workersA, const std::vector<TWorker>& workersB)
|
||||
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
|
||||
{
|
||||
|
||||
@@ -78,7 +78,7 @@ int tutorialAddModule1()
|
||||
|
||||
// OpenPose wrapper
|
||||
op::log("Configuring OpenPose...", op::Priority::High);
|
||||
op::WrapperT<std::vector<op::UserDatum>> opWrapperT;
|
||||
op::WrapperT<op::UserDatum> opWrapperT;
|
||||
// Pose configuration (use WrapperStructPose{} for default and recommended configuration)
|
||||
const op::WrapperStructPose wrapperStructPose{
|
||||
!FLAGS_body_disable, netInputSize, outputSize, keypointScale, FLAGS_num_gpu, FLAGS_num_gpu_start,
|
||||
@@ -124,7 +124,7 @@ int tutorialAddModule1()
|
||||
|
||||
// Custom post-processing
|
||||
auto userPostProcessing = std::make_shared<op::UserPostProcessing>(/* Your class arguments here */);
|
||||
auto wUserPostProcessing = std::make_shared<op::WUserPostProcessing<std::shared_ptr<std::vector<op::UserDatum>>>>(
|
||||
auto wUserPostProcessing = std::make_shared<op::WUserPostProcessing<std::shared_ptr<std::vector<std::shared_ptr<op::UserDatum>>>>>(
|
||||
userPostProcessing
|
||||
);
|
||||
// Add custom processing
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace op
|
||||
for (auto& datum : *tDatums)
|
||||
// THIS IS THE ONLY LINE THAT THE USER MUST MODIFY ON THIS HPP FILE, by using the proper function
|
||||
// and datum elements
|
||||
spUserPostProcessing->doSomething(datum.cvOutputData, datum.cvOutputData);
|
||||
spUserPostProcessing->doSomething(datum->cvOutputData, datum->cvOutputData);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -13,7 +13,7 @@ DEFINE_string(image_path, "examples/media/COCO_val2014_000000000192.jpg",
|
||||
"Process an image. Read all standard formats (jpg, png, bmp, etc.).");
|
||||
|
||||
// This worker will just read and return all the jpg files in a directory
|
||||
void display(const std::shared_ptr<std::vector<op::Datum>>& datumsPtr)
|
||||
void display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& datumsPtr)
|
||||
{
|
||||
// User's displaying/saving/other processing here
|
||||
// datum.cvOutputData: rendered frame with pose or heatmaps
|
||||
@@ -21,20 +21,20 @@ void display(const std::shared_ptr<std::vector<op::Datum>>& datumsPtr)
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
{
|
||||
// Display image
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0).cvOutputData);
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
|
||||
cv::waitKey(0);
|
||||
}
|
||||
else
|
||||
op::log("Nullptr or empty datumsPtr found.", op::Priority::High);
|
||||
}
|
||||
|
||||
void printKeypoints(const std::shared_ptr<std::vector<op::Datum>>& datumsPtr)
|
||||
void printKeypoints(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& datumsPtr)
|
||||
{
|
||||
// Example: How to use the pose keypoints
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
{
|
||||
// Alternative 1
|
||||
op::log("Body keypoints: " + datumsPtr->at(0).poseKeypoints.toString());
|
||||
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString());
|
||||
|
||||
// // Alternative 2
|
||||
// op::log(datumsPtr->at(0).poseKeypoints);
|
||||
|
||||
@@ -13,7 +13,7 @@ DEFINE_string(image_path, "examples/media/COCO_val2014_000000000241.jpg",
|
||||
"Process an image. Read all standard formats (jpg, png, bmp, etc.).");
|
||||
|
||||
// This worker will just read and return all the jpg files in a directory
|
||||
void display(const std::shared_ptr<std::vector<op::Datum>>& datumsPtr)
|
||||
void display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& datumsPtr)
|
||||
{
|
||||
// User's displaying/saving/other processing here
|
||||
// datum.cvOutputData: rendered frame with pose or heatmaps
|
||||
@@ -21,22 +21,22 @@ void display(const std::shared_ptr<std::vector<op::Datum>>& datumsPtr)
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
{
|
||||
// Display image
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0).cvOutputData);
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
|
||||
cv::waitKey(0);
|
||||
}
|
||||
else
|
||||
op::log("Nullptr or empty datumsPtr found.", op::Priority::High);
|
||||
}
|
||||
|
||||
void printKeypoints(const std::shared_ptr<std::vector<op::Datum>>& datumsPtr)
|
||||
void printKeypoints(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& datumsPtr)
|
||||
{
|
||||
// Example: How to use the pose keypoints
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
{
|
||||
op::log("Body keypoints: " + datumsPtr->at(0).poseKeypoints.toString());
|
||||
op::log("Face keypoints: " + datumsPtr->at(0).faceKeypoints.toString());
|
||||
op::log("Left hand keypoints: " + datumsPtr->at(0).handKeypoints[0].toString());
|
||||
op::log("Right hand keypoints: " + datumsPtr->at(0).handKeypoints[1].toString());
|
||||
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString());
|
||||
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString());
|
||||
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString());
|
||||
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString());
|
||||
}
|
||||
else
|
||||
op::log("Nullptr or empty datumsPtr found.", op::Priority::High);
|
||||
|
||||
@@ -15,7 +15,7 @@ DEFINE_string(image_path, "examples/media/COCO_val2014_000000000294.jpg",
|
||||
"Process an image. Read all standard formats (jpg, png, bmp, etc.).");
|
||||
|
||||
// This worker will just read and return all the jpg files in a directory
|
||||
void display(const std::shared_ptr<std::vector<op::Datum>>& datumsPtr)
|
||||
void display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& datumsPtr)
|
||||
{
|
||||
// User's displaying/saving/other processing here
|
||||
// datum.cvOutputData: rendered frame with pose or heatmaps
|
||||
@@ -23,22 +23,22 @@ void display(const std::shared_ptr<std::vector<op::Datum>>& datumsPtr)
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
{
|
||||
// Display image
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0).cvOutputData);
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
|
||||
cv::waitKey(0);
|
||||
}
|
||||
else
|
||||
op::log("Nullptr or empty datumsPtr found.", op::Priority::High);
|
||||
}
|
||||
|
||||
void printKeypoints(const std::shared_ptr<std::vector<op::Datum>>& datumsPtr)
|
||||
void printKeypoints(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& datumsPtr)
|
||||
{
|
||||
// Example: How to use the pose keypoints
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
{
|
||||
op::log("Body keypoints: " + datumsPtr->at(0).poseKeypoints.toString());
|
||||
op::log("Face keypoints: " + datumsPtr->at(0).faceKeypoints.toString());
|
||||
op::log("Left hand keypoints: " + datumsPtr->at(0).handKeypoints[0].toString());
|
||||
op::log("Right hand keypoints: " + datumsPtr->at(0).handKeypoints[1].toString());
|
||||
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString());
|
||||
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString());
|
||||
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString());
|
||||
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString());
|
||||
}
|
||||
else
|
||||
op::log("Nullptr or empty datumsPtr found.", op::Priority::High);
|
||||
|
||||
@@ -29,7 +29,8 @@ DEFINE_string(image_dir, "examples/media/",
|
||||
|
||||
// If the user needs his own variables, he can inherit the op::Datum struct and add them in there.
|
||||
// UserDatum can be directly used by the OpenPose wrapper because it inherits from op::Datum, just define
|
||||
// WrapperT<std::vector<UserDatum>> instead of Wrapper (or equivalently WrapperT<std::vector<UserDatum>>)
|
||||
// WrapperT<std::vector<std::shared_ptr<UserDatum>>> instead of Wrapper
|
||||
// (or equivalently WrapperT<std::vector<std::shared_ptr<UserDatum>>>)
|
||||
struct UserDatum : public op::Datum
|
||||
{
|
||||
bool boolThatUserNeedsForSomeReason;
|
||||
@@ -58,7 +59,7 @@ public:
|
||||
op::error("No images found on: " + directoryPath, __LINE__, __FUNCTION__, __FILE__);
|
||||
}
|
||||
|
||||
std::shared_ptr<std::vector<UserDatum>> createDatum()
|
||||
std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>> createDatum()
|
||||
{
|
||||
// Close program when empty frame
|
||||
if (mClosed || mImageFiles.size() <= mCounter)
|
||||
@@ -72,15 +73,15 @@ public:
|
||||
else // if (!mClosed)
|
||||
{
|
||||
// Create new datum
|
||||
auto datumsPtr = std::make_shared<std::vector<UserDatum>>();
|
||||
auto datumsPtr = std::make_shared<std::vector<std::shared_ptr<UserDatum>>>();
|
||||
datumsPtr->emplace_back();
|
||||
auto& datum = datumsPtr->at(0);
|
||||
auto& datumPtr = datumsPtr->at(0);
|
||||
|
||||
// Fill datum
|
||||
datum.cvInputData = cv::imread(mImageFiles.at(mCounter++));
|
||||
datumPtr->cvInputData = cv::imread(mImageFiles.at(mCounter++));
|
||||
|
||||
// If empty frame -> return nullptr
|
||||
if (datum.cvInputData.empty())
|
||||
if (datumPtr->cvInputData.empty())
|
||||
{
|
||||
op::log("Empty frame detected on path: " + mImageFiles.at(mCounter-1) + ". Closing program.",
|
||||
op::Priority::High);
|
||||
@@ -107,15 +108,15 @@ private:
|
||||
class UserOutputClass
|
||||
{
|
||||
public:
|
||||
bool display(const std::shared_ptr<std::vector<UserDatum>>& datumsPtr)
|
||||
bool display(const std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>& datumsPtr)
|
||||
{
|
||||
// User's displaying/saving/other processing here
|
||||
// datum.cvOutputData: rendered frame with pose or heatmaps
|
||||
// datum.poseKeypoints: Array<float> with the estimated pose
|
||||
// datumPtr->cvOutputData: rendered frame with pose or heatmaps
|
||||
// datumPtr->poseKeypoints: Array<float> with the estimated pose
|
||||
char key = ' ';
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
{
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0).cvOutputData);
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
|
||||
// Display image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
|
||||
key = (char)cv::waitKey(1);
|
||||
}
|
||||
@@ -123,14 +124,14 @@ public:
|
||||
op::log("Nullptr or empty datumsPtr found.", op::Priority::High, __LINE__, __FUNCTION__, __FILE__);
|
||||
return (key == 27);
|
||||
}
|
||||
void printKeypoints(const std::shared_ptr<std::vector<UserDatum>>& datumsPtr)
|
||||
void printKeypoints(const std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>& datumsPtr)
|
||||
{
|
||||
// Example: How to use the pose keypoints
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
{
|
||||
op::log("\nKeypoints:");
|
||||
// Accesing each element of the keypoints
|
||||
const auto& poseKeypoints = datumsPtr->at(0).poseKeypoints;
|
||||
const auto& poseKeypoints = datumsPtr->at(0)->poseKeypoints;
|
||||
op::log("Person pose keypoints:");
|
||||
for (auto person = 0 ; person < poseKeypoints.getSize(0) ; person++)
|
||||
{
|
||||
@@ -145,22 +146,22 @@ public:
|
||||
}
|
||||
op::log(" ");
|
||||
// Alternative: just getting std::string equivalent
|
||||
op::log("Face keypoints: " + datumsPtr->at(0).faceKeypoints.toString());
|
||||
op::log("Left hand keypoints: " + datumsPtr->at(0).handKeypoints[0].toString());
|
||||
op::log("Right hand keypoints: " + datumsPtr->at(0).handKeypoints[1].toString());
|
||||
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString());
|
||||
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString());
|
||||
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString());
|
||||
// Heatmaps
|
||||
const auto& poseHeatMaps = datumsPtr->at(0).poseHeatMaps;
|
||||
const auto& poseHeatMaps = datumsPtr->at(0)->poseHeatMaps;
|
||||
if (!poseHeatMaps.empty())
|
||||
{
|
||||
op::log("Pose heatmaps size: [" + std::to_string(poseHeatMaps.getSize(0)) + ", "
|
||||
+ std::to_string(poseHeatMaps.getSize(1)) + ", "
|
||||
+ std::to_string(poseHeatMaps.getSize(2)) + "]");
|
||||
const auto& faceHeatMaps = datumsPtr->at(0).faceHeatMaps;
|
||||
const auto& faceHeatMaps = datumsPtr->at(0)->faceHeatMaps;
|
||||
op::log("Face heatmaps size: [" + std::to_string(faceHeatMaps.getSize(0)) + ", "
|
||||
+ std::to_string(faceHeatMaps.getSize(1)) + ", "
|
||||
+ std::to_string(faceHeatMaps.getSize(2)) + ", "
|
||||
+ std::to_string(faceHeatMaps.getSize(3)) + "]");
|
||||
const auto& handHeatMaps = datumsPtr->at(0).handHeatMaps;
|
||||
const auto& handHeatMaps = datumsPtr->at(0)->handHeatMaps;
|
||||
op::log("Left hand heatmaps size: [" + std::to_string(handHeatMaps[0].getSize(0)) + ", "
|
||||
+ std::to_string(handHeatMaps[0].getSize(1)) + ", "
|
||||
+ std::to_string(handHeatMaps[0].getSize(2)) + ", "
|
||||
@@ -217,7 +218,7 @@ int tutorialApiCpp4()
|
||||
|
||||
// Configuring OpenPose
|
||||
op::log("Configuring OpenPose...", op::Priority::High);
|
||||
op::WrapperT<std::vector<UserDatum>> opWrapperT{op::ThreadManagerMode::Asynchronous};
|
||||
op::WrapperT<UserDatum> opWrapperT{op::ThreadManagerMode::Asynchronous};
|
||||
// Pose configuration (use WrapperStructPose{} for default and recommended configuration)
|
||||
const op::WrapperStructPose wrapperStructPose{
|
||||
!FLAGS_body_disable, netInputSize, outputSize, keypointScale, FLAGS_num_gpu, FLAGS_num_gpu_start,
|
||||
@@ -271,7 +272,7 @@ int tutorialApiCpp4()
|
||||
{
|
||||
auto successfullyEmplaced = opWrapperT.waitAndEmplace(datumToProcess);
|
||||
// Pop frame
|
||||
std::shared_ptr<std::vector<UserDatum>> datumProcessed;
|
||||
std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>> datumProcessed;
|
||||
if (successfullyEmplaced && opWrapperT.waitAndPop(datumProcessed))
|
||||
{
|
||||
userWantsToExit = userOutputClass.display(datumProcessed);
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
|
||||
// If the user needs his own variables, he can inherit the op::Datum struct and add them in there.
|
||||
// UserDatum can be directly used by the OpenPose wrapper because it inherits from op::Datum, just define
|
||||
// WrapperT<std::vector<UserDatum>> instead of Wrapper (or equivalently WrapperT<std::vector<UserDatum>>)
|
||||
// WrapperT<std::vector<std::shared_ptr<UserDatum>>> instead of Wrapper
|
||||
// (or equivalently WrapperT<std::vector<std::shared_ptr<UserDatum>>>)
|
||||
struct UserDatum : public op::Datum
|
||||
{
|
||||
bool boolThatUserNeedsForSomeReason;
|
||||
@@ -41,15 +42,15 @@ struct UserDatum : public op::Datum
|
||||
class UserOutputClass
|
||||
{
|
||||
public:
|
||||
bool display(const std::shared_ptr<std::vector<UserDatum>>& datumsPtr)
|
||||
bool display(const std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>& datumsPtr)
|
||||
{
|
||||
// User's displaying/saving/other processing here
|
||||
// datum.cvOutputData: rendered frame with pose or heatmaps
|
||||
// datum.poseKeypoints: Array<float> with the estimated pose
|
||||
// datumPtr->cvOutputData: rendered frame with pose or heatmaps
|
||||
// datumPtr->poseKeypoints: Array<float> with the estimated pose
|
||||
char key = ' ';
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
{
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0).cvOutputData);
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
|
||||
// Display image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
|
||||
key = (char)cv::waitKey(1);
|
||||
}
|
||||
@@ -57,14 +58,14 @@ public:
|
||||
op::log("Nullptr or empty datumsPtr found.", op::Priority::High, __LINE__, __FUNCTION__, __FILE__);
|
||||
return (key == 27);
|
||||
}
|
||||
void printKeypoints(const std::shared_ptr<std::vector<UserDatum>>& datumsPtr)
|
||||
void printKeypoints(const std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>& datumsPtr)
|
||||
{
|
||||
// Example: How to use the pose keypoints
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
{
|
||||
op::log("\nKeypoints:");
|
||||
// Accesing each element of the keypoints
|
||||
const auto& poseKeypoints = datumsPtr->at(0).poseKeypoints;
|
||||
const auto& poseKeypoints = datumsPtr->at(0)->poseKeypoints;
|
||||
op::log("Person pose keypoints:");
|
||||
for (auto person = 0 ; person < poseKeypoints.getSize(0) ; person++)
|
||||
{
|
||||
@@ -81,22 +82,22 @@ public:
|
||||
}
|
||||
op::log(" ");
|
||||
// Alternative: just getting std::string equivalent
|
||||
op::log("Face keypoints: " + datumsPtr->at(0).faceKeypoints.toString());
|
||||
op::log("Left hand keypoints: " + datumsPtr->at(0).handKeypoints[0].toString());
|
||||
op::log("Right hand keypoints: " + datumsPtr->at(0).handKeypoints[1].toString());
|
||||
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString());
|
||||
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString());
|
||||
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString());
|
||||
// Heatmaps
|
||||
const auto& poseHeatMaps = datumsPtr->at(0).poseHeatMaps;
|
||||
const auto& poseHeatMaps = datumsPtr->at(0)->poseHeatMaps;
|
||||
if (!poseHeatMaps.empty())
|
||||
{
|
||||
op::log("Pose heatmaps size: [" + std::to_string(poseHeatMaps.getSize(0)) + ", "
|
||||
+ std::to_string(poseHeatMaps.getSize(1)) + ", "
|
||||
+ std::to_string(poseHeatMaps.getSize(2)) + "]");
|
||||
const auto& faceHeatMaps = datumsPtr->at(0).faceHeatMaps;
|
||||
const auto& faceHeatMaps = datumsPtr->at(0)->faceHeatMaps;
|
||||
op::log("Face heatmaps size: [" + std::to_string(faceHeatMaps.getSize(0)) + ", "
|
||||
+ std::to_string(faceHeatMaps.getSize(1)) + ", "
|
||||
+ std::to_string(faceHeatMaps.getSize(2)) + ", "
|
||||
+ std::to_string(faceHeatMaps.getSize(3)) + "]");
|
||||
const auto& handHeatMaps = datumsPtr->at(0).handHeatMaps;
|
||||
const auto& handHeatMaps = datumsPtr->at(0)->handHeatMaps;
|
||||
op::log("Left hand heatmaps size: [" + std::to_string(handHeatMaps[0].getSize(0)) + ", "
|
||||
+ std::to_string(handHeatMaps[0].getSize(1)) + ", "
|
||||
+ std::to_string(handHeatMaps[0].getSize(2)) + ", "
|
||||
@@ -160,7 +161,7 @@ int tutorialApiCpp5()
|
||||
|
||||
// Configuring OpenPose
|
||||
op::log("Configuring OpenPose...", op::Priority::High);
|
||||
op::WrapperT<std::vector<UserDatum>> opWrapperT{op::ThreadManagerMode::AsynchronousOut};
|
||||
op::WrapperT<UserDatum> opWrapperT{op::ThreadManagerMode::AsynchronousOut};
|
||||
// Pose configuration (use WrapperStructPose{} for default and recommended configuration)
|
||||
const op::WrapperStructPose wrapperStructPose{
|
||||
!FLAGS_body_disable, netInputSize, outputSize, keypointScale, FLAGS_num_gpu, FLAGS_num_gpu_start,
|
||||
@@ -214,7 +215,7 @@ int tutorialApiCpp5()
|
||||
while (!userWantsToExit)
|
||||
{
|
||||
// Pop frame
|
||||
std::shared_ptr<std::vector<UserDatum>> datumProcessed;
|
||||
std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>> datumProcessed;
|
||||
if (opWrapperT.waitAndPop(datumProcessed))
|
||||
{
|
||||
userWantsToExit = userOutputClass.display(datumProcessed);;
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
|
||||
// If the user needs his own variables, he can inherit the op::Datum struct and add them in there.
|
||||
// UserDatum can be directly used by the OpenPose wrapper because it inherits from op::Datum, just define
|
||||
// WrapperT<std::vector<UserDatum>> instead of Wrapper (or equivalently WrapperT<std::vector<UserDatum>>)
|
||||
// WrapperT<std::vector<std::shared_ptr<UserDatum>>> instead of Wrapper
|
||||
// (or equivalently WrapperT<std::vector<std::shared_ptr<UserDatum>>>)
|
||||
struct UserDatum : public op::Datum
|
||||
{
|
||||
bool boolThatUserNeedsForSomeReason;
|
||||
@@ -38,7 +39,7 @@ struct UserDatum : public op::Datum
|
||||
// in this case we assume a std::shared_ptr of a std::vector of UserDatum
|
||||
|
||||
// This worker will just invert the image
|
||||
class WUserPostProcessing : public op::Worker<std::shared_ptr<std::vector<UserDatum>>>
|
||||
class WUserPostProcessing : public op::Worker<std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>>
|
||||
{
|
||||
public:
|
||||
WUserPostProcessing()
|
||||
@@ -48,16 +49,16 @@ public:
|
||||
|
||||
void initializationOnThread() {}
|
||||
|
||||
void work(std::shared_ptr<std::vector<UserDatum>>& datumsPtr)
|
||||
void work(std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>& datumsPtr)
|
||||
{
|
||||
// User's post-processing (after OpenPose processing & before OpenPose outputs) here
|
||||
// datum.cvOutputData: rendered frame with pose or heatmaps
|
||||
// datum.poseKeypoints: Array<float> with the estimated pose
|
||||
// datumPtr->cvOutputData: rendered frame with pose or heatmaps
|
||||
// datumPtr->poseKeypoints: Array<float> with the estimated pose
|
||||
try
|
||||
{
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
for (auto& datum : *datumsPtr)
|
||||
cv::bitwise_not(datum.cvOutputData, datum.cvOutputData);
|
||||
for (auto& datumPtr : *datumsPtr)
|
||||
cv::bitwise_not(datumPtr->cvOutputData, datumPtr->cvOutputData);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -120,7 +121,7 @@ int tutorialApiCpp6()
|
||||
|
||||
// OpenPose wrapper
|
||||
op::log("Configuring OpenPose...", op::Priority::High);
|
||||
op::WrapperT<std::vector<UserDatum>> opWrapperT;
|
||||
op::WrapperT<UserDatum> opWrapperT;
|
||||
|
||||
// Initializing the user custom classes
|
||||
// Processing
|
||||
|
||||
@@ -29,7 +29,8 @@ DEFINE_string(image_dir, "examples/media/",
|
||||
|
||||
// If the user needs his own variables, he can inherit the op::Datum struct and add them in there.
|
||||
// UserDatum can be directly used by the OpenPose wrapper because it inherits from op::Datum, just define
|
||||
// WrapperT<std::vector<UserDatum>> instead of Wrapper (or equivalently WrapperT<std::vector<UserDatum>>)
|
||||
// WrapperT<std::vector<std::shared_ptr<UserDatum>>> instead of Wrapper
|
||||
// (or equivalently WrapperT<std::vector<std::shared_ptr<UserDatum>>>)
|
||||
struct UserDatum : public op::Datum
|
||||
{
|
||||
bool boolThatUserNeedsForSomeReason;
|
||||
@@ -44,7 +45,7 @@ struct UserDatum : public op::Datum
|
||||
// in this case we assume a std::shared_ptr of a std::vector of UserDatum
|
||||
|
||||
// This worker will just read and return all the jpg files in a directory
|
||||
class WUserInput : public op::WorkerProducer<std::shared_ptr<std::vector<UserDatum>>>
|
||||
class WUserInput : public op::WorkerProducer<std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>>
|
||||
{
|
||||
public:
|
||||
WUserInput(const std::string& directoryPath) :
|
||||
@@ -59,7 +60,7 @@ public:
|
||||
|
||||
void initializationOnThread() {}
|
||||
|
||||
std::shared_ptr<std::vector<UserDatum>> workProducer()
|
||||
std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>> workProducer()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -76,15 +77,15 @@ public:
|
||||
else
|
||||
{
|
||||
// Create new datum
|
||||
auto datumsPtr = std::make_shared<std::vector<UserDatum>>();
|
||||
auto datumsPtr = std::make_shared<std::vector<std::shared_ptr<UserDatum>>>();
|
||||
datumsPtr->emplace_back();
|
||||
auto& datum = datumsPtr->at(0);
|
||||
auto& datumPtr = datumsPtr->at(0);
|
||||
|
||||
// Fill datum
|
||||
datum.cvInputData = cv::imread(mImageFiles.at(mCounter++));
|
||||
datumPtr->cvInputData = cv::imread(mImageFiles.at(mCounter++));
|
||||
|
||||
// If empty frame -> return nullptr
|
||||
if (datum.cvInputData.empty())
|
||||
if (datumPtr->cvInputData.empty())
|
||||
{
|
||||
op::log("Empty frame detected on path: " + mImageFiles.at(mCounter-1) + ". Closing program.",
|
||||
op::Priority::High);
|
||||
@@ -155,7 +156,7 @@ int tutorialApiCpp7()
|
||||
|
||||
// OpenPose wrapper
|
||||
op::log("Configuring OpenPose...", op::Priority::High);
|
||||
op::WrapperT<std::vector<UserDatum>> opWrapperT;
|
||||
op::WrapperT<UserDatum> opWrapperT;
|
||||
|
||||
// Initializing the user custom classes
|
||||
// Frames producer (e.g., video, webcam, ...)
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
|
||||
// If the user needs his own variables, he can inherit the op::Datum struct and add them in there.
|
||||
// UserDatum can be directly used by the OpenPose wrapper because it inherits from op::Datum, just define
|
||||
// WrapperT<std::vector<UserDatum>> instead of Wrapper (or equivalently WrapperT<std::vector<UserDatum>>)
|
||||
// WrapperT<std::vector<std::shared_ptr<UserDatum>>> instead of Wrapper
|
||||
// (or equivalently WrapperT<std::vector<std::shared_ptr<UserDatum>>>)
|
||||
struct UserDatum : public op::Datum
|
||||
{
|
||||
bool boolThatUserNeedsForSomeReason;
|
||||
@@ -39,24 +40,24 @@ struct UserDatum : public op::Datum
|
||||
// in this case we assume a std::shared_ptr of a std::vector of UserDatum
|
||||
|
||||
// This worker will just read and return all the jpg files in a directory
|
||||
class WUserOutput : public op::WorkerConsumer<std::shared_ptr<std::vector<UserDatum>>>
|
||||
class WUserOutput : public op::WorkerConsumer<std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>>
|
||||
{
|
||||
public:
|
||||
void initializationOnThread() {}
|
||||
|
||||
void workConsumer(const std::shared_ptr<std::vector<UserDatum>>& datumsPtr)
|
||||
void workConsumer(const std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>& datumsPtr)
|
||||
{
|
||||
try
|
||||
{
|
||||
// User's displaying/saving/other processing here
|
||||
// datum.cvOutputData: rendered frame with pose or heatmaps
|
||||
// datum.poseKeypoints: Array<float> with the estimated pose
|
||||
// datumPtr->cvOutputData: rendered frame with pose or heatmaps
|
||||
// datumPtr->poseKeypoints: Array<float> with the estimated pose
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
{
|
||||
// Show in command line the resulting pose keypoints for body, face and hands
|
||||
op::log("\nKeypoints:");
|
||||
// Accesing each element of the keypoints
|
||||
const auto& poseKeypoints = datumsPtr->at(0).poseKeypoints;
|
||||
const auto& poseKeypoints = datumsPtr->at(0)->poseKeypoints;
|
||||
op::log("Person pose keypoints:");
|
||||
for (auto person = 0 ; person < poseKeypoints.getSize(0) ; person++)
|
||||
{
|
||||
@@ -73,22 +74,22 @@ public:
|
||||
}
|
||||
op::log(" ");
|
||||
// Alternative: just getting std::string equivalent
|
||||
op::log("Face keypoints: " + datumsPtr->at(0).faceKeypoints.toString());
|
||||
op::log("Left hand keypoints: " + datumsPtr->at(0).handKeypoints[0].toString());
|
||||
op::log("Right hand keypoints: " + datumsPtr->at(0).handKeypoints[1].toString());
|
||||
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString());
|
||||
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString());
|
||||
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString());
|
||||
// Heatmaps
|
||||
const auto& poseHeatMaps = datumsPtr->at(0).poseHeatMaps;
|
||||
const auto& poseHeatMaps = datumsPtr->at(0)->poseHeatMaps;
|
||||
if (!poseHeatMaps.empty())
|
||||
{
|
||||
op::log("Pose heatmaps size: [" + std::to_string(poseHeatMaps.getSize(0)) + ", "
|
||||
+ std::to_string(poseHeatMaps.getSize(1)) + ", "
|
||||
+ std::to_string(poseHeatMaps.getSize(2)) + "]");
|
||||
const auto& faceHeatMaps = datumsPtr->at(0).faceHeatMaps;
|
||||
const auto& faceHeatMaps = datumsPtr->at(0)->faceHeatMaps;
|
||||
op::log("Face heatmaps size: [" + std::to_string(faceHeatMaps.getSize(0)) + ", "
|
||||
+ std::to_string(faceHeatMaps.getSize(1)) + ", "
|
||||
+ std::to_string(faceHeatMaps.getSize(2)) + ", "
|
||||
+ std::to_string(faceHeatMaps.getSize(3)) + "]");
|
||||
const auto& handHeatMaps = datumsPtr->at(0).handHeatMaps;
|
||||
const auto& handHeatMaps = datumsPtr->at(0)->handHeatMaps;
|
||||
op::log("Left hand heatmaps size: [" + std::to_string(handHeatMaps[0].getSize(0)) + ", "
|
||||
+ std::to_string(handHeatMaps[0].getSize(1)) + ", "
|
||||
+ std::to_string(handHeatMaps[0].getSize(2)) + ", "
|
||||
@@ -100,7 +101,7 @@ public:
|
||||
}
|
||||
|
||||
// Display rendered output image
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0).cvOutputData);
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
|
||||
// Display image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
|
||||
const char key = (char)cv::waitKey(1);
|
||||
if (key == 27)
|
||||
@@ -168,7 +169,7 @@ int tutorialApiCpp8()
|
||||
|
||||
// OpenPose wrapper
|
||||
op::log("Configuring OpenPose...", op::Priority::High);
|
||||
op::WrapperT<std::vector<UserDatum>> opWrapperT;
|
||||
op::WrapperT<UserDatum> opWrapperT;
|
||||
|
||||
// Initializing the user custom classes
|
||||
// GUI (Display)
|
||||
|
||||
@@ -29,7 +29,8 @@ DEFINE_string(image_dir, "examples/media/",
|
||||
|
||||
// If the user needs his own variables, he can inherit the op::Datum struct and add them in there.
|
||||
// UserDatum can be directly used by the OpenPose wrapper because it inherits from op::Datum, just define
|
||||
// WrapperT<std::vector<UserDatum>> instead of Wrapper (or equivalently WrapperT<std::vector<UserDatum>>)
|
||||
// WrapperT<std::vector<std::shared_ptr<UserDatum>>> instead of Wrapper
|
||||
// (or equivalently WrapperT<std::vector<std::shared_ptr<UserDatum>>>)
|
||||
struct UserDatum : public op::Datum
|
||||
{
|
||||
bool boolThatUserNeedsForSomeReason;
|
||||
@@ -44,7 +45,7 @@ struct UserDatum : public op::Datum
|
||||
// in this case we assume a std::shared_ptr of a std::vector of UserDatum
|
||||
|
||||
// This worker will just read and return all the jpg files in a directory
|
||||
class WUserInput : public op::WorkerProducer<std::shared_ptr<std::vector<UserDatum>>>
|
||||
class WUserInput : public op::WorkerProducer<std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>>
|
||||
{
|
||||
public:
|
||||
WUserInput(const std::string& directoryPath) :
|
||||
@@ -59,7 +60,7 @@ public:
|
||||
|
||||
void initializationOnThread() {}
|
||||
|
||||
std::shared_ptr<std::vector<UserDatum>> workProducer()
|
||||
std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>> workProducer()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -76,15 +77,15 @@ public:
|
||||
else
|
||||
{
|
||||
// Create new datum
|
||||
auto datumsPtr = std::make_shared<std::vector<UserDatum>>();
|
||||
auto datumsPtr = std::make_shared<std::vector<std::shared_ptr<UserDatum>>>();
|
||||
datumsPtr->emplace_back();
|
||||
auto& datum = datumsPtr->at(0);
|
||||
auto& datumPtr = datumsPtr->at(0);
|
||||
|
||||
// Fill datum
|
||||
datum.cvInputData = cv::imread(mImageFiles.at(mCounter++));
|
||||
datumPtr->cvInputData = cv::imread(mImageFiles.at(mCounter++));
|
||||
|
||||
// If empty frame -> return nullptr
|
||||
if (datum.cvInputData.empty())
|
||||
if (datumPtr->cvInputData.empty())
|
||||
{
|
||||
op::log("Empty frame detected on path: " + mImageFiles.at(mCounter-1) + ". Closing program.",
|
||||
op::Priority::High);
|
||||
@@ -109,7 +110,7 @@ private:
|
||||
};
|
||||
|
||||
// This worker will just invert the image
|
||||
class WUserPostProcessing : public op::Worker<std::shared_ptr<std::vector<UserDatum>>>
|
||||
class WUserPostProcessing : public op::Worker<std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>>
|
||||
{
|
||||
public:
|
||||
WUserPostProcessing()
|
||||
@@ -119,16 +120,16 @@ public:
|
||||
|
||||
void initializationOnThread() {}
|
||||
|
||||
void work(std::shared_ptr<std::vector<UserDatum>>& datumsPtr)
|
||||
void work(std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>& datumsPtr)
|
||||
{
|
||||
// User's post-processing (after OpenPose processing & before OpenPose outputs) here
|
||||
// datum.cvOutputData: rendered frame with pose or heatmaps
|
||||
// datum.poseKeypoints: Array<float> with the estimated pose
|
||||
// datumPtr->cvOutputData: rendered frame with pose or heatmaps
|
||||
// datumPtr->poseKeypoints: Array<float> with the estimated pose
|
||||
try
|
||||
{
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
for (auto& datum : *datumsPtr)
|
||||
cv::bitwise_not(datum.cvOutputData, datum.cvOutputData);
|
||||
for (auto& datumPtr : *datumsPtr)
|
||||
cv::bitwise_not(datumPtr->cvOutputData, datumPtr->cvOutputData);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -139,24 +140,24 @@ public:
|
||||
};
|
||||
|
||||
// This worker will just read and return all the jpg files in a directory
|
||||
class WUserOutput : public op::WorkerConsumer<std::shared_ptr<std::vector<UserDatum>>>
|
||||
class WUserOutput : public op::WorkerConsumer<std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>>
|
||||
{
|
||||
public:
|
||||
void initializationOnThread() {}
|
||||
|
||||
void workConsumer(const std::shared_ptr<std::vector<UserDatum>>& datumsPtr)
|
||||
void workConsumer(const std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>& datumsPtr)
|
||||
{
|
||||
try
|
||||
{
|
||||
// User's displaying/saving/other processing here
|
||||
// datum.cvOutputData: rendered frame with pose or heatmaps
|
||||
// datum.poseKeypoints: Array<float> with the estimated pose
|
||||
// datumPtr->cvOutputData: rendered frame with pose or heatmaps
|
||||
// datumPtr->poseKeypoints: Array<float> with the estimated pose
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
{
|
||||
// Show in command line the resulting pose keypoints for body, face and hands
|
||||
op::log("\nKeypoints:");
|
||||
// Accesing each element of the keypoints
|
||||
const auto& poseKeypoints = datumsPtr->at(0).poseKeypoints;
|
||||
const auto& poseKeypoints = datumsPtr->at(0)->poseKeypoints;
|
||||
op::log("Person pose keypoints:");
|
||||
for (auto person = 0 ; person < poseKeypoints.getSize(0) ; person++)
|
||||
{
|
||||
@@ -173,22 +174,22 @@ public:
|
||||
}
|
||||
op::log(" ");
|
||||
// Alternative: just getting std::string equivalent
|
||||
op::log("Face keypoints: " + datumsPtr->at(0).faceKeypoints.toString());
|
||||
op::log("Left hand keypoints: " + datumsPtr->at(0).handKeypoints[0].toString());
|
||||
op::log("Right hand keypoints: " + datumsPtr->at(0).handKeypoints[1].toString());
|
||||
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString());
|
||||
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString());
|
||||
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString());
|
||||
// Heatmaps
|
||||
const auto& poseHeatMaps = datumsPtr->at(0).poseHeatMaps;
|
||||
const auto& poseHeatMaps = datumsPtr->at(0)->poseHeatMaps;
|
||||
if (!poseHeatMaps.empty())
|
||||
{
|
||||
op::log("Pose heatmaps size: [" + std::to_string(poseHeatMaps.getSize(0)) + ", "
|
||||
+ std::to_string(poseHeatMaps.getSize(1)) + ", "
|
||||
+ std::to_string(poseHeatMaps.getSize(2)) + "]");
|
||||
const auto& faceHeatMaps = datumsPtr->at(0).faceHeatMaps;
|
||||
const auto& faceHeatMaps = datumsPtr->at(0)->faceHeatMaps;
|
||||
op::log("Face heatmaps size: [" + std::to_string(faceHeatMaps.getSize(0)) + ", "
|
||||
+ std::to_string(faceHeatMaps.getSize(1)) + ", "
|
||||
+ std::to_string(faceHeatMaps.getSize(2)) + ", "
|
||||
+ std::to_string(faceHeatMaps.getSize(3)) + "]");
|
||||
const auto& handHeatMaps = datumsPtr->at(0).handHeatMaps;
|
||||
const auto& handHeatMaps = datumsPtr->at(0)->handHeatMaps;
|
||||
op::log("Left hand heatmaps size: [" + std::to_string(handHeatMaps[0].getSize(0)) + ", "
|
||||
+ std::to_string(handHeatMaps[0].getSize(1)) + ", "
|
||||
+ std::to_string(handHeatMaps[0].getSize(2)) + ", "
|
||||
@@ -200,7 +201,7 @@ public:
|
||||
}
|
||||
|
||||
// Display rendered output image
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0).cvOutputData);
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
|
||||
// Display image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
|
||||
const char key = (char)cv::waitKey(1);
|
||||
if (key == 27)
|
||||
@@ -264,7 +265,7 @@ int tutorialApiCpp9()
|
||||
|
||||
// OpenPose wrapper
|
||||
op::log("Configuring OpenPose...", op::Priority::High);
|
||||
op::WrapperT<std::vector<UserDatum>> opWrapperT;
|
||||
op::WrapperT<UserDatum> opWrapperT;
|
||||
// Add custom input
|
||||
const auto workerInputOnNewThread = false;
|
||||
opWrapperT.setWorker(op::WorkerType::Input, wUserInput, workerInputOnNewThread);
|
||||
|
||||
@@ -99,16 +99,16 @@ int tutorialDeveloperThread1()
|
||||
(int)producerSharedPtr->get(CV_CAP_PROP_FRAME_WIDTH),
|
||||
(int)producerSharedPtr->get(CV_CAP_PROP_FRAME_HEIGHT)};
|
||||
// Step 4 - Setting thread workers && manager
|
||||
typedef std::vector<op::Datum> TypedefDatumsNoPtr;
|
||||
typedef std::shared_ptr<TypedefDatumsNoPtr> TypedefDatums;
|
||||
op::ThreadManager<TypedefDatums> threadManager;
|
||||
typedef op::Datum TypedefDatum;
|
||||
typedef std::shared_ptr<std::vector<std::shared_ptr<TypedefDatum>>> TypedefDatumsSP;
|
||||
op::ThreadManager<TypedefDatumsSP> threadManager;
|
||||
// Step 5 - Initializing the worker classes
|
||||
// Frames producer (e.g., video, webcam, ...)
|
||||
auto DatumProducer = std::make_shared<op::DatumProducer<TypedefDatumsNoPtr>>(producerSharedPtr);
|
||||
auto wDatumProducer = std::make_shared<op::WDatumProducer<TypedefDatums, TypedefDatumsNoPtr>>(DatumProducer);
|
||||
auto DatumProducer = std::make_shared<op::DatumProducer<TypedefDatum>>(producerSharedPtr);
|
||||
auto wDatumProducer = std::make_shared<op::WDatumProducer<TypedefDatum>>(DatumProducer);
|
||||
// GUI (Display)
|
||||
auto gui = std::make_shared<op::Gui>(outputSize, FLAGS_fullscreen, threadManager.getIsRunningSharedPtr());
|
||||
auto wGui = std::make_shared<op::WGui<TypedefDatums>>(gui);
|
||||
auto wGui = std::make_shared<op::WGui<TypedefDatumsSP>>(gui);
|
||||
|
||||
// ------------------------- CONFIGURING THREADING -------------------------
|
||||
// In this simple multi-thread example, we will do the following:
|
||||
|
||||
@@ -64,7 +64,7 @@ DEFINE_bool(fullscreen, false, "Run in full-screen mode
|
||||
// This class can be implemented either as a template or as a simple class given
|
||||
// that the user usually knows which kind of data he will move between the queues,
|
||||
// in this case we assume a std::shared_ptr of a std::vector of op::Datum
|
||||
class WUserClass : public op::Worker<std::shared_ptr<std::vector<op::Datum>>>
|
||||
class WUserClass : public op::Worker<std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>>
|
||||
{
|
||||
public:
|
||||
WUserClass()
|
||||
@@ -74,16 +74,16 @@ public:
|
||||
|
||||
void initializationOnThread() {}
|
||||
|
||||
void work(std::shared_ptr<std::vector<op::Datum>>& datumsPtr)
|
||||
void work(std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& datumsPtr)
|
||||
{
|
||||
try
|
||||
{
|
||||
// User's processing here
|
||||
// datum.cvInputData: initial cv::Mat obtained from the frames producer (video, webcam, etc.)
|
||||
// datum.cvOutputData: final cv::Mat to be displayed
|
||||
// datumPtr->cvInputData: initial cv::Mat obtained from the frames producer (video, webcam, etc.)
|
||||
// datumPtr->cvOutputData: final cv::Mat to be displayed
|
||||
if (datumsPtr != nullptr)
|
||||
for (auto& datum : *datumsPtr)
|
||||
cv::bitwise_not(datum.cvInputData, datum.cvOutputData);
|
||||
for (auto& datumPtr : *datumsPtr)
|
||||
cv::bitwise_not(datumPtr->cvInputData, datumPtr->cvOutputData);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -133,18 +133,18 @@ int tutorialDeveloperThread2()
|
||||
(int)producerSharedPtr->get(CV_CAP_PROP_FRAME_WIDTH),
|
||||
(int)producerSharedPtr->get(CV_CAP_PROP_FRAME_HEIGHT)};
|
||||
// Step 4 - Setting thread workers && manager
|
||||
typedef std::vector<op::Datum> TypedefDatumsNoPtr;
|
||||
typedef std::shared_ptr<TypedefDatumsNoPtr> TypedefDatums;
|
||||
op::ThreadManager<TypedefDatums> threadManager;
|
||||
typedef op::Datum TypedefDatum;
|
||||
typedef std::shared_ptr<std::vector<std::shared_ptr<TypedefDatum>>> TypedefDatumsSP;
|
||||
op::ThreadManager<TypedefDatumsSP> threadManager;
|
||||
// Step 5 - Initializing the worker classes
|
||||
// Frames producer (e.g., video, webcam, ...)
|
||||
auto DatumProducer = std::make_shared<op::DatumProducer<TypedefDatumsNoPtr>>(producerSharedPtr);
|
||||
auto wDatumProducer = std::make_shared<op::WDatumProducer<TypedefDatums, TypedefDatumsNoPtr>>(DatumProducer);
|
||||
auto DatumProducer = std::make_shared<op::DatumProducer<TypedefDatum>>(producerSharedPtr);
|
||||
auto wDatumProducer = std::make_shared<op::WDatumProducer<TypedefDatum>>(DatumProducer);
|
||||
// Specific WUserClass
|
||||
auto wUserClass = std::make_shared<WUserClass>();
|
||||
// GUI (Display)
|
||||
auto gui = std::make_shared<op::Gui>(outputSize, FLAGS_fullscreen, threadManager.getIsRunningSharedPtr());
|
||||
auto wGui = std::make_shared<op::WGui<TypedefDatums>>(gui);
|
||||
auto wGui = std::make_shared<op::WGui<TypedefDatumsSP>>(gui);
|
||||
|
||||
// ------------------------- CONFIGURING THREADING -------------------------
|
||||
// In this simple multi-thread example, we will do the following:
|
||||
|
||||
@@ -44,7 +44,7 @@ DEFINE_bool(fullscreen, false, "Run in full-screen mode
|
||||
// in this case we assume a std::shared_ptr of a std::vector of op::Datum
|
||||
|
||||
// This worker will just read and return all the jpg files in a directory
|
||||
class WUserInput : public op::WorkerProducer<std::shared_ptr<std::vector<op::Datum>>>
|
||||
class WUserInput : public op::WorkerProducer<std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>>
|
||||
{
|
||||
public:
|
||||
WUserInput(const std::string& directoryPath) :
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
|
||||
void initializationOnThread() {}
|
||||
|
||||
std::shared_ptr<std::vector<op::Datum>> workProducer()
|
||||
std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>> workProducer()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -76,15 +76,15 @@ public:
|
||||
else
|
||||
{
|
||||
// Create new datum
|
||||
auto datumsPtr = std::make_shared<std::vector<op::Datum>>();
|
||||
auto datumsPtr = std::make_shared<std::vector<std::shared_ptr<op::Datum>>>();
|
||||
datumsPtr->emplace_back();
|
||||
auto& datum = datumsPtr->at(0);
|
||||
auto& datumPtr = datumsPtr->at(0);
|
||||
|
||||
// Fill datum
|
||||
datum.cvInputData = cv::imread(mImageFiles.at(mCounter++));
|
||||
datumPtr->cvInputData = cv::imread(mImageFiles.at(mCounter++));
|
||||
|
||||
// If empty frame -> return nullptr
|
||||
if (datum.cvInputData.empty())
|
||||
if (datumPtr->cvInputData.empty())
|
||||
{
|
||||
op::log("Empty frame detected on path: " + mImageFiles.at(mCounter-1) + ". Closing program.",
|
||||
op::Priority::High);
|
||||
@@ -110,7 +110,7 @@ private:
|
||||
};
|
||||
|
||||
// This worker will just invert the image
|
||||
class WUserPostProcessing : public op::Worker<std::shared_ptr<std::vector<op::Datum>>>
|
||||
class WUserPostProcessing : public op::Worker<std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>>
|
||||
{
|
||||
public:
|
||||
WUserPostProcessing()
|
||||
@@ -120,16 +120,16 @@ public:
|
||||
|
||||
void initializationOnThread() {}
|
||||
|
||||
void work(std::shared_ptr<std::vector<op::Datum>>& datumsPtr)
|
||||
void work(std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& datumsPtr)
|
||||
{
|
||||
// User's post-processing (after OpenPose processing & before OpenPose outputs) here
|
||||
// datum.cvOutputData: rendered frame with pose or heatmaps
|
||||
// datum.poseKeypoints: Array<float> with the estimated pose
|
||||
// datumPtr->cvOutputData: rendered frame with pose or heatmaps
|
||||
// datumPtr->poseKeypoints: Array<float> with the estimated pose
|
||||
try
|
||||
{
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
for (auto& datum : *datumsPtr)
|
||||
cv::bitwise_not(datum.cvInputData, datum.cvOutputData);
|
||||
for (auto& datumPtr : *datumsPtr)
|
||||
cv::bitwise_not(datumPtr->cvInputData, datumPtr->cvOutputData);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -141,21 +141,21 @@ public:
|
||||
};
|
||||
|
||||
// This worker will just read and return all the jpg files in a directory
|
||||
class WUserOutput : public op::WorkerConsumer<std::shared_ptr<std::vector<op::Datum>>>
|
||||
class WUserOutput : public op::WorkerConsumer<std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>>
|
||||
{
|
||||
public:
|
||||
void initializationOnThread() {}
|
||||
|
||||
void workConsumer(const std::shared_ptr<std::vector<op::Datum>>& datumsPtr)
|
||||
void workConsumer(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& datumsPtr)
|
||||
{
|
||||
try
|
||||
{
|
||||
// User's displaying/saving/other processing here
|
||||
// datum.cvOutputData: rendered frame with pose or heatmaps
|
||||
// datum.poseKeypoints: Array<float> with the estimated pose
|
||||
// datumPtr->cvOutputData: rendered frame with pose or heatmaps
|
||||
// datumPtr->poseKeypoints: Array<float> with the estimated pose
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
{
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0).cvOutputData);
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
|
||||
// It displays the image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
|
||||
cv::waitKey(1);
|
||||
}
|
||||
@@ -184,9 +184,9 @@ int openPoseTutorialThread3()
|
||||
__LINE__, __FUNCTION__, __FILE__);
|
||||
op::ConfigureLog::setPriorityThreshold((op::Priority)FLAGS_logging_level);
|
||||
// Step 2 - Setting thread workers && manager
|
||||
typedef std::shared_ptr<std::vector<op::Datum>> TypedefDatums;
|
||||
typedef std::shared_ptr<op::Worker<TypedefDatums>> TypedefWorker;
|
||||
op::ThreadManager<TypedefDatums> threadManager;
|
||||
typedef std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>> TypedefDatumsSP;
|
||||
typedef std::shared_ptr<op::Worker<TypedefDatumsSP>> TypedefWorker;
|
||||
op::ThreadManager<TypedefDatumsSP> threadManager;
|
||||
// Step 3 - Initializing the worker classes
|
||||
// Frames producer (e.g., video, webcam, ...)
|
||||
TypedefWorker wUserInput = std::make_shared<WUserInput>(FLAGS_image_dir);
|
||||
|
||||
@@ -42,7 +42,8 @@ DEFINE_bool(fullscreen, false, "Run in full-screen mode
|
||||
|
||||
// If the user needs his own variables, he can inherit the op::Datum struct and add them in there.
|
||||
// UserDatum can be directly used by the OpenPose wrapper because it inherits from op::Datum, just define
|
||||
// WrapperT<std::vector<UserDatum>> instead of Wrapper (or equivalently WrapperT<std::vector<UserDatum>>)
|
||||
// WrapperT<std::vector<std::shared_ptr<UserDatum>>> instead of Wrapper
|
||||
// (or equivalently WrapperT<std::vector<std::shared_ptr<UserDatum>>>)
|
||||
struct UserDatum : public op::Datum
|
||||
{
|
||||
bool boolThatUserNeedsForSomeReason;
|
||||
@@ -57,7 +58,7 @@ struct UserDatum : public op::Datum
|
||||
// in this case we assume a std::shared_ptr of a std::vector of UserDatum
|
||||
|
||||
// This worker will just read and return all the jpg files in a directory
|
||||
class WUserInput : public op::WorkerProducer<std::shared_ptr<std::vector<UserDatum>>>
|
||||
class WUserInput : public op::WorkerProducer<std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>>
|
||||
{
|
||||
public:
|
||||
WUserInput(const std::string& directoryPath) :
|
||||
@@ -72,7 +73,7 @@ public:
|
||||
|
||||
void initializationOnThread() {}
|
||||
|
||||
std::shared_ptr<std::vector<UserDatum>> workProducer()
|
||||
std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>> workProducer()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -89,15 +90,15 @@ public:
|
||||
else
|
||||
{
|
||||
// Create new datum
|
||||
auto datumsPtr = std::make_shared<std::vector<UserDatum>>();
|
||||
auto datumsPtr = std::make_shared<std::vector<std::shared_ptr<UserDatum>>>();
|
||||
datumsPtr->emplace_back();
|
||||
auto& datum = datumsPtr->at(0);
|
||||
auto& datumPtr = datumsPtr->at(0);
|
||||
|
||||
// Fill datum
|
||||
datum.cvInputData = cv::imread(mImageFiles.at(mCounter++));
|
||||
datumPtr->cvInputData = cv::imread(mImageFiles.at(mCounter++));
|
||||
|
||||
// If empty frame -> return nullptr
|
||||
if (datum.cvInputData.empty())
|
||||
if (datumPtr->cvInputData.empty())
|
||||
{
|
||||
op::log("Empty frame detected on path: " + mImageFiles.at(mCounter-1) + ". Closing program.",
|
||||
op::Priority::High);
|
||||
@@ -123,7 +124,7 @@ private:
|
||||
};
|
||||
|
||||
// This worker will just invert the image
|
||||
class WUserPostProcessing : public op::Worker<std::shared_ptr<std::vector<UserDatum>>>
|
||||
class WUserPostProcessing : public op::Worker<std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>>
|
||||
{
|
||||
public:
|
||||
WUserPostProcessing()
|
||||
@@ -133,16 +134,16 @@ public:
|
||||
|
||||
void initializationOnThread() {}
|
||||
|
||||
void work(std::shared_ptr<std::vector<UserDatum>>& datumsPtr)
|
||||
void work(std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>& datumsPtr)
|
||||
{
|
||||
// User's post-processing (after OpenPose processing & before OpenPose outputs) here
|
||||
// datum.cvOutputData: rendered frame with pose or heatmaps
|
||||
// datum.poseKeypoints: Array<float> with the estimated pose
|
||||
// datumPtr->cvOutputData: rendered frame with pose or heatmaps
|
||||
// datumPtr->poseKeypoints: Array<float> with the estimated pose
|
||||
try
|
||||
{
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
for (auto& datum : *datumsPtr)
|
||||
cv::bitwise_not(datum.cvInputData, datum.cvOutputData);
|
||||
for (auto& datumPtr : *datumsPtr)
|
||||
cv::bitwise_not(datumPtr->cvInputData, datumPtr->cvOutputData);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -154,21 +155,21 @@ public:
|
||||
};
|
||||
|
||||
// This worker will just read and return all the jpg files in a directory
|
||||
class WUserOutput : public op::WorkerConsumer<std::shared_ptr<std::vector<UserDatum>>>
|
||||
class WUserOutput : public op::WorkerConsumer<std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>>
|
||||
{
|
||||
public:
|
||||
void initializationOnThread() {}
|
||||
|
||||
void workConsumer(const std::shared_ptr<std::vector<UserDatum>>& datumsPtr)
|
||||
void workConsumer(const std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>& datumsPtr)
|
||||
{
|
||||
try
|
||||
{
|
||||
// User's displaying/saving/other processing here
|
||||
// datum.cvOutputData: rendered frame with pose or heatmaps
|
||||
// datum.poseKeypoints: Array<float> with the estimated pose
|
||||
// datumPtr->cvOutputData: rendered frame with pose or heatmaps
|
||||
// datumPtr->poseKeypoints: Array<float> with the estimated pose
|
||||
if (datumsPtr != nullptr && !datumsPtr->empty())
|
||||
{
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0).cvOutputData);
|
||||
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
|
||||
// It displays the image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
|
||||
cv::waitKey(1);
|
||||
}
|
||||
@@ -197,9 +198,9 @@ int openPoseTutorialThread4()
|
||||
__LINE__, __FUNCTION__, __FILE__);
|
||||
op::ConfigureLog::setPriorityThreshold((op::Priority)FLAGS_logging_level);
|
||||
// Step 2 - Setting thread workers && manager
|
||||
typedef std::shared_ptr<std::vector<UserDatum>> TypedefDatums;
|
||||
typedef std::shared_ptr<op::Worker<TypedefDatums>> TypedefWorker;
|
||||
op::ThreadManager<TypedefDatums> threadManager;
|
||||
typedef std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>> TypedefDatumsSP;
|
||||
typedef std::shared_ptr<op::Worker<TypedefDatumsSP>> TypedefWorker;
|
||||
op::ThreadManager<TypedefDatumsSP> threadManager;
|
||||
// Step 3 - Initializing the worker classes
|
||||
// Frames producer (e.g., video, webcam, ...)
|
||||
TypedefWorker wUserInput = std::make_shared<WUserInput>(FLAGS_image_dir);
|
||||
|
||||
@@ -71,14 +71,14 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Input
|
||||
auto& datum = tDatums->at(0);
|
||||
const auto& poseKeypoints3D = datum.poseKeypoints3D;
|
||||
const auto& faceKeypoints3D = datum.faceKeypoints3D;
|
||||
const auto& handKeypoints3D = datum.handKeypoints3D;
|
||||
auto& tDatumPtr = tDatums->at(0);
|
||||
const auto& poseKeypoints3D = tDatumPtr->poseKeypoints3D;
|
||||
const auto& faceKeypoints3D = tDatumPtr->faceKeypoints3D;
|
||||
const auto& handKeypoints3D = tDatumPtr->handKeypoints3D;
|
||||
// Running Adam model
|
||||
spJointAngleEstimation->adamFastFit(
|
||||
datum.adamPose, datum.adamTranslation, datum.vtVec, datum.j0Vec,
|
||||
datum.adamFaceCoeffsExp, poseKeypoints3D, faceKeypoints3D, handKeypoints3D);
|
||||
tDatumPtr->adamPose, tDatumPtr->adamTranslation, tDatumPtr->vtVec, tDatumPtr->j0Vec,
|
||||
tDatumPtr->adamFaceCoeffsExp, poseKeypoints3D, faceKeypoints3D, handKeypoints3D);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -76,27 +76,27 @@ namespace op
|
||||
std::vector<Array<float>> leftHandKeypointVector;
|
||||
std::vector<Array<float>> rightHandKeypointVector;
|
||||
std::vector<Point<int>> imageSizes;
|
||||
for (auto& datumsElement : *tDatums)
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
{
|
||||
poseKeypointVector.emplace_back(datumsElement.poseKeypoints);
|
||||
faceKeypointVector.emplace_back(datumsElement.faceKeypoints);
|
||||
leftHandKeypointVector.emplace_back(datumsElement.handKeypoints[0]);
|
||||
rightHandKeypointVector.emplace_back(datumsElement.handKeypoints[1]);
|
||||
cameraMatrices.emplace_back(datumsElement.cameraMatrix);
|
||||
imageSizes.emplace_back(Point<int>{datumsElement.cvInputData.cols,
|
||||
datumsElement.cvInputData.rows});
|
||||
poseKeypointVector.emplace_back(tDatumPtr->poseKeypoints);
|
||||
faceKeypointVector.emplace_back(tDatumPtr->faceKeypoints);
|
||||
leftHandKeypointVector.emplace_back(tDatumPtr->handKeypoints[0]);
|
||||
rightHandKeypointVector.emplace_back(tDatumPtr->handKeypoints[1]);
|
||||
cameraMatrices.emplace_back(tDatumPtr->cameraMatrix);
|
||||
imageSizes.emplace_back(
|
||||
Point<int>{tDatumPtr->cvInputData.cols, tDatumPtr->cvInputData.rows});
|
||||
}
|
||||
// Pose 3-D reconstruction
|
||||
auto poseKeypoints3Ds = spPoseTriangulation->reconstructArray(
|
||||
{poseKeypointVector, faceKeypointVector, leftHandKeypointVector, rightHandKeypointVector},
|
||||
cameraMatrices, imageSizes);
|
||||
// Assign to all tDatums
|
||||
for (auto& datumsElement : *tDatums)
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
{
|
||||
datumsElement.poseKeypoints3D = poseKeypoints3Ds[0];
|
||||
datumsElement.faceKeypoints3D = poseKeypoints3Ds[1];
|
||||
datumsElement.handKeypoints3D[0] = poseKeypoints3Ds[2];
|
||||
datumsElement.handKeypoints3D[1] = poseKeypoints3Ds[3];
|
||||
tDatumPtr->poseKeypoints3D = poseKeypoints3Ds[0];
|
||||
tDatumPtr->faceKeypoints3D = poseKeypoints3Ds[1];
|
||||
tDatumPtr->handKeypoints3D[0] = poseKeypoints3Ds[2];
|
||||
tDatumPtr->handKeypoints3D[1] = poseKeypoints3Ds[3];
|
||||
}
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -389,10 +389,11 @@ namespace op
|
||||
};
|
||||
|
||||
// Defines for Datum. Added here rather than in `macros.hpp` to avoid circular dependencies
|
||||
#define DATUM_BASE_NO_PTR std::vector<Datum>
|
||||
#define DATUM_BASE std::shared_ptr<DATUM_BASE_NO_PTR>
|
||||
#define DEFINE_TEMPLATE_DATUM(templateName) template class OP_API templateName<DATUM_BASE>
|
||||
#define COMPILE_TEMPLATE_DATUM(templateName) extern template class templateName<DATUM_BASE>
|
||||
#define BASE_DATUM Datum
|
||||
#define BASE_DATUMS std::vector<std::shared_ptr<BASE_DATUM>>
|
||||
#define BASE_DATUMS_SH std::shared_ptr<BASE_DATUMS>
|
||||
#define DEFINE_TEMPLATE_DATUM(templateName) template class OP_API templateName<BASE_DATUMS_SH>
|
||||
#define COMPILE_TEMPLATE_DATUM(templateName) extern template class templateName<BASE_DATUMS_SH>
|
||||
}
|
||||
|
||||
#endif // OPENPOSE_CORE_DATUM_HPP
|
||||
|
||||
@@ -62,10 +62,9 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// cv::Mat -> float*
|
||||
for (auto& tDatum : *tDatums)
|
||||
tDatum.inputNetData = spCvMatToOpInput->createArray(tDatum.cvInputData,
|
||||
tDatum.scaleInputToNetInputs,
|
||||
tDatum.netInputSizes);
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
tDatumPtr->inputNetData = spCvMatToOpInput->createArray(
|
||||
tDatumPtr->cvInputData, tDatumPtr->scaleInputToNetInputs, tDatumPtr->netInputSizes);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -65,9 +65,9 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// cv::Mat -> float*
|
||||
for (auto& tDatum : tDatumsNoPtr)
|
||||
tDatum.outputData = spCvMatToOpOutput->createArray(tDatum.cvInputData, tDatum.scaleInputToOutput,
|
||||
tDatum.netOutputSize);
|
||||
for (auto& tDatumPtr : tDatumsNoPtr)
|
||||
tDatumPtr->outputData = spCvMatToOpOutput->createArray(
|
||||
tDatumPtr->cvInputData, tDatumPtr->scaleInputToOutput, tDatumPtr->netOutputSize);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -60,14 +60,16 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Rescale pose data
|
||||
for (auto& tDatum : *tDatums)
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
{
|
||||
tDatum.poseKeypoints = spKeepTopNPeople->keepTopPeople(tDatum.poseKeypoints, tDatum.poseScores);
|
||||
tDatum.faceKeypoints = spKeepTopNPeople->keepTopPeople(tDatum.faceKeypoints, tDatum.poseScores);
|
||||
tDatum.handKeypoints[0] = spKeepTopNPeople->keepTopPeople(tDatum.handKeypoints[0],
|
||||
tDatum.poseScores);
|
||||
tDatum.handKeypoints[1] = spKeepTopNPeople->keepTopPeople(tDatum.handKeypoints[1],
|
||||
tDatum.poseScores);
|
||||
tDatumPtr->poseKeypoints = spKeepTopNPeople->keepTopPeople(
|
||||
tDatumPtr->poseKeypoints, tDatumPtr->poseScores);
|
||||
tDatumPtr->faceKeypoints = spKeepTopNPeople->keepTopPeople(
|
||||
tDatumPtr->faceKeypoints, tDatumPtr->poseScores);
|
||||
tDatumPtr->handKeypoints[0] = spKeepTopNPeople->keepTopPeople(
|
||||
tDatumPtr->handKeypoints[0], tDatumPtr->poseScores);
|
||||
tDatumPtr->handKeypoints[1] = spKeepTopNPeople->keepTopPeople(
|
||||
tDatumPtr->handKeypoints[1], tDatumPtr->poseScores);
|
||||
}
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -60,15 +60,18 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Rescale pose data
|
||||
for (auto& tDatum : *tDatums)
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
{
|
||||
std::vector<Array<float>> arraysToScale{tDatum.poseKeypoints, tDatum.handKeypoints[0],
|
||||
tDatum.handKeypoints[1], tDatum.faceKeypoints};
|
||||
spKeypointScaler->scale(arraysToScale, tDatum.scaleInputToOutput, tDatum.scaleNetToOutput,
|
||||
Point<int>{tDatum.cvInputData.cols, tDatum.cvInputData.rows});
|
||||
std::vector<Array<float>> arraysToScale{
|
||||
tDatumPtr->poseKeypoints, tDatumPtr->handKeypoints[0],
|
||||
tDatumPtr->handKeypoints[1], tDatumPtr->faceKeypoints};
|
||||
spKeypointScaler->scale(
|
||||
arraysToScale, tDatumPtr->scaleInputToOutput, tDatumPtr->scaleNetToOutput,
|
||||
Point<int>{tDatumPtr->cvInputData.cols, tDatumPtr->cvInputData.rows});
|
||||
// Rescale part candidates
|
||||
spKeypointScaler->scale(tDatum.poseCandidates, tDatum.scaleInputToOutput, tDatum.scaleNetToOutput,
|
||||
Point<int>{tDatum.cvInputData.cols, tDatum.cvInputData.rows});
|
||||
spKeypointScaler->scale(
|
||||
tDatumPtr->poseCandidates, tDatumPtr->scaleInputToOutput, tDatumPtr->scaleNetToOutput,
|
||||
Point<int>{tDatumPtr->cvInputData.cols, tDatumPtr->cvInputData.rows});
|
||||
}
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -62,8 +62,8 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// float* -> cv::Mat
|
||||
for (auto& tDatum : *tDatums)
|
||||
tDatum.cvOutputData = spOpOutputToCvMat->formatToCvMat(tDatum.outputData);
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
tDatumPtr->cvOutputData = spOpOutputToCvMat->formatToCvMat(tDatumPtr->outputData);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -63,11 +63,11 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// cv::Mat -> float*
|
||||
for (auto& tDatum : *tDatums)
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
{
|
||||
const Point<int> inputSize{tDatum.cvInputData.cols, tDatum.cvInputData.rows};
|
||||
std::tie(tDatum.scaleInputToNetInputs, tDatum.netInputSizes, tDatum.scaleInputToOutput,
|
||||
tDatum.netOutputSize) = spScaleAndSizeExtractor->extract(inputSize);
|
||||
const Point<int> inputSize{tDatumPtr->cvInputData.cols, tDatumPtr->cvInputData.rows};
|
||||
std::tie(tDatumPtr->scaleInputToNetInputs, tDatumPtr->netInputSizes, tDatumPtr->scaleInputToOutput,
|
||||
tDatumPtr->netOutputSize) = spScaleAndSizeExtractor->extract(inputSize);
|
||||
}
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -65,8 +65,8 @@ namespace op
|
||||
// Print verbose
|
||||
if (checkNoNullNorEmpty(tDatums))
|
||||
{
|
||||
const auto tDatum = (*tDatums)[0];
|
||||
spVerbosePrinter->printVerbose(tDatum.frameNumber);
|
||||
const auto tDatumPtr = (*tDatums)[0];
|
||||
spVerbosePrinter->printVerbose(tDatumPtr->frameNumber);
|
||||
}
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -62,8 +62,8 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Detect people face
|
||||
for (auto& tDatum : *tDatums)
|
||||
tDatum.faceRectangles = spFaceDetector->detectFaces(tDatum.poseKeypoints);
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
tDatumPtr->faceRectangles = spFaceDetector->detectFaces(tDatumPtr->poseKeypoints);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -62,8 +62,8 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Detect people face
|
||||
for (auto& tDatum : *tDatums)
|
||||
tDatum.faceRectangles = spFaceDetectorOpenCV->detectFaces(tDatum.cvInputData);
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
tDatumPtr->faceRectangles = spFaceDetectorOpenCV->detectFaces(tDatumPtr->cvInputData);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -63,11 +63,11 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Extract people face
|
||||
for (auto& tDatum : *tDatums)
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
{
|
||||
spFaceExtractorNet->forwardPass(tDatum.faceRectangles, tDatum.cvInputData);
|
||||
tDatum.faceHeatMaps = spFaceExtractorNet->getHeatMaps().clone();
|
||||
tDatum.faceKeypoints = spFaceExtractorNet->getFaceKeypoints().clone();
|
||||
spFaceExtractorNet->forwardPass(tDatumPtr->faceRectangles, tDatumPtr->cvInputData);
|
||||
tDatumPtr->faceHeatMaps = spFaceExtractorNet->getHeatMaps().clone();
|
||||
tDatumPtr->faceKeypoints = spFaceExtractorNet->getFaceKeypoints().clone();
|
||||
}
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -63,9 +63,9 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Render people face
|
||||
for (auto& tDatum : *tDatums)
|
||||
spFaceRenderer->renderFace(tDatum.outputData, tDatum.faceKeypoints,
|
||||
(float)tDatum.scaleInputToOutput);
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
spFaceRenderer->renderFace(
|
||||
tDatumPtr->outputData, tDatumPtr->faceKeypoints, (float)tDatumPtr->scaleInputToOutput);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -63,9 +63,9 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Record BVH file
|
||||
const auto& tDatum = (*tDatums)[0];
|
||||
if (!tDatum.poseKeypoints3D.empty())
|
||||
spBvhSaver->updateBvh(tDatum.adamPose, tDatum.adamTranslation, tDatum.j0Vec);
|
||||
const auto& tDatumPtr = (*tDatums)[0];
|
||||
if (!tDatumPtr->poseKeypoints3D.empty())
|
||||
spBvhSaver->updateBvh(tDatumPtr->adamPose, tDatumPtr->adamTranslation, tDatumPtr->j0Vec);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -65,9 +65,9 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// T* to T
|
||||
const auto& tDatum = tDatums->at(0);
|
||||
const auto& tDatumPtr = tDatums->at(0);
|
||||
// Record json in COCO format
|
||||
spCocoJsonSaver->record(tDatum.poseKeypoints, tDatum.poseScores, tDatum.name);
|
||||
spCocoJsonSaver->record(tDatumPtr->poseKeypoints, tDatumPtr->poseScores, tDatumPtr->name);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -67,8 +67,9 @@ namespace op
|
||||
// Record people face keypoint data
|
||||
std::vector<Array<float>> keypointVector(tDatumsNoPtr.size());
|
||||
for (auto i = 0u; i < tDatumsNoPtr.size(); i++)
|
||||
keypointVector[i] = tDatumsNoPtr[i].faceKeypoints;
|
||||
const auto fileName = (!tDatumsNoPtr[0].name.empty() ? tDatumsNoPtr[0].name : std::to_string(tDatumsNoPtr[0].id));
|
||||
keypointVector[i] = tDatumsNoPtr[i]->faceKeypoints;
|
||||
const auto fileName = (!tDatumsNoPtr[0]->name.empty()
|
||||
? tDatumsNoPtr[0]->name : std::to_string(tDatumsNoPtr[0]->id));
|
||||
spKeypointSaver->saveKeypoints(keypointVector, fileName, "face");
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -65,15 +65,16 @@ namespace op
|
||||
// T* to T
|
||||
auto& tDatumsNoPtr = *tDatums;
|
||||
// Record people hand keypoint data
|
||||
const auto fileName = (!tDatumsNoPtr[0].name.empty() ? tDatumsNoPtr[0].name : std::to_string(tDatumsNoPtr[0].id));
|
||||
const auto fileName = (!tDatumsNoPtr[0]->name.empty()
|
||||
? tDatumsNoPtr[0]->name : std::to_string(tDatumsNoPtr[0]->id));
|
||||
std::vector<Array<float>> keypointVector(tDatumsNoPtr.size());
|
||||
// Left hand
|
||||
for (auto i = 0u; i < tDatumsNoPtr.size(); i++)
|
||||
keypointVector[i] = tDatumsNoPtr[i].handKeypoints[0];
|
||||
keypointVector[i] = tDatumsNoPtr[i]->handKeypoints[0];
|
||||
spKeypointSaver->saveKeypoints(keypointVector, fileName, "hand_left");
|
||||
// Right hand
|
||||
for (auto i = 0u; i < tDatumsNoPtr.size(); i++)
|
||||
keypointVector[i] = tDatumsNoPtr[i].handKeypoints[1];
|
||||
keypointVector[i] = tDatumsNoPtr[i]->handKeypoints[1];
|
||||
spKeypointSaver->saveKeypoints(keypointVector, fileName, "hand_right");
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -66,9 +66,9 @@ namespace op
|
||||
// Record pose heatmap image(s) on disk
|
||||
std::vector<Array<float>> poseHeatMaps(tDatumsNoPtr.size());
|
||||
for (auto i = 0u; i < tDatumsNoPtr.size(); i++)
|
||||
poseHeatMaps[i] = tDatumsNoPtr[i].poseHeatMaps;
|
||||
const auto fileName = (!tDatumsNoPtr[0].name.empty()
|
||||
? tDatumsNoPtr[0].name : std::to_string(tDatumsNoPtr[0].id)) + "_pose_heatmaps";
|
||||
poseHeatMaps[i] = tDatumsNoPtr[i]->poseHeatMaps;
|
||||
const auto fileName = (!tDatumsNoPtr[0]->name.empty()
|
||||
? tDatumsNoPtr[0]->name : std::to_string(tDatumsNoPtr[0]->id)) + "_pose_heatmaps";
|
||||
spHeatMapSaver->saveHeatMaps(poseHeatMaps, fileName);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -66,8 +66,9 @@ namespace op
|
||||
// Record image(s) on disk
|
||||
std::vector<cv::Mat> cvOutputDatas(tDatumsNoPtr.size());
|
||||
for (auto i = 0u; i < tDatumsNoPtr.size(); i++)
|
||||
cvOutputDatas[i] = tDatumsNoPtr[i].cvOutputData;
|
||||
const auto fileName = (!tDatumsNoPtr[0].name.empty() ? tDatumsNoPtr[0].name : std::to_string(tDatumsNoPtr[0].id));
|
||||
cvOutputDatas[i] = tDatumsNoPtr[i]->cvOutputData;
|
||||
const auto fileName = (!tDatumsNoPtr[0]->name.empty()
|
||||
? tDatumsNoPtr[0]->name : std::to_string(tDatumsNoPtr[0]->id));
|
||||
spImageSaver->saveImages(cvOutputDatas, fileName);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -62,30 +62,30 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Save body/face/hand keypoints to JSON file
|
||||
const auto& tDatumFirst = (*tDatums)[0];
|
||||
const auto baseFileName = (!tDatumFirst.name.empty() ? tDatumFirst.name
|
||||
: std::to_string(tDatumFirst.id)) + "_keypoints";
|
||||
const auto& tDatumFirstPtr = (*tDatums)[0];
|
||||
const auto baseFileName = (!tDatumFirstPtr->name.empty() ? tDatumFirstPtr->name
|
||||
: std::to_string(tDatumFirstPtr->id)) + "_keypoints";
|
||||
const bool humanReadable = false;
|
||||
for (auto i = 0u ; i < tDatums->size() ; i++)
|
||||
{
|
||||
const auto& tDatum = (*tDatums)[i];
|
||||
const auto& tDatumPtr = (*tDatums)[i];
|
||||
// const auto fileName = baseFileName;
|
||||
const auto fileName = baseFileName + (i != 0 ? "_" + std::to_string(i) : "");
|
||||
|
||||
const std::vector<std::pair<Array<float>, std::string>> keypointVector{
|
||||
// 2D
|
||||
std::make_pair(tDatum.poseKeypoints, "pose_keypoints_2d"),
|
||||
std::make_pair(tDatum.faceKeypoints, "face_keypoints_2d"),
|
||||
std::make_pair(tDatum.handKeypoints[0], "hand_left_keypoints_2d"),
|
||||
std::make_pair(tDatum.handKeypoints[1], "hand_right_keypoints_2d"),
|
||||
std::make_pair(tDatumPtr->poseKeypoints, "pose_keypoints_2d"),
|
||||
std::make_pair(tDatumPtr->faceKeypoints, "face_keypoints_2d"),
|
||||
std::make_pair(tDatumPtr->handKeypoints[0], "hand_left_keypoints_2d"),
|
||||
std::make_pair(tDatumPtr->handKeypoints[1], "hand_right_keypoints_2d"),
|
||||
// 3D
|
||||
std::make_pair(tDatum.poseKeypoints3D, "pose_keypoints_3d"),
|
||||
std::make_pair(tDatum.faceKeypoints3D, "face_keypoints_3d"),
|
||||
std::make_pair(tDatum.handKeypoints3D[0], "hand_left_keypoints_3d"),
|
||||
std::make_pair(tDatum.handKeypoints3D[1], "hand_right_keypoints_3d")
|
||||
std::make_pair(tDatumPtr->poseKeypoints3D, "pose_keypoints_3d"),
|
||||
std::make_pair(tDatumPtr->faceKeypoints3D, "face_keypoints_3d"),
|
||||
std::make_pair(tDatumPtr->handKeypoints3D[0], "hand_left_keypoints_3d"),
|
||||
std::make_pair(tDatumPtr->handKeypoints3D[1], "hand_right_keypoints_3d")
|
||||
};
|
||||
// Save keypoints
|
||||
spPeopleJsonSaver->save(keypointVector, tDatum.poseCandidates, fileName, humanReadable);
|
||||
spPeopleJsonSaver->save(keypointVector, tDatumPtr->poseCandidates, fileName, humanReadable);
|
||||
}
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -67,8 +67,9 @@ namespace op
|
||||
// Record people pose keypoint data
|
||||
std::vector<Array<float>> keypointVector(tDatumsNoPtr.size());
|
||||
for (auto i = 0u; i < tDatumsNoPtr.size(); i++)
|
||||
keypointVector[i] = tDatumsNoPtr[i].poseKeypoints;
|
||||
const auto fileName = (!tDatumsNoPtr[0].name.empty() ? tDatumsNoPtr[0].name : std::to_string(tDatumsNoPtr[0].id));
|
||||
keypointVector[i] = tDatumsNoPtr[i]->poseKeypoints;
|
||||
const auto fileName = (!tDatumsNoPtr[0]->name.empty()
|
||||
? tDatumsNoPtr[0]->name : std::to_string(tDatumsNoPtr[0]->id));
|
||||
spKeypointSaver->saveKeypoints(keypointVector, fileName, "pose");
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -63,24 +63,24 @@ namespace op
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Send though UDP communication
|
||||
#ifdef USE_3D_ADAM_MODEL
|
||||
const auto& tDatum = (*tDatums)[0];
|
||||
if (!tDatum.poseKeypoints3D.empty())
|
||||
const auto& tDatumPtr = (*tDatums)[0];
|
||||
if (!tDatumPtr->poseKeypoints3D.empty())
|
||||
{
|
||||
const auto& adamPose = tDatum.adamPose; // Eigen::Matrix<double, 62, 3, Eigen::RowMajor>
|
||||
const auto& adamTranslation = tDatum.adamTranslation; // Eigen::Vector3d(3, 1)
|
||||
const auto adamFaceCoeffsExp = tDatum.adamFaceCoeffsExp; // Eigen::VectorXd resized to (200, 1)
|
||||
//const float mouth_open = tDatum.mouthOpening; // tDatum.mouth_open;
|
||||
//const float leye_open = tDatum.rightEyeOpening; // tDatum.leye_open;
|
||||
//const float reye_open = tDatum.leftEyeOpening; // tDatum.reye_open;
|
||||
//const float dist_root_foot = Datum.distanceRootFoot; // tDatum.dist_root_foot;
|
||||
const auto& adamPose = tDatumPtr->adamPose; // Eigen::Matrix<double, 62, 3, Eigen::RowMajor>
|
||||
const auto& adamTranslation = tDatumPtr->adamTranslation; // Eigen::Vector3d(3, 1)
|
||||
const auto adamFaceCoeffsExp = tDatumPtr->adamFaceCoeffsExp; // Eigen::VectorXd resized to (200, 1)
|
||||
//const float mouth_open = tDatumPtr->mouthOpening; // tDatumPtr->mouth_open;
|
||||
//const float leye_open = tDatumPtr->rightEyeOpening; // tDatumPtr->leye_open;
|
||||
//const float reye_open = tDatumPtr->leftEyeOpening; // tDatumPtr->reye_open;
|
||||
//const float dist_root_foot = Datum.distanceRootFoot; // tDatumPtr->dist_root_foot;
|
||||
// m_adam_t:
|
||||
// 1. Total translation (centimeters) of the root in camera/global coordinate representation.
|
||||
// m_adam_pose:
|
||||
// 1. First row is global rotation, in AngleAxis representation. Radians (not degrees!)
|
||||
// 2. Rest are joint-angles in Euler-Angle representation. Degrees.
|
||||
spUdpSender->sendJointAngles(adamPose.data(), adamPose.rows(),
|
||||
adamTranslation.data(),
|
||||
adamFaceCoeffsExp.data(), adamFaceCoeffsExp.rows());
|
||||
spUdpSender->sendJointAngles(
|
||||
adamPose.data(), adamPose.rows(), adamTranslation.data(), adamFaceCoeffsExp.data(),
|
||||
adamFaceCoeffsExp.rows());
|
||||
}
|
||||
#endif
|
||||
// Profiling speed
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace op
|
||||
// Record video(s)
|
||||
std::vector<cv::Mat> cvOutputDatas(tDatumsNoPtr.size());
|
||||
for (auto i = 0u ; i < cvOutputDatas.size() ; i++)
|
||||
cvOutputDatas[i] = tDatumsNoPtr[i].cvOutputData;
|
||||
cvOutputDatas[i] = tDatumsNoPtr[i]->cvOutputData;
|
||||
spVideoSaver->write(cvOutputDatas);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace op
|
||||
auto& tDatumsNoPtr = *tDatums;
|
||||
// Record video(s)
|
||||
if (!tDatumsNoPtr.empty())
|
||||
spVideoSaver->write(tDatumsNoPtr[0].cvOutputData3D);
|
||||
spVideoSaver->write(tDatumsNoPtr[0]->cvOutputData3D);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -74,8 +74,8 @@ namespace op
|
||||
if (!tDatums->empty())
|
||||
{
|
||||
std::vector<cv::Mat> cvOutputDatas;
|
||||
for (auto& tDatum : *tDatums)
|
||||
cvOutputDatas.emplace_back(tDatum.cvOutputData);
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
cvOutputDatas.emplace_back(tDatumPtr->cvOutputData);
|
||||
spGui->setImage(cvOutputDatas);
|
||||
}
|
||||
// Refresh/update GUI
|
||||
|
||||
@@ -76,21 +76,22 @@ namespace op
|
||||
{
|
||||
// Update cvMat
|
||||
std::vector<cv::Mat> cvOutputDatas;
|
||||
for (auto& tDatum : *tDatums)
|
||||
cvOutputDatas.emplace_back(tDatum.cvOutputData);
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
cvOutputDatas.emplace_back(tDatumPtr->cvOutputData);
|
||||
spGui3D->setImage(cvOutputDatas);
|
||||
// Update keypoints
|
||||
auto& tDatum = (*tDatums)[0];
|
||||
spGui3D->setKeypoints(tDatum.poseKeypoints3D, tDatum.faceKeypoints3D, tDatum.handKeypoints3D[0],
|
||||
tDatum.handKeypoints3D[1]);
|
||||
auto& tDatumPtr = (*tDatums)[0];
|
||||
spGui3D->setKeypoints(
|
||||
tDatumPtr->poseKeypoints3D, tDatumPtr->faceKeypoints3D, tDatumPtr->handKeypoints3D[0],
|
||||
tDatumPtr->handKeypoints3D[1]);
|
||||
}
|
||||
// Refresh/update GUI
|
||||
spGui3D->update();
|
||||
// Read OpenCV mat equivalent
|
||||
if (!tDatums->empty())
|
||||
{
|
||||
auto& tDatum = (*tDatums)[0];
|
||||
tDatum.cvOutputData3D = spGui3D->readCvMat();
|
||||
auto& tDatumPtr = (*tDatums)[0];
|
||||
tDatumPtr->cvOutputData3D = spGui3D->readCvMat();
|
||||
}
|
||||
// Profiling speed
|
||||
if (!tDatums->empty())
|
||||
|
||||
@@ -77,16 +77,16 @@ namespace op
|
||||
// Update cvMat
|
||||
std::vector<cv::Mat> cvOutputDatas;
|
||||
for (auto& tDatum : *tDatums)
|
||||
cvOutputDatas.emplace_back(tDatum.cvOutputData);
|
||||
cvOutputDatas.emplace_back(tDatumPtr->cvOutputData);
|
||||
spGuiAdam->setImage(cvOutputDatas);
|
||||
// Update keypoints
|
||||
const auto& tDatum = (*tDatums)[0];
|
||||
if (!tDatum.poseKeypoints3D.empty())
|
||||
spGuiAdam->generateMesh(tDatum.poseKeypoints3D, tDatum.faceKeypoints3D, tDatum.handKeypoints3D,
|
||||
tDatum.adamPose.data(), tDatum.adamTranslation.data(),
|
||||
tDatum.vtVec.data(), tDatum.vtVec.rows(),
|
||||
tDatum.j0Vec.data(), tDatum.j0Vec.rows(),
|
||||
tDatum.adamFaceCoeffsExp.data());
|
||||
const auto& tDatumPtr = (*tDatums)[0];
|
||||
if (!tDatumPtr->poseKeypoints3D.empty())
|
||||
spGuiAdam->generateMesh(
|
||||
tDatumPtr->poseKeypoints3D, tDatumPtr->faceKeypoints3D, tDatumPtr->handKeypoints3D,
|
||||
tDatumPtr->adamPose.data(), tDatumPtr->adamTranslation.data(), tDatumPtr->vtVec.data(),
|
||||
tDatumPtr->vtVec.rows(), tDatumPtr->j0Vec.data(), tDatumPtr->j0Vec.rows(),
|
||||
tDatumPtr->adamFaceCoeffsExp.data());
|
||||
}
|
||||
// Refresh/update GUI
|
||||
spGuiAdam->update();
|
||||
|
||||
@@ -62,11 +62,12 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Add GUI components to frame
|
||||
for (auto& tDatum : *tDatums)
|
||||
spGuiInfoAdder->addInfo(tDatum.cvOutputData, std::max(tDatum.poseKeypoints.getSize(0),
|
||||
tDatum.faceKeypoints.getSize(0)),
|
||||
tDatum.id, tDatum.elementRendered.second, tDatum.frameNumber,
|
||||
tDatum.poseIds, tDatum.poseKeypoints);
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
spGuiInfoAdder->addInfo(
|
||||
tDatumPtr->cvOutputData,
|
||||
std::max(tDatumPtr->poseKeypoints.getSize(0), tDatumPtr->faceKeypoints.getSize(0)),
|
||||
tDatumPtr->id, tDatumPtr->elementRendered.second, tDatumPtr->frameNumber,
|
||||
tDatumPtr->poseIds, tDatumPtr->poseKeypoints);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -62,8 +62,8 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Detect people hand
|
||||
for (auto& tDatum : *tDatums)
|
||||
tDatum.handRectangles = spHandDetector->detectHands(tDatum.poseKeypoints);
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
tDatumPtr->handRectangles = spHandDetector->detectHands(tDatumPtr->poseKeypoints);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -62,8 +62,8 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Detect people hand
|
||||
for (auto& tDatum : *tDatums)
|
||||
tDatum.handRectangles = spHandDetectorFromTxt->detectHands();
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
tDatumPtr->handRectangles = spHandDetectorFromTxt->detectHands();
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -62,8 +62,8 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Detect people hand
|
||||
for (auto& tDatum : *tDatums)
|
||||
tDatum.handRectangles = spHandDetector->trackHands(tDatum.poseKeypoints);
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
tDatumPtr->handRectangles = spHandDetector->trackHands(tDatumPtr->poseKeypoints);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -62,8 +62,8 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Detect people hand
|
||||
for (auto& tDatum : *tDatums)
|
||||
spHandDetector->updateTracker(tDatum.handKeypoints, tDatum.id);
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
spHandDetector->updateTracker(tDatumPtr->handKeypoints, tDatumPtr->id);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -63,13 +63,13 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Extract people hands
|
||||
for (auto& tDatum : *tDatums)
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
{
|
||||
spHandExtractorNet->forwardPass(tDatum.handRectangles, tDatum.cvInputData);
|
||||
spHandExtractorNet->forwardPass(tDatumPtr->handRectangles, tDatumPtr->cvInputData);
|
||||
for (auto hand = 0 ; hand < 2 ; hand++)
|
||||
{
|
||||
tDatum.handHeatMaps[hand] = spHandExtractorNet->getHeatMaps()[hand].clone();
|
||||
tDatum.handKeypoints[hand] = spHandExtractorNet->getHandKeypoints()[hand].clone();
|
||||
tDatumPtr->handHeatMaps[hand] = spHandExtractorNet->getHeatMaps()[hand].clone();
|
||||
tDatumPtr->handKeypoints[hand] = spHandExtractorNet->getHandKeypoints()[hand].clone();
|
||||
}
|
||||
}
|
||||
// Profiling speed
|
||||
|
||||
@@ -63,9 +63,9 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Render people hands
|
||||
for (auto& tDatum : *tDatums)
|
||||
spHandRenderer->renderHand(tDatum.outputData, tDatum.handKeypoints,
|
||||
(float)tDatum.scaleInputToOutput);
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
spHandRenderer->renderHand(
|
||||
tDatumPtr->outputData, tDatumPtr->handKeypoints, (float)tDatumPtr->scaleInputToOutput);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -73,25 +73,25 @@ namespace op
|
||||
for (auto i = 0u ; i < tDatums->size() ; i++)
|
||||
// for (auto& tDatum : *tDatums)
|
||||
{
|
||||
auto& tDatum = (*tDatums)[i];
|
||||
auto& tDatumPtr = (*tDatums)[i];
|
||||
// OpenPose net forward pass
|
||||
spPoseExtractor->forwardPass(tDatum.inputNetData,
|
||||
Point<int>{tDatum.cvInputData.cols, tDatum.cvInputData.rows},
|
||||
tDatum.scaleInputToNetInputs, tDatum.id);
|
||||
spPoseExtractor->forwardPass(
|
||||
tDatumPtr->inputNetData, Point<int>{tDatumPtr->cvInputData.cols, tDatumPtr->cvInputData.rows},
|
||||
tDatumPtr->scaleInputToNetInputs, tDatumPtr->id);
|
||||
// OpenPose keypoint detector
|
||||
tDatum.poseCandidates = spPoseExtractor->getCandidatesCopy();
|
||||
tDatum.poseHeatMaps = spPoseExtractor->getHeatMapsCopy();
|
||||
tDatum.poseKeypoints = spPoseExtractor->getPoseKeypoints().clone();
|
||||
tDatum.poseScores = spPoseExtractor->getPoseScores().clone();
|
||||
tDatum.scaleNetToOutput = spPoseExtractor->getScaleNetToOutput();
|
||||
tDatumPtr->poseCandidates = spPoseExtractor->getCandidatesCopy();
|
||||
tDatumPtr->poseHeatMaps = spPoseExtractor->getHeatMapsCopy();
|
||||
tDatumPtr->poseKeypoints = spPoseExtractor->getPoseKeypoints().clone();
|
||||
tDatumPtr->poseScores = spPoseExtractor->getPoseScores().clone();
|
||||
tDatumPtr->scaleNetToOutput = spPoseExtractor->getScaleNetToOutput();
|
||||
// Keep desired top N people
|
||||
spPoseExtractor->keepTopPeople(tDatum.poseKeypoints, tDatum.poseScores);
|
||||
spPoseExtractor->keepTopPeople(tDatumPtr->poseKeypoints, tDatumPtr->poseScores);
|
||||
// ID extractor (experimental)
|
||||
tDatum.poseIds = spPoseExtractor->extractIdsLockThread(
|
||||
tDatum.poseKeypoints, tDatum.cvInputData, i, tDatum.id);
|
||||
tDatumPtr->poseIds = spPoseExtractor->extractIdsLockThread(
|
||||
tDatumPtr->poseKeypoints, tDatumPtr->cvInputData, i, tDatumPtr->id);
|
||||
// Tracking (experimental)
|
||||
spPoseExtractor->trackLockThread(
|
||||
tDatum.poseKeypoints, tDatum.poseIds, tDatum.cvInputData, i, tDatum.id);
|
||||
tDatumPtr->poseKeypoints, tDatumPtr->poseIds, tDatumPtr->cvInputData, i, tDatumPtr->id);
|
||||
}
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -70,16 +70,16 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Extract people pose
|
||||
for (auto& tDatum : *tDatums)
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
{
|
||||
spPoseExtractorNet->forwardPass(tDatum.inputNetData,
|
||||
Point<int>{tDatum.cvInputData.cols, tDatum.cvInputData.rows},
|
||||
tDatum.scaleInputToNetInputs);
|
||||
tDatum.poseCandidates = spPoseExtractorNet->getCandidatesCopy();
|
||||
tDatum.poseHeatMaps = spPoseExtractorNet->getHeatMapsCopy();
|
||||
tDatum.poseKeypoints = spPoseExtractorNet->getPoseKeypoints().clone();
|
||||
tDatum.poseScores = spPoseExtractorNet->getPoseScores().clone();
|
||||
tDatum.scaleNetToOutput = spPoseExtractorNet->getScaleNetToOutput();
|
||||
spPoseExtractorNet->forwardPass(
|
||||
tDatumPtr->inputNetData, Point<int>{tDatumPtr->cvInputData.cols, tDatumPtr->cvInputData.rows},
|
||||
tDatumPtr->scaleInputToNetInputs);
|
||||
tDatumPtr->poseCandidates = spPoseExtractorNet->getCandidatesCopy();
|
||||
tDatumPtr->poseHeatMaps = spPoseExtractorNet->getHeatMapsCopy();
|
||||
tDatumPtr->poseKeypoints = spPoseExtractorNet->getPoseKeypoints().clone();
|
||||
tDatumPtr->poseScores = spPoseExtractorNet->getPoseScores().clone();
|
||||
tDatumPtr->scaleNetToOutput = spPoseExtractorNet->getScaleNetToOutput();
|
||||
}
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -70,10 +70,10 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Render people pose
|
||||
for (auto& tDatum : *tDatums)
|
||||
tDatum.elementRendered = spPoseRenderer->renderPose(
|
||||
tDatum.outputData, tDatum.poseKeypoints, (float)tDatum.scaleInputToOutput,
|
||||
(float)tDatum.scaleNetToOutput);
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
tDatumPtr->elementRendered = spPoseRenderer->renderPose(
|
||||
tDatumPtr->outputData, tDatumPtr->poseKeypoints, (float)tDatumPtr->scaleInputToOutput,
|
||||
(float)tDatumPtr->scaleNetToOutput);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -11,19 +11,19 @@
|
||||
|
||||
namespace op
|
||||
{
|
||||
template<typename TDatumsNoPtr>
|
||||
template<typename TDatum>
|
||||
class DatumProducer
|
||||
{
|
||||
public:
|
||||
explicit DatumProducer(const std::shared_ptr<Producer>& producerSharedPtr,
|
||||
const unsigned long long frameFirst = 0, const unsigned long long frameStep = 1,
|
||||
const unsigned long long frameLast = std::numeric_limits<unsigned long long>::max(),
|
||||
const std::shared_ptr<std::pair<std::atomic<bool>,
|
||||
std::atomic<int>>>& videoSeekSharedPtr = nullptr);
|
||||
explicit DatumProducer(
|
||||
const std::shared_ptr<Producer>& producerSharedPtr,
|
||||
const unsigned long long frameFirst = 0, const unsigned long long frameStep = 1,
|
||||
const unsigned long long frameLast = std::numeric_limits<unsigned long long>::max(),
|
||||
const std::shared_ptr<std::pair<std::atomic<bool>, std::atomic<int>>>& videoSeekSharedPtr = nullptr);
|
||||
|
||||
virtual ~DatumProducer();
|
||||
|
||||
std::pair<bool, std::shared_ptr<TDatumsNoPtr>> checkIfRunningAndGetDatum();
|
||||
std::pair<bool, std::shared_ptr<std::vector<std::shared_ptr<TDatum>>>> checkIfRunningAndGetDatum();
|
||||
|
||||
private:
|
||||
const unsigned long long mNumberFramesToProcess;
|
||||
@@ -33,8 +33,8 @@ namespace op
|
||||
unsigned int mNumberConsecutiveEmptyFrames;
|
||||
std::shared_ptr<std::pair<std::atomic<bool>, std::atomic<int>>> spVideoSeek;
|
||||
|
||||
void checkIfTooManyConsecutiveEmptyFrames(unsigned int& numberConsecutiveEmptyFrames,
|
||||
const bool emptyFrame) const;
|
||||
void checkIfTooManyConsecutiveEmptyFrames(
|
||||
unsigned int& numberConsecutiveEmptyFrames, const bool emptyFrame) const;
|
||||
|
||||
DELETE_COPY(DatumProducer);
|
||||
};
|
||||
@@ -49,12 +49,12 @@ namespace op
|
||||
#include <openpose/producer/datumProducer.hpp>
|
||||
namespace op
|
||||
{
|
||||
template<typename TDatumsNoPtr>
|
||||
DatumProducer<TDatumsNoPtr>::DatumProducer(const std::shared_ptr<Producer>& producerSharedPtr,
|
||||
const unsigned long long frameFirst, const unsigned long long frameStep,
|
||||
const unsigned long long frameLast,
|
||||
const std::shared_ptr<std::pair<std::atomic<bool>,
|
||||
std::atomic<int>>>& videoSeekSharedPtr) :
|
||||
template<typename TDatum>
|
||||
DatumProducer<TDatum>::DatumProducer(
|
||||
const std::shared_ptr<Producer>& producerSharedPtr,
|
||||
const unsigned long long frameFirst, const unsigned long long frameStep,
|
||||
const unsigned long long frameLast,
|
||||
const std::shared_ptr<std::pair<std::atomic<bool>, std::atomic<int>>>& videoSeekSharedPtr) :
|
||||
mNumberFramesToProcess{(frameLast != std::numeric_limits<unsigned long long>::max()
|
||||
? frameLast - frameFirst : frameLast)},
|
||||
spProducer{producerSharedPtr},
|
||||
@@ -92,17 +92,17 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatumsNoPtr>
|
||||
DatumProducer<TDatumsNoPtr>::~DatumProducer()
|
||||
template<typename TDatum>
|
||||
DatumProducer<TDatum>::~DatumProducer()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename TDatumsNoPtr>
|
||||
std::pair<bool, std::shared_ptr<TDatumsNoPtr>> DatumProducer<TDatumsNoPtr>::checkIfRunningAndGetDatum()
|
||||
template<typename TDatum>
|
||||
std::pair<bool, std::shared_ptr<std::vector<std::shared_ptr<TDatum>>>> DatumProducer<TDatum>::checkIfRunningAndGetDatum()
|
||||
{
|
||||
try
|
||||
{
|
||||
auto datums = std::make_shared<TDatumsNoPtr>();
|
||||
auto datums = std::make_shared<std::vector<std::shared_ptr<TDatum>>>();
|
||||
// Check last desired frame has not been reached
|
||||
if (mNumberFramesToProcess != std::numeric_limits<unsigned long long>::max()
|
||||
&& mGlobalCounter > mNumberFramesToProcess)
|
||||
@@ -137,52 +137,54 @@ namespace op
|
||||
{
|
||||
datums->resize(cvMats.size());
|
||||
// Datum cannot be assigned before resize()
|
||||
auto& datum = (*datums)[0];
|
||||
auto& datumPtr = (*datums)[0];
|
||||
datumPtr = std::make_shared<TDatum>();
|
||||
// Filling first element
|
||||
std::swap(datum.name, nextFrameName);
|
||||
datum.frameNumber = nextFrameNumber;
|
||||
datum.cvInputData = cvMats[0];
|
||||
std::swap(datumPtr->name, nextFrameName);
|
||||
datumPtr->frameNumber = nextFrameNumber;
|
||||
datumPtr->cvInputData = cvMats[0];
|
||||
if (!cameraMatrices.empty())
|
||||
{
|
||||
datum.cameraMatrix = cameraMatrices[0];
|
||||
datum.cameraExtrinsics = cameraExtrinsics[0];
|
||||
datum.cameraIntrinsics = cameraIntrinsics[0];
|
||||
datumPtr->cameraMatrix = cameraMatrices[0];
|
||||
datumPtr->cameraExtrinsics = cameraExtrinsics[0];
|
||||
datumPtr->cameraIntrinsics = cameraIntrinsics[0];
|
||||
}
|
||||
// Image integrity
|
||||
if (datum.cvInputData.channels() != 3)
|
||||
if (datumPtr->cvInputData.channels() != 3)
|
||||
{
|
||||
const std::string commonMessage{"Input images must be 3-channel BGR."};
|
||||
// Grey to RGB if required
|
||||
if (datum.cvInputData.channels() == 1)
|
||||
if (datumPtr->cvInputData.channels() == 1)
|
||||
{
|
||||
log(commonMessage + " Converting grey image into BGR.", Priority::High);
|
||||
cv::cvtColor(datum.cvInputData, datum.cvInputData, CV_GRAY2BGR);
|
||||
cv::cvtColor(datumPtr->cvInputData, datumPtr->cvInputData, CV_GRAY2BGR);
|
||||
}
|
||||
else
|
||||
error(commonMessage, __LINE__, __FUNCTION__, __FILE__);
|
||||
}
|
||||
datum.cvOutputData = datum.cvInputData;
|
||||
datumPtr->cvOutputData = datumPtr->cvInputData;
|
||||
// Resize if it's stereo-system
|
||||
if (datums->size() > 1)
|
||||
{
|
||||
// Stereo-system: Assign all cv::Mat
|
||||
for (auto i = 1u ; i < datums->size() ; i++)
|
||||
{
|
||||
auto& datumI = (*datums)[i];
|
||||
datumI.name = datum.name;
|
||||
datumI.frameNumber = datum.frameNumber;
|
||||
datumI.cvInputData = cvMats[i];
|
||||
datumI.cvOutputData = datumI.cvInputData;
|
||||
auto& datumIPtr = (*datums)[i];
|
||||
datumIPtr = std::make_shared<TDatum>();
|
||||
datumIPtr->name = datumPtr->name;
|
||||
datumIPtr->frameNumber = datumPtr->frameNumber;
|
||||
datumIPtr->cvInputData = cvMats[i];
|
||||
datumIPtr->cvOutputData = datumIPtr->cvInputData;
|
||||
if (cameraMatrices.size() > i)
|
||||
{
|
||||
datumI.cameraMatrix = cameraMatrices[i];
|
||||
datumI.cameraExtrinsics = cameraExtrinsics[i];
|
||||
datumI.cameraIntrinsics = cameraIntrinsics[i];
|
||||
datumIPtr->cameraMatrix = cameraMatrices[i];
|
||||
datumIPtr->cameraExtrinsics = cameraExtrinsics[i];
|
||||
datumIPtr->cameraIntrinsics = cameraIntrinsics[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check producer is running
|
||||
if (!datumProducerRunning || (*datums)[0].cvInputData.empty())
|
||||
if (!datumProducerRunning || (*datums)[0]->cvInputData.empty())
|
||||
datums = nullptr;
|
||||
// Increase counter if successful image
|
||||
if (datums != nullptr)
|
||||
@@ -195,13 +197,13 @@ namespace op
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
|
||||
return std::make_pair(false, std::make_shared<TDatumsNoPtr>());
|
||||
return std::make_pair(false, std::make_shared<std::vector<std::shared_ptr<TDatum>>>());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatumsNoPtr>
|
||||
void DatumProducer<TDatumsNoPtr>::checkIfTooManyConsecutiveEmptyFrames(unsigned int& numberConsecutiveEmptyFrames,
|
||||
const bool emptyFrame) const
|
||||
template<typename TDatum>
|
||||
void DatumProducer<TDatum>::checkIfTooManyConsecutiveEmptyFrames(
|
||||
unsigned int& numberConsecutiveEmptyFrames, const bool emptyFrame) const
|
||||
{
|
||||
numberConsecutiveEmptyFrames = (emptyFrame ? numberConsecutiveEmptyFrames+1 : 0);
|
||||
const auto threshold = 500u;
|
||||
@@ -210,7 +212,7 @@ namespace op
|
||||
__LINE__, __FUNCTION__, __FILE__);
|
||||
}
|
||||
|
||||
extern template class DatumProducer<DATUM_BASE_NO_PTR>;
|
||||
extern template class DatumProducer<BASE_DATUM>;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,21 +9,21 @@
|
||||
|
||||
namespace op
|
||||
{
|
||||
template<typename TDatums, typename TDatumsNoPtr>
|
||||
class WDatumProducer : public WorkerProducer<TDatums>
|
||||
template<typename TDatum>
|
||||
class WDatumProducer : public WorkerProducer<std::shared_ptr<std::vector<std::shared_ptr<TDatum>>>>
|
||||
{
|
||||
public:
|
||||
explicit WDatumProducer(const std::shared_ptr<DatumProducer<TDatumsNoPtr>>& datumProducer);
|
||||
explicit WDatumProducer(const std::shared_ptr<DatumProducer<TDatum>>& datumProducer);
|
||||
|
||||
virtual ~WDatumProducer();
|
||||
|
||||
void initializationOnThread();
|
||||
|
||||
TDatums workProducer();
|
||||
std::shared_ptr<std::vector<std::shared_ptr<TDatum>>> workProducer();
|
||||
|
||||
private:
|
||||
std::shared_ptr<DatumProducer<TDatumsNoPtr>> spDatumProducer;
|
||||
std::queue<TDatums> mQueuedElements;
|
||||
std::shared_ptr<DatumProducer<TDatum>> spDatumProducer;
|
||||
std::queue<std::shared_ptr<std::vector<std::shared_ptr<TDatum>>>> mQueuedElements;
|
||||
|
||||
DELETE_COPY(WDatumProducer);
|
||||
};
|
||||
@@ -37,25 +37,26 @@ namespace op
|
||||
#include <openpose/core/datum.hpp>
|
||||
namespace op
|
||||
{
|
||||
template<typename TDatums, typename TDatumsNoPtr>
|
||||
WDatumProducer<TDatums, TDatumsNoPtr>::WDatumProducer(const std::shared_ptr<DatumProducer<TDatumsNoPtr>>& datumProducer) :
|
||||
template<typename TDatum>
|
||||
WDatumProducer<TDatum>::WDatumProducer(
|
||||
const std::shared_ptr<DatumProducer<TDatum>>& datumProducer) :
|
||||
spDatumProducer{datumProducer}
|
||||
{
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsNoPtr>
|
||||
WDatumProducer<TDatums, TDatumsNoPtr>::~WDatumProducer()
|
||||
template<typename TDatum>
|
||||
WDatumProducer<TDatum>::~WDatumProducer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template<typename TDatums, typename TDatumsNoPtr>
|
||||
void WDatumProducer<TDatums, TDatumsNoPtr>::initializationOnThread()
|
||||
template<typename TDatum>
|
||||
void WDatumProducer<TDatum>::initializationOnThread()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsNoPtr>
|
||||
TDatums WDatumProducer<TDatums, TDatumsNoPtr>::workProducer()
|
||||
template<typename TDatum>
|
||||
std::shared_ptr<std::vector<std::shared_ptr<TDatum>>> WDatumProducer<TDatum>::workProducer()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -63,8 +64,8 @@ namespace op
|
||||
dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Create and fill TDatums
|
||||
std::shared_ptr<TDatumsNoPtr> tDatums;
|
||||
// Create and fill final shared pointer
|
||||
std::shared_ptr<std::vector<std::shared_ptr<TDatum>>> tDatums;
|
||||
// Producer
|
||||
if (mQueuedElements.empty())
|
||||
{
|
||||
@@ -80,17 +81,18 @@ namespace op
|
||||
dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
|
||||
}
|
||||
// Equivalent to WQueueSplitter
|
||||
// Queued elements - Multiple views --> Split views into different TDatums
|
||||
// Queued elements - Multiple views --> Split views into different share pointers
|
||||
if (tDatums != nullptr && tDatums->size() > 1)
|
||||
{
|
||||
// Add tDatums to mQueuedElements
|
||||
for (auto i = 0u ; i < tDatums->size() ; i++)
|
||||
{
|
||||
auto& tDatum = (*tDatums)[i];
|
||||
tDatum.subId = i;
|
||||
tDatum.subIdMax = tDatums->size()-1;
|
||||
auto& tDatumPtr = (*tDatums)[i];
|
||||
tDatumPtr->subId = i;
|
||||
tDatumPtr->subIdMax = tDatums->size()-1;
|
||||
mQueuedElements.emplace(
|
||||
std::make_shared<TDatumsNoPtr>(TDatumsNoPtr{tDatum}));
|
||||
std::make_shared<std::vector<std::shared_ptr<TDatum>>>(
|
||||
std::vector<std::shared_ptr<TDatum>>{tDatumPtr}));
|
||||
}
|
||||
}
|
||||
// Queued elements - Multiple views --> Return oldest view
|
||||
@@ -99,18 +101,18 @@ namespace op
|
||||
tDatums = mQueuedElements.front();
|
||||
mQueuedElements.pop();
|
||||
}
|
||||
// Return TDatums
|
||||
// Return result
|
||||
return tDatums;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
this->stop();
|
||||
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
|
||||
return TDatums{};
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
extern template class WDatumProducer<DATUM_BASE, DATUM_BASE_NO_PTR>;
|
||||
extern template class WDatumProducer<BASE_DATUM>;
|
||||
}
|
||||
|
||||
#endif // OPENPOSE_PRODUCER_W_DATUM_PRODUCER_HPP
|
||||
|
||||
@@ -514,8 +514,11 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
extern template class QueueBase<DATUM_BASE, std::queue<DATUM_BASE>>;
|
||||
extern template class QueueBase<DATUM_BASE, std::priority_queue<DATUM_BASE, std::vector<DATUM_BASE>, std::greater<DATUM_BASE>>>;
|
||||
extern template class QueueBase<BASE_DATUMS_SH, std::queue<BASE_DATUMS_SH>>;
|
||||
extern template class QueueBase<
|
||||
BASE_DATUMS_SH,
|
||||
std::priority_queue<BASE_DATUMS_SH, std::vector<BASE_DATUMS_SH>,
|
||||
std::greater<BASE_DATUMS_SH>>>;
|
||||
}
|
||||
|
||||
#endif // OPENPOSE_THREAD_QUEUE_BASE_HPP
|
||||
|
||||
@@ -63,13 +63,13 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Add ID
|
||||
for (auto& tDatum : *tDatums)
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
// To avoid overwritting ID if e.g., custom input has already filled it
|
||||
if (tDatum.id == std::numeric_limits<unsigned long long>::max())
|
||||
tDatum.id = mGlobalCounter;
|
||||
if (tDatumPtr->id == std::numeric_limits<unsigned long long>::max())
|
||||
tDatumPtr->id = mGlobalCounter;
|
||||
// Increase ID
|
||||
const auto& tDatum = (*tDatums)[0];
|
||||
if (tDatum.subId == tDatum.subIdMax)
|
||||
const auto& tDatumPtr = (*tDatums)[0];
|
||||
if (tDatumPtr->subId == tDatumPtr->subIdMax)
|
||||
mGlobalCounter++;
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
|
||||
@@ -13,8 +13,8 @@ namespace op
|
||||
// with the same GPU. In this way, this work is parallelized over GPUs (1 view for each).
|
||||
// Pros: Latency highly recuded, same speed
|
||||
// Cons: Requires these extra 2 classes and proper threads for them
|
||||
template<typename TDatums, typename TDatumsNoPtr>
|
||||
class WQueueAssembler : public Worker<TDatums>
|
||||
template<typename TDatums>
|
||||
class WQueueAssembler : public Worker<std::shared_ptr<TDatums>>
|
||||
{
|
||||
public:
|
||||
explicit WQueueAssembler();
|
||||
@@ -23,10 +23,10 @@ namespace op
|
||||
|
||||
void initializationOnThread();
|
||||
|
||||
void work(TDatums& tDatums);
|
||||
void work(std::shared_ptr<TDatums>& tDatums);
|
||||
|
||||
private:
|
||||
TDatums mNextTDatums;
|
||||
std::shared_ptr<TDatums> mNextTDatums;
|
||||
|
||||
DELETE_COPY(WQueueAssembler);
|
||||
};
|
||||
@@ -39,23 +39,23 @@ namespace op
|
||||
// Implementation
|
||||
namespace op
|
||||
{
|
||||
template<typename TDatums, typename TDatumsNoPtr>
|
||||
WQueueAssembler<TDatums, TDatumsNoPtr>::WQueueAssembler()
|
||||
template<typename TDatums>
|
||||
WQueueAssembler<TDatums>::WQueueAssembler()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsNoPtr>
|
||||
WQueueAssembler<TDatums, TDatumsNoPtr>::~WQueueAssembler()
|
||||
template<typename TDatums>
|
||||
WQueueAssembler<TDatums>::~WQueueAssembler()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsNoPtr>
|
||||
void WQueueAssembler<TDatums, TDatumsNoPtr>::initializationOnThread()
|
||||
template<typename TDatums>
|
||||
void WQueueAssembler<TDatums>::initializationOnThread()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsNoPtr>
|
||||
void WQueueAssembler<TDatums, TDatumsNoPtr>::work(TDatums& tDatums)
|
||||
template<typename TDatums>
|
||||
void WQueueAssembler<TDatums>::work(std::shared_ptr<TDatums>& tDatums)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -70,17 +70,17 @@ namespace op
|
||||
" was applied in the first place, i.e., that there is only 1 element"
|
||||
" per TDatums (size = " + std::to_string(tDatums->size()) + ").",
|
||||
__LINE__, __FUNCTION__, __FILE__);
|
||||
auto tDatum = (*tDatums)[0];
|
||||
auto tDatumPtr = (*tDatums)[0];
|
||||
// Single view --> Return
|
||||
if (tDatum.subIdMax == 0)
|
||||
if (tDatumPtr->subIdMax == 0)
|
||||
return;
|
||||
// Multiple view --> Merge views into different TDatums (1st frame)
|
||||
if (mNextTDatums == nullptr)
|
||||
mNextTDatums = std::make_shared<TDatumsNoPtr>();
|
||||
mNextTDatums = std::make_shared<TDatums>();
|
||||
// Multiple view --> Merge views into different TDatums
|
||||
mNextTDatums->emplace_back(tDatum);
|
||||
mNextTDatums->emplace_back(tDatumPtr);
|
||||
// Last view - Return frame
|
||||
if (mNextTDatums->back().subId == mNextTDatums->back().subIdMax)
|
||||
if (mNextTDatums->back()->subId == mNextTDatums->back()->subIdMax)
|
||||
{
|
||||
tDatums = mNextTDatums;
|
||||
mNextTDatums = nullptr;
|
||||
@@ -106,7 +106,7 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
extern template class WQueueAssembler<DATUM_BASE, DATUM_BASE_NO_PTR>;
|
||||
extern template class WQueueAssembler<BASE_DATUMS>;
|
||||
}
|
||||
|
||||
#endif // OPENPOSE_THREAD_W_QUEUE_ASSEMBLER_HPP
|
||||
|
||||
@@ -73,16 +73,16 @@ namespace op
|
||||
// T* to T
|
||||
auto& tDatumsNoPtr = *tDatums;
|
||||
// tDatums is the next expected, update counter
|
||||
if (tDatumsNoPtr[0].id == mNextExpectedId && tDatumsNoPtr[0].subId == mNextExpectedSubId)
|
||||
if (tDatumsNoPtr[0]->id == mNextExpectedId && tDatumsNoPtr[0]->subId == mNextExpectedSubId)
|
||||
{
|
||||
// If single-view
|
||||
if (tDatumsNoPtr[0].subIdMax == 0)
|
||||
if (tDatumsNoPtr[0]->subIdMax == 0)
|
||||
mNextExpectedId++;
|
||||
// If muilti-view system
|
||||
else
|
||||
{
|
||||
mNextExpectedSubId++;
|
||||
if (mNextExpectedSubId > tDatumsNoPtr[0].subIdMax)
|
||||
if (mNextExpectedSubId > tDatumsNoPtr[0]->subIdMax)
|
||||
{
|
||||
mNextExpectedSubId = 0;
|
||||
mNextExpectedId++;
|
||||
@@ -109,8 +109,8 @@ namespace op
|
||||
// Retrieve frame if next is desired frame or if we want to stop this worker
|
||||
if (!mPriorityQueueBuffer.empty()
|
||||
&& (mStopWhenEmpty ||
|
||||
((*mPriorityQueueBuffer.top())[0].id == mNextExpectedId
|
||||
&& (*mPriorityQueueBuffer.top())[0].subId == mNextExpectedSubId)))
|
||||
((*mPriorityQueueBuffer.top())[0]->id == mNextExpectedId
|
||||
&& (*mPriorityQueueBuffer.top())[0]->subId == mNextExpectedSubId)))
|
||||
{
|
||||
tDatums = { mPriorityQueueBuffer.top() };
|
||||
mPriorityQueueBuffer.pop();
|
||||
@@ -121,16 +121,16 @@ namespace op
|
||||
{
|
||||
const auto& tDatumsNoPtr = *tDatums;
|
||||
// If single-view
|
||||
if (tDatumsNoPtr[0].subIdMax == 0)
|
||||
mNextExpectedId = tDatumsNoPtr[0].id + 1;
|
||||
if (tDatumsNoPtr[0]->subIdMax == 0)
|
||||
mNextExpectedId = tDatumsNoPtr[0]->id + 1;
|
||||
// If muilti-view system
|
||||
else
|
||||
{
|
||||
mNextExpectedSubId = tDatumsNoPtr[0].subId + 1;
|
||||
if (mNextExpectedSubId > tDatumsNoPtr[0].subIdMax)
|
||||
mNextExpectedSubId = tDatumsNoPtr[0]->subId + 1;
|
||||
if (mNextExpectedSubId > tDatumsNoPtr[0]->subIdMax)
|
||||
{
|
||||
mNextExpectedSubId = 0;
|
||||
mNextExpectedId = tDatumsNoPtr[0].id + 1;
|
||||
mNextExpectedId = tDatumsNoPtr[0]->id + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,8 +62,9 @@ namespace op
|
||||
// Profiling speed
|
||||
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
|
||||
// Render people pose
|
||||
for (auto& tDatum : *tDatums)
|
||||
tDatum.poseIds = spPersonIdExtractor->extractIds(tDatum.poseKeypoints, tDatum.cvInputData);
|
||||
for (auto& tDatumPtr : *tDatums)
|
||||
tDatumPtr->poseIds = spPersonIdExtractor->extractIds(
|
||||
tDatumPtr->poseKeypoints, tDatumPtr->cvInputData);
|
||||
// Profiling speed
|
||||
Profiler::timerEnd(profilerKey);
|
||||
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
@@ -29,7 +29,8 @@ namespace op
|
||||
* - Asynchronous input + synchronous output: call the constructor
|
||||
* WrapperT(ThreadManagerMode::Synchronous, nullptr, workersOutput, irrelevantBoolean, true)
|
||||
*/
|
||||
template<typename TDatums = std::vector<Datum>,
|
||||
template<typename TDatum = BASE_DATUM,
|
||||
typename TDatums = std::vector<std::shared_ptr<TDatum>>,
|
||||
typename TDatumsSP = std::shared_ptr<TDatums>,
|
||||
typename TWorker = std::shared_ptr<Worker<TDatumsSP>>>
|
||||
class WrapperT
|
||||
@@ -216,7 +217,7 @@ namespace op
|
||||
};
|
||||
|
||||
// Type
|
||||
typedef WrapperT<DATUM_BASE_NO_PTR> Wrapper;
|
||||
typedef WrapperT<BASE_DATUM> Wrapper;
|
||||
}
|
||||
|
||||
|
||||
@@ -227,16 +228,16 @@ namespace op
|
||||
#include <openpose/wrapper/wrapperAuxiliary.hpp>
|
||||
namespace op
|
||||
{
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
WrapperT<TDatums, TDatumsSP, TWorker>::WrapperT(const ThreadManagerMode threadManagerMode) :
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::WrapperT(const ThreadManagerMode threadManagerMode) :
|
||||
mThreadManagerMode{threadManagerMode},
|
||||
mThreadManager{threadManagerMode},
|
||||
mMultiThreadEnabled{true}
|
||||
{
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
WrapperT<TDatums, TDatumsSP, TWorker>::~WrapperT()
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::~WrapperT()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -253,8 +254,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatums, TDatumsSP, TWorker>::disableMultiThreading()
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::disableMultiThreading()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -266,8 +267,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatums, TDatumsSP, TWorker>::setWorker(
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::setWorker(
|
||||
const WorkerType workerType, const TWorker& worker, const bool workerOnNewThread)
|
||||
{
|
||||
try
|
||||
@@ -286,8 +287,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatums, TDatumsSP, TWorker>::configure(const WrapperStructPose& wrapperStructPose)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::configure(const WrapperStructPose& wrapperStructPose)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -299,8 +300,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatums, TDatumsSP, TWorker>::configure(const WrapperStructFace& wrapperStructFace)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::configure(const WrapperStructFace& wrapperStructFace)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -312,8 +313,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatums, TDatumsSP, TWorker>::configure(const WrapperStructHand& wrapperStructHand)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::configure(const WrapperStructHand& wrapperStructHand)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -325,8 +326,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatums, TDatumsSP, TWorker>::configure(const WrapperStructExtra& wrapperStructExtra)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::configure(const WrapperStructExtra& wrapperStructExtra)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -338,8 +339,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatums, TDatumsSP, TWorker>::configure(const WrapperStructInput& wrapperStructInput)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::configure(const WrapperStructInput& wrapperStructInput)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -351,8 +352,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatums, TDatumsSP, TWorker>::configure(const WrapperStructOutput& wrapperStructOutput)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::configure(const WrapperStructOutput& wrapperStructOutput)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -364,8 +365,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatums, TDatumsSP, TWorker>::configure(const WrapperStructGui& wrapperStructGui)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::configure(const WrapperStructGui& wrapperStructGui)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -377,12 +378,12 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatums, TDatumsSP, TWorker>::exec()
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::exec()
|
||||
{
|
||||
try
|
||||
{
|
||||
configureThreadManager<TDatums, TDatumsSP, TWorker>(
|
||||
configureThreadManager<TDatum, TDatums, TDatumsSP, TWorker>(
|
||||
mThreadManager, mMultiThreadEnabled, mThreadManagerMode, mWrapperStructPose, mWrapperStructFace,
|
||||
mWrapperStructHand, mWrapperStructExtra, mWrapperStructInput, mWrapperStructOutput, mWrapperStructGui,
|
||||
mUserWs, mUserWsOnNewThread);
|
||||
@@ -395,12 +396,12 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatums, TDatumsSP, TWorker>::start()
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::start()
|
||||
{
|
||||
try
|
||||
{
|
||||
configureThreadManager<TDatums, TDatumsSP, TWorker>(
|
||||
configureThreadManager<TDatum, TDatums, TDatumsSP, TWorker>(
|
||||
mThreadManager, mMultiThreadEnabled, mThreadManagerMode, mWrapperStructPose, mWrapperStructFace,
|
||||
mWrapperStructHand, mWrapperStructExtra, mWrapperStructInput, mWrapperStructOutput, mWrapperStructGui,
|
||||
mUserWs, mUserWsOnNewThread);
|
||||
@@ -413,8 +414,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatums, TDatumsSP, TWorker>::stop()
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -426,8 +427,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatums, TDatumsSP, TWorker>::isRunning() const
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::isRunning() const
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -440,8 +441,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatums, TDatumsSP, TWorker>::tryEmplace(TDatumsSP& tDatums)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::tryEmplace(TDatumsSP& tDatums)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -457,8 +458,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatums, TDatumsSP, TWorker>::waitAndEmplace(TDatumsSP& tDatums)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::waitAndEmplace(TDatumsSP& tDatums)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -474,8 +475,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatums, TDatumsSP, TWorker>::tryPush(const TDatumsSP& tDatums)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::tryPush(const TDatumsSP& tDatums)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -491,8 +492,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatums, TDatumsSP, TWorker>::waitAndPush(const TDatumsSP& tDatums)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::waitAndPush(const TDatumsSP& tDatums)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -508,8 +509,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatums, TDatumsSP, TWorker>::tryPop(TDatumsSP& tDatums)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::tryPop(TDatumsSP& tDatums)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -525,8 +526,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatums, TDatumsSP, TWorker>::waitAndPop(TDatumsSP& tDatums)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::waitAndPop(TDatumsSP& tDatums)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -542,8 +543,8 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatums, TDatumsSP, TWorker>::emplaceAndPop(TDatumsSP& tDatums)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
bool WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::emplaceAndPop(TDatumsSP& tDatums)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -559,17 +560,18 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
TDatumsSP WrapperT<TDatums, TDatumsSP, TWorker>::emplaceAndPop(const cv::Mat& cvMat)
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
TDatumsSP WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::emplaceAndPop(const cv::Mat& cvMat)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Create new datum
|
||||
auto datumsPtr = std::make_shared<TDatums>();
|
||||
auto datumsPtr = std::make_shared<std::vector<std::shared_ptr<TDatum>>>();
|
||||
datumsPtr->emplace_back();
|
||||
auto& datum = datumsPtr->at(0);
|
||||
auto& tDatumPtr = datumsPtr->at(0);
|
||||
tDatumPtr = std::make_shared<TDatum>();
|
||||
// Fill datum
|
||||
datum.cvInputData = cvMat;
|
||||
tDatumPtr->cvInputData = cvMat;
|
||||
// Emplace and pop
|
||||
emplaceAndPop(datumsPtr);
|
||||
// Return result
|
||||
@@ -582,7 +584,7 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
extern template class WrapperT<DATUM_BASE_NO_PTR>;
|
||||
extern template class WrapperT<BASE_DATUM>;
|
||||
}
|
||||
|
||||
#endif // OPENPOSE_WRAPPER_WRAPPER_HPP
|
||||
|
||||
@@ -49,7 +49,8 @@ namespace op
|
||||
* and adds them.
|
||||
* Common code for start() and exec().
|
||||
*/
|
||||
template<typename TDatums,
|
||||
template<typename TDatum,
|
||||
typename TDatums = std::vector<std::shared_ptr<TDatum>>,
|
||||
typename TDatumsSP = std::shared_ptr<TDatums>,
|
||||
typename TWorker = std::shared_ptr<Worker<TDatumsSP>>>
|
||||
void configureThreadManager(
|
||||
@@ -81,7 +82,7 @@ namespace op
|
||||
#include <openpose/utilities/standard.hpp>
|
||||
namespace op
|
||||
{
|
||||
template<typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
|
||||
void configureThreadManager(
|
||||
ThreadManager<TDatumsSP>& threadManager, const bool multiThreadEnabledTemp,
|
||||
const ThreadManagerMode threadManagerMode, const WrapperStructPose& wrapperStructPoseTemp,
|
||||
@@ -210,11 +211,11 @@ namespace op
|
||||
TWorker datumProducerW;
|
||||
if (oPProducer)
|
||||
{
|
||||
const auto datumProducer = std::make_shared<DatumProducer<TDatums>>(
|
||||
const auto datumProducer = std::make_shared<DatumProducer<TDatum>>(
|
||||
producerSharedPtr, wrapperStructInput.frameFirst, wrapperStructInput.frameStep,
|
||||
wrapperStructInput.frameLast, spVideoSeek
|
||||
);
|
||||
datumProducerW = std::make_shared<WDatumProducer<TDatumsSP, TDatums>>(datumProducer);
|
||||
datumProducerW = std::make_shared<WDatumProducer<TDatum>>(datumProducer);
|
||||
}
|
||||
else
|
||||
datumProducerW = nullptr;
|
||||
@@ -931,7 +932,7 @@ namespace op
|
||||
}
|
||||
}
|
||||
// Assemble all frames from same time instant (3-D module)
|
||||
const auto wQueueAssembler = std::make_shared<WQueueAssembler<TDatumsSP, TDatums>>();
|
||||
const auto wQueueAssembler = std::make_shared<WQueueAssembler<TDatums>>();
|
||||
// 3-D reconstruction
|
||||
if (!poseTriangulationsWs.empty())
|
||||
{
|
||||
|
||||
@@ -109,6 +109,7 @@ endif
|
||||
WITH_EIGEN ?= 0
|
||||
ifneq ($(WITH_EIGEN), 0)
|
||||
COMMON_FLAGS += -DUSE_EIGEN
|
||||
INCLUDE_DIRS += $(EIGEN_DIR)
|
||||
endif
|
||||
# Spinnaker SDK
|
||||
WITH_FLIR_CAMERA ?= 0
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
namespace op
|
||||
{
|
||||
template class OP_API DatumProducer<DATUM_BASE_NO_PTR>;
|
||||
template class OP_API WDatumProducer<DATUM_BASE, DATUM_BASE_NO_PTR>;
|
||||
template class OP_API DatumProducer<BASE_DATUM>;
|
||||
template class OP_API WDatumProducer<BASE_DATUM>;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,11 @@ namespace op
|
||||
// Queues
|
||||
DEFINE_TEMPLATE_DATUM(PriorityQueue);
|
||||
DEFINE_TEMPLATE_DATUM(Queue);
|
||||
template class OP_API QueueBase<DATUM_BASE, std::queue<DATUM_BASE>>;
|
||||
template class OP_API QueueBase<DATUM_BASE, std::priority_queue<DATUM_BASE, std::vector<DATUM_BASE>, std::greater<DATUM_BASE>>>;
|
||||
template class OP_API QueueBase<BASE_DATUMS_SH, std::queue<BASE_DATUMS_SH>>;
|
||||
template class OP_API QueueBase<
|
||||
BASE_DATUMS_SH,
|
||||
std::priority_queue<BASE_DATUMS_SH, std::vector<BASE_DATUMS_SH>,
|
||||
std::greater<BASE_DATUMS_SH>>>;
|
||||
// Subthread
|
||||
DEFINE_TEMPLATE_DATUM(SubThread);
|
||||
DEFINE_TEMPLATE_DATUM(SubThreadNoQueue);
|
||||
@@ -23,6 +26,6 @@ namespace op
|
||||
// W-classes
|
||||
DEFINE_TEMPLATE_DATUM(WFpsMax);
|
||||
DEFINE_TEMPLATE_DATUM(WIdGenerator);
|
||||
template class OP_API WQueueAssembler<DATUM_BASE, DATUM_BASE_NO_PTR>;
|
||||
template class OP_API WQueueAssembler<BASE_DATUMS>;
|
||||
DEFINE_TEMPLATE_DATUM(WQueueOrderer);
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
|
||||
namespace op
|
||||
{
|
||||
template class OP_API WrapperT<DATUM_BASE_NO_PTR>;
|
||||
template class OP_API WrapperT<BASE_DATUM>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user