Wrapper template simplified

This commit is contained in:
gineshidalgo99
2019-01-08 20:05:08 -05:00
parent fbee9b6524
commit ea771954ea
71 changed files with 576 additions and 540 deletions
+1 -1
View File
@@ -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.
+4 -4
View File
@@ -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.
+1
View File
@@ -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.
+1 -1
View File
@@ -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,
+24 -22
View File
@@ -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__);
+13 -13
View 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);
+5 -4
View File
@@ -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
+3 -4
View File
@@ -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__);
+3 -3
View 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__);
+9 -7
View 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);
+10 -7
View File
@@ -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);
+2 -2
View File
@@ -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);
+2 -2
View File
@@ -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);
+2 -2
View 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 = 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__);
+4 -4
View 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);
+3 -3
View File
@@ -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__);
+3 -3
View 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__);
+3 -2
View 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);
+4 -3
View File
@@ -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);
+3 -2
View File
@@ -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);
+3 -2
View File
@@ -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);
+12 -12
View File
@@ -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
+1 -1
View File
@@ -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__);
+2 -2
View 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
+8 -7
View File
@@ -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())
+8 -8
View File
@@ -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();
+6 -5
View File
@@ -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__);
+2 -2
View 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__);
+4 -4
View 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
+3 -3
View File
@@ -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__);
+13 -13
View 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);
+9 -9
View File
@@ -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);
+4 -4
View File
@@ -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__);
+47 -45
View 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>;
}
+26 -24
View File
@@ -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
+5 -2
View File
@@ -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
+5 -5
View File
@@ -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);
+18 -18
View File
@@ -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
+10 -10
View File
@@ -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__);
+56 -54
View 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())
{
+1
View File
@@ -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 -2
View File
@@ -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>;
}
+6 -3
View File
@@ -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);
}
+1 -1
View File
@@ -2,5 +2,5 @@
namespace op
{
template class OP_API WrapperT<DATUM_BASE_NO_PTR>;
template class OP_API WrapperT<BASE_DATUM>;
}