提交 efdf39d6 编写于 作者: G gineshidalgo99

Queue size configurable through wrapper and cleaned examples

上级 5f768fe5
......@@ -26,7 +26,7 @@ void display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& dat
if (datumsPtr != nullptr && !datumsPtr->empty())
{
// Display image
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
cv::waitKey(0);
}
else
......
......@@ -26,7 +26,7 @@ void display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& dat
if (datumsPtr != nullptr && !datumsPtr->empty())
{
// Display image
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
cv::waitKey(0);
}
else
......
......@@ -28,7 +28,7 @@ void display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& dat
if (datumsPtr != nullptr && !datumsPtr->empty())
{
// Display image
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
cv::waitKey(0);
}
else
......
......@@ -11,7 +11,7 @@
// Custom OpenPose flags
// Producer
DEFINE_string(image_dir, "examples/media/",
DEFINE_string(image_dir, "examples/media/",
"Process a directory of images. Read all standard formats (jpg, png, bmp, etc.).");
// Display
DEFINE_bool(no_display, false,
......@@ -29,7 +29,7 @@ bool display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& dat
if (datumsPtr != nullptr && !datumsPtr->empty())
{
// Display image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
key = (char)cv::waitKey(1);
}
else
......
......@@ -11,8 +11,14 @@
// Custom OpenPose flags
// Producer
DEFINE_string(image_dir, "examples/media/",
DEFINE_string(image_dir, "examples/media/",
"Process a directory of images. Read all standard formats (jpg, png, bmp, etc.).");
// OpenPose
DEFINE_bool(latency_is_irrelevant_and_computer_with_lots_of_ram, false,
"If false, it will read and then then process images right away. If true, it will first store all the frames and"
" later process them (slightly faster). However: 1) Latency will hugely increase (no frames will be processed"
" until they have all been read). And 2) The program might go out of RAM memory with long videos or folders with"
" many images (so the computer might freeze).");
// Display
DEFINE_bool(no_display, false,
"Enable to disable the visual display.");
......@@ -29,7 +35,7 @@ bool display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& dat
if (datumsPtr != nullptr && !datumsPtr->empty())
{
// Display image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
key = (char)cv::waitKey(1);
}
else
......@@ -160,6 +166,9 @@ int tutorialApiCpp()
op::log("Configuring OpenPose...", op::Priority::High);
op::Wrapper opWrapper{op::ThreadManagerMode::Asynchronous};
configureWrapper(opWrapper);
// Increase maximum wrapper queue size
if (FLAGS_latency_is_irrelevant_and_computer_with_lots_of_ram)
opWrapper.setDefaultMaxSizeQueues(std::numeric_limits<long long>::max());
// Starting OpenPose
op::log("Starting thread(s)...", op::Priority::High);
......@@ -177,12 +186,63 @@ int tutorialApiCpp()
// 1. One pushing images to OpenPose all the time.
// 2. A second one retrieving those frames.
// Option b) Much easier and faster to implement but slightly slower runtime performance
for (auto imageId = 0u ; imageId < imagePaths.size() ; imageId+=numberGPUs)
if (!FLAGS_latency_is_irrelevant_and_computer_with_lots_of_ram)
{
// Read and push images into OpenPose wrapper
for (auto gpuId = 0 ; gpuId < numberGPUs ; gpuId++)
for (auto imageBaseId = 0u ; imageBaseId < imagePaths.size() ; imageBaseId+=numberGPUs)
{
// Read and push images into OpenPose wrapper
for (auto gpuId = 0 ; gpuId < numberGPUs ; gpuId++)
{
const auto imageId = imageBaseId+gpuId;
if (imageId < imagePaths.size())
{
const auto& imagePath = imagePaths.at(imageId);
// Faster alternative that moves imageToProcess
auto imageToProcess = cv::imread(imagePath);
opWrapper.waitAndEmplace(imageToProcess);
// // Slower but safer alternative that copies imageToProcess
// const auto imageToProcess = cv::imread(imagePath);
// opWrapper.waitAndPush(imageToProcess);
}
}
// Retrieve processed results from OpenPose wrapper
for (auto gpuId = 0 ; gpuId < numberGPUs ; gpuId++)
{
const auto imageId = imageBaseId+gpuId;
if (imageId < imagePaths.size())
{
std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>> datumProcessed;
const auto status = opWrapper.waitAndPop(datumProcessed);
if (status && datumProcessed != nullptr)
{
printKeypoints(datumProcessed);
if (!FLAGS_no_display)
{
const auto userWantsToExit = display(datumProcessed);
if (userWantsToExit)
{
op::log("User pressed Esc to exit demo.", op::Priority::High);
break;
}
}
}
else
op::log("Image could not be processed.", op::Priority::High);
}
}
}
}
// Option c) Even easier and faster to implement than option b. In addition, its runtime performance should
// be slightly faster too, but:
// - Latency will hugely increase (no frames will be processed until they have all been read).
// - The program might go out of RAM memory with long videos or folders with many images (so the computer
// might freeze).
else
{
// Read and push all images into OpenPose wrapper
op::log("Loading images into OpenPose wrapper...", op::Priority::High);
for (const auto& imagePath : imagePaths)
{
const auto& imagePath = imagePaths.at(imageId+gpuId);
// Faster alternative that moves imageToProcess
auto imageToProcess = cv::imread(imagePath);
opWrapper.waitAndEmplace(imageToProcess);
......@@ -191,7 +251,8 @@ int tutorialApiCpp()
// opWrapper.waitAndPush(imageToProcess);
}
// Retrieve processed results from OpenPose wrapper
for (auto gpuId = 0 ; gpuId < numberGPUs ; gpuId++)
op::log("Retrieving results from OpenPose wrapper...", op::Priority::High);
for (auto imageId = 0u ; imageId < imagePaths.size() ; imageId++)
{
std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>> datumProcessed;
const auto status = opWrapper.waitAndPop(datumProcessed);
......
// ----------------------------- OpenPose C++ API Tutorial - Example 9 - Face from Image -----------------------------
// ----------------------------- OpenPose C++ API Tutorial - Example 6 - Face from Image -----------------------------
// It reads an image and the face location, process it, and displays the face keypoints. In addition,
// it includes all the OpenPose configuration flags.
// Input: An image and the face rectangle locations.
......@@ -31,7 +31,7 @@ void display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& dat
if (datumsPtr != nullptr && !datumsPtr->empty())
{
// Display image
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
cv::waitKey(0);
}
else
......
// ----------------------------- OpenPose C++ API Tutorial - Example 9 - Face from Image -----------------------------
// ----------------------------- OpenPose C++ API Tutorial - Example 7 - Face from Image -----------------------------
// It reads an image and the hand location, process it, and displays the hand keypoints. In addition,
// it includes all the OpenPose configuration flags.
// Input: An image and the hand rectangle locations.
......@@ -31,7 +31,7 @@ void display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& dat
if (datumsPtr != nullptr && !datumsPtr->empty())
{
// Display image
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
cv::waitKey(0);
}
else
......
// ------------------------- OpenPose C++ API Tutorial - Example 6 - Custom Input -------------------------
// ------------------------- OpenPose C++ API Tutorial - Example 9 - Custom Input -------------------------
// Asynchronous mode: ideal for fast prototyping when performance is not an issue.
// In this function, the user can implement its own way to create frames (e.g., reading his own folder of images)
// and emplaces/pushes the frames to OpenPose.
......@@ -11,13 +11,9 @@
// Custom OpenPose flags
// Producer
DEFINE_string(image_dir, "examples/media/",
DEFINE_string(image_dir, "examples/media/",
"Process a directory of images. Read all standard formats (jpg, png, bmp, etc.).");
// The W-classes can be implemented either as a template or as simple classes 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
// This worker will just read and return all the basic image file formats in a directory
class UserInputClass
{
......
// ------------------------- OpenPose C++ API Tutorial - Example 7 - Custom Output -------------------------
// ------------------------- OpenPose C++ API Tutorial - Example 10 - Custom Output -------------------------
// Asynchronous mode: ideal for fast prototyping when performance is not an issue.
// In this function, the user can implement its own way to render/display the frames.
// In this function, the user can implement its own way to render/display/storage the results.
// Command-line user intraface
#define OPENPOSE_FLAGS_DISABLE_DISPLAY
......@@ -13,10 +13,6 @@
DEFINE_bool(no_display, false,
"Enable to disable the visual display.");
// The W-classes can be implemented either as a template or as simple classes 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
// This worker will just read and return all the jpg files in a directory
class UserOutputClass
{
......@@ -29,7 +25,7 @@ public:
char key = ' ';
if (datumsPtr != nullptr && !datumsPtr->empty())
{
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", 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);
}
......
// ------------------------- OpenPose C++ API Tutorial - Example 8 - Custom Input and Output -------------------------
// --------------------- OpenPose C++ API Tutorial - Example 11 - Custom Input, Output, and Datum ---------------------
// Asynchronous mode: ideal for fast prototyping when performance is not an issue.
// In this function, the user can implement its own way to create frames (e.g., reading his own folder of images)
// and its own way to render/display them after being processed by OpenPose.
......@@ -12,7 +12,7 @@
// Custom OpenPose flags
// Producer
DEFINE_string(image_dir, "examples/media/",
DEFINE_string(image_dir, "examples/media/",
"Process a directory of images. Read all standard formats (jpg, png, bmp, etc.).");
// Display
DEFINE_bool(no_display, false,
......@@ -31,10 +31,6 @@ struct UserDatum : public op::Datum
{}
};
// The W-classes can be implemented either as a template or as simple classes 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 UserDatum
// This worker will just read and return all the basic image file formats in a directory
class UserInputClass
{
......@@ -111,7 +107,7 @@ public:
if (datumsPtr != nullptr && !datumsPtr->empty())
{
// Display image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
key = (char)cv::waitKey(1);
}
else
......
// ------------------------- OpenPose C++ API Tutorial - Example 7 - XXXXXXXXXXXXX -------------------------
// If the user wants to learn to use the OpenPose library, we highly recommend to start with the
// examples in `examples/tutorial_api_cpp/`.
// This example summarizes all the functionality of the OpenPose library:
// 1. Read folder of images / video / webcam (`producer` module)
// 2. Extract and render body keypoint / heatmap / PAF of that image (`pose` module)
// 3. Extract and render face keypoint / heatmap / PAF of that image (`face` module)
// 4. Save the results on disk (`filestream` module)
// 5. Display the rendered pose (`gui` module)
// Everything in a multi-thread scenario (`thread` module)
// Points 2 to 5 are included in the `wrapper` module
// In addition to the previous OpenPose modules, we also need to use:
// 1. `core` module:
// For the Array<float> class that the `pose` module needs
// For the Datum struct that the `thread` module sends between the queues
// 2. `utilities` module: for the error & logging functions, i.e., op::error & op::log respectively
// This file should only be used for the user to take specific examples.
// ------------------------- OpenPose C++ API Tutorial - Example 12 - Custom Input -------------------------
// Synchronous mode: ideal for production integration. It provides the fastest results with respect to runtime
// performance.
// In this function, the user can implement its own way to create frames (e.g., reading his own folder of images).
// Command-line user intraface
#define OPENPOSE_FLAGS_DISABLE_PRODUCER
......@@ -24,28 +11,11 @@
// Custom OpenPose flags
// Producer
DEFINE_string(image_dir, "examples/media/",
DEFINE_string(image_dir, "examples/media/",
"Process a directory of images. Read all standard formats (jpg, png, bmp, etc.).");
// 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<std::shared_ptr<UserDatum>>> instead of Wrapper
// (or equivalently WrapperT<std::vector<std::shared_ptr<UserDatum>>>)
struct UserDatum : public op::Datum
{
bool boolThatUserNeedsForSomeReason;
UserDatum(const bool boolThatUserNeedsForSomeReason_ = false) :
boolThatUserNeedsForSomeReason{boolThatUserNeedsForSomeReason_}
{}
};
// The W-classes can be implemented either as a template or as simple classes 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 UserDatum
// This worker will just read and return all the basic image file formats in a directory
class WUserInput : public op::WorkerProducer<std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>>
class WUserInput : public op::WorkerProducer<std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>>
{
public:
WUserInput(const std::string& directoryPath) :
......@@ -60,7 +30,7 @@ public:
void initializationOnThread() {}
std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>> workProducer()
std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>> workProducer()
{
try
{
......@@ -77,10 +47,10 @@ public:
else
{
// Create new datum
auto datumsPtr = std::make_shared<std::vector<std::shared_ptr<UserDatum>>>();
auto datumsPtr = std::make_shared<std::vector<std::shared_ptr<op::Datum>>>();
datumsPtr->emplace_back();
auto& datumPtr = datumsPtr->at(0);
datumPtr = std::make_shared<UserDatum>();
datumPtr = std::make_shared<op::Datum>();
// Fill datum
datumPtr->cvInputData = cv::imread(mImageFiles.at(mCounter++));
......@@ -110,23 +80,17 @@ private:
unsigned long long mCounter;
};
int tutorialApiCpp()
void configureWrapper(op::Wrapper& opWrapper)
{
try
{
op::log("Starting OpenPose demo...", op::Priority::High);
const auto timerBegin = std::chrono::high_resolution_clock::now();
// Configuring OpenPose
// logging_level
op::check(0 <= FLAGS_logging_level && FLAGS_logging_level <= 255, "Wrong logging_level value.",
__LINE__, __FUNCTION__, __FILE__);
op::ConfigureLog::setPriorityThreshold((op::Priority)FLAGS_logging_level);
op::Profiler::setDefaultX(FLAGS_profile_speed);
// // For debugging
// // Print all logging messages
// op::ConfigureLog::setPriorityThreshold(op::Priority::None);
// // Print out speed values faster
// op::Profiler::setDefaultX(100);
// Applying user defined configuration - GFlags to program variables
// outputSize
......@@ -158,16 +122,12 @@ int tutorialApiCpp()
// Enabling Google Logging
const bool enableGoogleLogging = true;
// OpenPose wrapper
op::log("Configuring OpenPose...", op::Priority::High);
op::WrapperT<UserDatum> opWrapperT;
// Initializing the user custom classes
// Frames producer (e.g., video, webcam, ...)
auto wUserInput = std::make_shared<WUserInput>(FLAGS_image_dir);
// Add custom processing
const auto workerInputOnNewThread = true;
opWrapperT.setWorker(op::WorkerType::Input, wUserInput, workerInputOnNewThread);
opWrapper.setWorker(op::WorkerType::Input, wUserInput, workerInputOnNewThread);
// Pose configuration (use WrapperStructPose{} for default and recommended configuration)
const op::WrapperStructPose wrapperStructPose{
......@@ -177,23 +137,23 @@ int tutorialApiCpp()
FLAGS_part_to_show, FLAGS_model_folder, heatMapTypes, heatMapScaleMode, FLAGS_part_candidates,
(float)FLAGS_render_threshold, FLAGS_number_people_max, FLAGS_maximize_positives, FLAGS_fps_max,
FLAGS_prototxt_path, FLAGS_caffemodel_path, enableGoogleLogging};
opWrapperT.configure(wrapperStructPose);
opWrapper.configure(wrapperStructPose);
// Face configuration (use op::WrapperStructFace{} to disable it)
const op::WrapperStructFace wrapperStructFace{
FLAGS_face, faceDetector, faceNetInputSize,
op::flagsToRenderMode(FLAGS_face_render, multipleView, FLAGS_render_pose),
(float)FLAGS_face_alpha_pose, (float)FLAGS_face_alpha_heatmap, (float)FLAGS_face_render_threshold};
opWrapperT.configure(wrapperStructFace);
opWrapper.configure(wrapperStructFace);
// Hand configuration (use op::WrapperStructHand{} to disable it)
const op::WrapperStructHand wrapperStructHand{
FLAGS_hand, handDetector, handNetInputSize, FLAGS_hand_scale_number, (float)FLAGS_hand_scale_range,
op::flagsToRenderMode(FLAGS_hand_render, multipleView, FLAGS_render_pose), (float)FLAGS_hand_alpha_pose,
(float)FLAGS_hand_alpha_heatmap, (float)FLAGS_hand_render_threshold};
opWrapperT.configure(wrapperStructHand);
opWrapper.configure(wrapperStructHand);
// Extra functionality configuration (use op::WrapperStructExtra{} to disable it)
const op::WrapperStructExtra wrapperStructExtra{
FLAGS_3d, FLAGS_3d_min_views, FLAGS_identification, FLAGS_tracking, FLAGS_ik_threads};
opWrapperT.configure(wrapperStructExtra);
opWrapper.configure(wrapperStructExtra);
// Output (comment or use default argument to disable any output)
const op::WrapperStructOutput wrapperStructOutput{
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
......@@ -201,28 +161,41 @@ int tutorialApiCpp()
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
opWrapperT.configure(wrapperStructOutput);
opWrapper.configure(wrapperStructOutput);
// GUI (comment or use default argument to disable any visual output)
const op::WrapperStructGui wrapperStructGui{
op::flagsToDisplayMode(FLAGS_display, FLAGS_3d), !FLAGS_no_gui_verbose, FLAGS_fullscreen};
opWrapperT.configure(wrapperStructGui);
opWrapper.configure(wrapperStructGui);
// Set to single-thread (for sequential processing and/or debugging and/or reducing latency)
if (FLAGS_disable_multi_thread)
opWrapperT.disableMultiThreading();
opWrapper.disableMultiThreading();
}
catch (const std::exception& e)
{
op::error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
int tutorialApiCpp()
{
try
{
op::log("Starting OpenPose demo...", op::Priority::High);
const auto opTimer = op::getTimerInit();
// OpenPose wrapper
op::log("Configuring OpenPose...", op::Priority::High);
op::Wrapper opWrapper;
configureWrapper(opWrapper);
// Start, run, and stop processing - exec() blocks this thread until OpenPose wrapper has finished
op::log("Starting thread(s)...", op::Priority::High);
opWrapperT.exec();
opWrapper.exec();
// Measuring total time
const auto now = std::chrono::high_resolution_clock::now();
const auto totalTimeSec = double(
std::chrono::duration_cast<std::chrono::nanoseconds>(now-timerBegin).count()* 1e-9);
const auto message = "OpenPose demo successfully finished. Total time: "
+ std::to_string(totalTimeSec) + " seconds.";
op::log(message, op::Priority::High);
// Return successful message
op::printTime(opTimer, "OpenPose demo successfully finished. Total time: ", " seconds.", op::Priority::High);
// Return
return 0;
}
catch (const std::exception& e)
......
// ------------------------- OpenPose C++ API Tutorial - Example 6 - XXXXXXXXXXXXX -------------------------
// If the user wants to learn to use the OpenPose library, we highly recommend to start with the
// examples in `examples/tutorial_api_cpp/`.
// This example summarizes all the functionality of the OpenPose library:
// 1. Read folder of images / video / webcam (`producer` module)
// 2. Extract and render body keypoint / heatmap / PAF of that image (`pose` module)
// 3. Extract and render face keypoint / heatmap / PAF of that image (`face` module)
// 4. Save the results on disk (`filestream` module)
// 5. Display the rendered pose (`gui` module)
// Everything in a multi-thread scenario (`thread` module)
// Points 2 to 5 are included in the `wrapper` module
// In addition to the previous OpenPose modules, we also need to use:
// 1. `core` module:
// For the Array<float> class that the `pose` module needs
// For the Datum struct that the `thread` module sends between the queues
// 2. `utilities` module: for the error & logging functions, i.e., op::error & op::log respectively
// This file should only be used for the user to take specific examples.
// ------------------------- OpenPose C++ API Tutorial - Example 14 - Custom Post-processing -------------------------
// Synchronous mode: ideal for production integration. It provides the fastest results with respect to runtime
// performance.
// In this function, the user can implement its own post-processing, i.e., his function will be called after OpenPose
// has processed the frames but before saving or visualizing any result.
// Command-line user intraface
#include <openpose/flags.hpp>
// OpenPose dependencies
#include <openpose/headers.hpp>
// 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<std::shared_ptr<UserDatum>>> instead of Wrapper
// (or equivalently WrapperT<std::vector<std::shared_ptr<UserDatum>>>)
struct UserDatum : public op::Datum
{
bool boolThatUserNeedsForSomeReason;
UserDatum(const bool boolThatUserNeedsForSomeReason_ = false) :
boolThatUserNeedsForSomeReason{boolThatUserNeedsForSomeReason_}
{}
};
// The W-classes can be implemented either as a template or as simple classes 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 UserDatum
// This worker will just invert the image
class WUserPostProcessing : public op::Worker<std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>>
class WUserPostProcessing : public op::Worker<std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>>
{
public:
WUserPostProcessing()
......@@ -49,7 +20,7 @@ public:
void initializationOnThread() {}
void work(std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>& 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
// datumPtr->cvOutputData: rendered frame with pose or heatmaps
......@@ -68,23 +39,17 @@ public:
}
};
int tutorialApiCpp()
void configureWrapper(op::Wrapper& opWrapper)
{
try
{
op::log("Starting OpenPose demo...", op::Priority::High);
const auto timerBegin = std::chrono::high_resolution_clock::now();
// Configuring OpenPose
// logging_level
op::check(0 <= FLAGS_logging_level && FLAGS_logging_level <= 255, "Wrong logging_level value.",
__LINE__, __FUNCTION__, __FILE__);
op::ConfigureLog::setPriorityThreshold((op::Priority)FLAGS_logging_level);
op::Profiler::setDefaultX(FLAGS_profile_speed);
// // For debugging
// // Print all logging messages
// op::ConfigureLog::setPriorityThreshold(op::Priority::None);
// // Print out speed values faster
// op::Profiler::setDefaultX(100);
// Applying user defined configuration - GFlags to program variables
// producerType
......@@ -122,16 +87,12 @@ int tutorialApiCpp()
// Enabling Google Logging
const bool enableGoogleLogging = true;
// OpenPose wrapper
op::log("Configuring OpenPose...", op::Priority::High);
op::WrapperT<UserDatum> opWrapperT;
// Initializing the user custom classes
// Processing
auto wUserPostProcessing = std::make_shared<WUserPostProcessing>();
// Add custom processing
const auto workerProcessingOnNewThread = true;
opWrapperT.setWorker(op::WorkerType::PostProcessing, wUserPostProcessing, workerProcessingOnNewThread);
opWrapper.setWorker(op::WorkerType::PostProcessing, wUserPostProcessing, workerProcessingOnNewThread);
// Pose configuration (use WrapperStructPose{} for default and recommended configuration)
const op::WrapperStructPose wrapperStructPose{
......@@ -141,29 +102,29 @@ int tutorialApiCpp()
FLAGS_part_to_show, FLAGS_model_folder, heatMapTypes, heatMapScaleMode, FLAGS_part_candidates,
(float)FLAGS_render_threshold, FLAGS_number_people_max, FLAGS_maximize_positives, FLAGS_fps_max,
FLAGS_prototxt_path, FLAGS_caffemodel_path, enableGoogleLogging};
opWrapperT.configure(wrapperStructPose);
opWrapper.configure(wrapperStructPose);
// Face configuration (use op::WrapperStructFace{} to disable it)
const op::WrapperStructFace wrapperStructFace{
FLAGS_face, faceDetector, faceNetInputSize,
op::flagsToRenderMode(FLAGS_face_render, multipleView, FLAGS_render_pose),
(float)FLAGS_face_alpha_pose, (float)FLAGS_face_alpha_heatmap, (float)FLAGS_face_render_threshold};
opWrapperT.configure(wrapperStructFace);
opWrapper.configure(wrapperStructFace);
// Hand configuration (use op::WrapperStructHand{} to disable it)
const op::WrapperStructHand wrapperStructHand{
FLAGS_hand, handDetector, handNetInputSize, FLAGS_hand_scale_number, (float)FLAGS_hand_scale_range,
op::flagsToRenderMode(FLAGS_hand_render, multipleView, FLAGS_render_pose), (float)FLAGS_hand_alpha_pose,
(float)FLAGS_hand_alpha_heatmap, (float)FLAGS_hand_render_threshold};
opWrapperT.configure(wrapperStructHand);
opWrapper.configure(wrapperStructHand);
// Extra functionality configuration (use op::WrapperStructExtra{} to disable it)
const op::WrapperStructExtra wrapperStructExtra{
FLAGS_3d, FLAGS_3d_min_views, FLAGS_identification, FLAGS_tracking, FLAGS_ik_threads};
opWrapperT.configure(wrapperStructExtra);
opWrapper.configure(wrapperStructExtra);
// Producer (use default to disable any input)
const op::WrapperStructInput wrapperStructInput{
producerType, producerString, FLAGS_frame_first, FLAGS_frame_step, FLAGS_frame_last,
FLAGS_process_real_time, FLAGS_frame_flip, FLAGS_frame_rotate, FLAGS_frames_repeat,
cameraSize, FLAGS_camera_parameter_path, FLAGS_frame_undistort, FLAGS_3d_views};
opWrapperT.configure(wrapperStructInput);
opWrapper.configure(wrapperStructInput);
// Output (comment or use default argument to disable any output)
const op::WrapperStructOutput wrapperStructOutput{
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
......@@ -171,28 +132,41 @@ int tutorialApiCpp()
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
opWrapperT.configure(wrapperStructOutput);
opWrapper.configure(wrapperStructOutput);
// GUI (comment or use default argument to disable any visual output)
const op::WrapperStructGui wrapperStructGui{
op::flagsToDisplayMode(FLAGS_display, FLAGS_3d), !FLAGS_no_gui_verbose, FLAGS_fullscreen};
opWrapperT.configure(wrapperStructGui);
opWrapper.configure(wrapperStructGui);
// Set to single-thread (for sequential processing and/or debugging and/or reducing latency)
if (FLAGS_disable_multi_thread)
opWrapperT.disableMultiThreading();
opWrapper.disableMultiThreading();
}
catch (const std::exception& e)
{
op::error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
int tutorialApiCpp()
{
try
{
op::log("Starting OpenPose demo...", op::Priority::High);
const auto opTimer = op::getTimerInit();
// OpenPose wrapper
op::log("Configuring OpenPose...", op::Priority::High);
op::Wrapper opWrapper;
configureWrapper(opWrapper);
// Start, run, and stop processing - exec() blocks this thread until OpenPose wrapper has finished
op::log("Starting thread(s)...", op::Priority::High);
opWrapperT.exec();
opWrapper.exec();
// Measuring total time
const auto now = std::chrono::high_resolution_clock::now();
const auto totalTimeSec = double(
std::chrono::duration_cast<std::chrono::nanoseconds>(now-timerBegin).count()* 1e-9);
const auto message = "OpenPose demo successfully finished. Total time: "
+ std::to_string(totalTimeSec) + " seconds.";
op::log(message, op::Priority::High);
// Return successful message
op::printTime(opTimer, "OpenPose demo successfully finished. Total time: ", " seconds.", op::Priority::High);
// Return
return 0;
}
catch (const std::exception& e)
......
// ------------------------- OpenPose C++ API Tutorial - Example 8 - XXXXXXXXXXXXX -------------------------
// If the user wants to learn to use the OpenPose library, we highly recommend to start with the
// examples in `examples/tutorial_api_cpp/`.
// This example summarizes all the functionality of the OpenPose library:
// 1. Read folder of images / video / webcam (`producer` module)
// 2. Extract and render body keypoint / heatmap / PAF of that image (`pose` module)
// 3. Extract and render face keypoint / heatmap / PAF of that image (`face` module)
// 4. Save the results on disk (`filestream` module)
// 5. Display the rendered pose (`gui` module)
// Everything in a multi-thread scenario (`thread` module)
// Points 2 to 5 are included in the `wrapper` module
// In addition to the previous OpenPose modules, we also need to use:
// 1. `core` module:
// For the Array<float> class that the `pose` module needs
// For the Datum struct that the `thread` module sends between the queues
// 2. `utilities` module: for the error & logging functions, i.e., op::error & op::log respectively
// This file should only be used for the user to take specific examples.
// ------------------------- OpenPose C++ API Tutorial - Example 15 - Custom Output -------------------------
// Synchronous mode: ideal for production integration. It provides the fastest results with respect to runtime
// performance.
// In this function, the user can implement its own way to render/display/storage the results.
// Command-line user intraface
#define OPENPOSE_FLAGS_DISABLE_DISPLAY
......@@ -27,30 +14,13 @@
DEFINE_bool(no_display, false,
"Enable to disable the visual display.");
// 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<std::shared_ptr<UserDatum>>> instead of Wrapper
// (or equivalently WrapperT<std::vector<std::shared_ptr<UserDatum>>>)
struct UserDatum : public op::Datum
{
bool boolThatUserNeedsForSomeReason;
UserDatum(const bool boolThatUserNeedsForSomeReason_ = false) :
boolThatUserNeedsForSomeReason{boolThatUserNeedsForSomeReason_}
{}
};
// The W-classes can be implemented either as a template or as simple classes 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 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<std::shared_ptr<UserDatum>>>>
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<std::shared_ptr<UserDatum>>>& datumsPtr)
void workConsumer(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& datumsPtr)
{
try
{
......@@ -109,7 +79,7 @@ public:
if (!FLAGS_no_display)
{
// Display rendered output image
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", 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)
......@@ -125,23 +95,17 @@ public:
}
};
int tutorialApiCpp()
void configureWrapper(op::Wrapper& opWrapper)
{
try
{
op::log("Starting OpenPose demo...", op::Priority::High);
const auto timerBegin = std::chrono::high_resolution_clock::now();
// Configuring OpenPose
// logging_level
op::check(0 <= FLAGS_logging_level && FLAGS_logging_level <= 255, "Wrong logging_level value.",
__LINE__, __FUNCTION__, __FILE__);
op::ConfigureLog::setPriorityThreshold((op::Priority)FLAGS_logging_level);
op::Profiler::setDefaultX(FLAGS_profile_speed);
// // For debugging
// // Print all logging messages
// op::ConfigureLog::setPriorityThreshold(op::Priority::None);
// // Print out speed values faster
// op::Profiler::setDefaultX(100);
// Applying user defined configuration - GFlags to program variables
// producerType
......@@ -179,16 +143,12 @@ int tutorialApiCpp()
// Enabling Google Logging
const bool enableGoogleLogging = true;
// OpenPose wrapper
op::log("Configuring OpenPose...", op::Priority::High);
op::WrapperT<UserDatum> opWrapperT;
// Initializing the user custom classes
// GUI (Display)
auto wUserOutput = std::make_shared<WUserOutput>();
// Add custom processing
const auto workerOutputOnNewThread = true;
opWrapperT.setWorker(op::WorkerType::Output, wUserOutput, workerOutputOnNewThread);
opWrapper.setWorker(op::WorkerType::Output, wUserOutput, workerOutputOnNewThread);
// Pose configuration (use WrapperStructPose{} for default and recommended configuration)
const op::WrapperStructPose wrapperStructPose{
......@@ -198,29 +158,29 @@ int tutorialApiCpp()
FLAGS_part_to_show, FLAGS_model_folder, heatMapTypes, heatMapScaleMode, FLAGS_part_candidates,
(float)FLAGS_render_threshold, FLAGS_number_people_max, FLAGS_maximize_positives, FLAGS_fps_max,
FLAGS_prototxt_path, FLAGS_caffemodel_path, enableGoogleLogging};
opWrapperT.configure(wrapperStructPose);
opWrapper.configure(wrapperStructPose);
// Face configuration (use op::WrapperStructFace{} to disable it)
const op::WrapperStructFace wrapperStructFace{
FLAGS_face, faceDetector, faceNetInputSize,
op::flagsToRenderMode(FLAGS_face_render, multipleView, FLAGS_render_pose),
(float)FLAGS_face_alpha_pose, (float)FLAGS_face_alpha_heatmap, (float)FLAGS_face_render_threshold};
opWrapperT.configure(wrapperStructFace);
opWrapper.configure(wrapperStructFace);
// Hand configuration (use op::WrapperStructHand{} to disable it)
const op::WrapperStructHand wrapperStructHand{
FLAGS_hand, handDetector, handNetInputSize, FLAGS_hand_scale_number, (float)FLAGS_hand_scale_range,
op::flagsToRenderMode(FLAGS_hand_render, multipleView, FLAGS_render_pose), (float)FLAGS_hand_alpha_pose,
(float)FLAGS_hand_alpha_heatmap, (float)FLAGS_hand_render_threshold};
opWrapperT.configure(wrapperStructHand);
opWrapper.configure(wrapperStructHand);
// Extra functionality configuration (use op::WrapperStructExtra{} to disable it)
const op::WrapperStructExtra wrapperStructExtra{
FLAGS_3d, FLAGS_3d_min_views, FLAGS_identification, FLAGS_tracking, FLAGS_ik_threads};
opWrapperT.configure(wrapperStructExtra);
opWrapper.configure(wrapperStructExtra);
// Producer (use default to disable any input)
const op::WrapperStructInput wrapperStructInput{
producerType, producerString, FLAGS_frame_first, FLAGS_frame_step, FLAGS_frame_last,
FLAGS_process_real_time, FLAGS_frame_flip, FLAGS_frame_rotate, FLAGS_frames_repeat,
cameraSize, FLAGS_camera_parameter_path, FLAGS_frame_undistort, FLAGS_3d_views};
opWrapperT.configure(wrapperStructInput);
opWrapper.configure(wrapperStructInput);
// Output (comment or use default argument to disable any output)
const op::WrapperStructOutput wrapperStructOutput{
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
......@@ -228,25 +188,38 @@ int tutorialApiCpp()
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
opWrapperT.configure(wrapperStructOutput);
opWrapper.configure(wrapperStructOutput);
// No GUI. Equivalent to: opWrapper.configure(op::WrapperStructGui{});
// Set to single-thread (for sequential processing and/or debugging and/or reducing latency)
if (FLAGS_disable_multi_thread)
opWrapperT.disableMultiThreading();
opWrapper.disableMultiThreading();
}
catch (const std::exception& e)
{
op::error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
int tutorialApiCpp()
{
try
{
op::log("Starting OpenPose demo...", op::Priority::High);
const auto opTimer = op::getTimerInit();
// OpenPose wrapper
op::log("Configuring OpenPose...", op::Priority::High);
op::Wrapper opWrapper;
configureWrapper(opWrapper);
// Start, run, and stop processing - exec() blocks this thread until OpenPose wrapper has finished
op::log("Starting thread(s)...", op::Priority::High);
opWrapperT.exec();
opWrapper.exec();
// Measuring total time
const auto now = std::chrono::high_resolution_clock::now();
const auto totalTimeSec = double(
std::chrono::duration_cast<std::chrono::nanoseconds>(now-timerBegin).count()* 1e-9);
const auto message = "OpenPose demo successfully finished. Total time: "
+ std::to_string(totalTimeSec) + " seconds.";
op::log(message, op::Priority::High);
op::printTime(opTimer, "OpenPose demo successfully finished. Total time: ", " seconds.", op::Priority::High);
// Return successful message
// Return
return 0;
}
catch (const std::exception& e)
......
// ------------------------- OpenPose C++ API Tutorial - Example 9 - XXXXXXXXXXXXX -------------------------
// Synchronous mode: ideal for performance. The user can add his own frames producer / post-processor / consumer to the OpenPose wrapper or use the
// default ones.
// This example shows the user how to use the OpenPose wrapper class:
// 1. User reads images
// 2. Extract and render keypoint / heatmap / PAF of that image
// 3. Save the results on disk
// 4. User displays the rendered pose
// Everything in a multi-thread scenario
// In addition to the previous OpenPose modules, we also need to use:
// 1. `core` module:
// For the Array<float> class that the `pose` module needs
// For the Datum struct that the `thread` module sends between the queues
// 2. `utilities` module: for the error & logging functions, i.e., op::error & op::log respectively
// This file should only be used for the user to take specific examples.
// --- OpenPose C++ API Tutorial - Example 16 - Custom Input, Pre-processing, Post-processing, Output, and Datum ---
// Synchronous mode: ideal for production integration. It provides the fastest results with respect to runtime
// performance.
// In this function, the user can implement its own way to read frames, implement its own post-processing (i.e., his
// function will be called after OpenPose has processed the frames but before saving), visualizing any result
// render/display/storage the results, and use their custom Datum structure
// Command-line user intraface
#define OPENPOSE_FLAGS_DISABLE_PRODUCER
......@@ -24,7 +14,7 @@
// Custom OpenPose flags
// Producer
DEFINE_string(image_dir, "examples/media/",
DEFINE_string(image_dir, "examples/media/",
"Process a directory of images. Read all standard formats (jpg, png, bmp, etc.).");
// Display
DEFINE_bool(no_display, false,
......@@ -43,10 +33,6 @@ struct UserDatum : public op::Datum
{}
};
// The W-classes can be implemented either as a template or as simple classes 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 UserDatum
// This worker will just read and return all the basic image file formats in a directory
class WUserInput : public op::WorkerProducer<std::shared_ptr<std::vector<std::shared_ptr<UserDatum>>>>
{
......@@ -208,7 +194,7 @@ public:
if (!FLAGS_no_display)
{
// Display rendered output image
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", 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)
......@@ -224,12 +210,11 @@ public:
}
};
int tutorialApiCpp()
void configureWrapper(op::WrapperT<UserDatum>& opWrapperT)
{
try
{
op::log("Starting OpenPose demo...", op::Priority::High);
const auto timerBegin = std::chrono::high_resolution_clock::now();
// Configuring OpenPose
// logging_level
op::check(0 <= FLAGS_logging_level && FLAGS_logging_level <= 255, "Wrong logging_level value.",
......@@ -274,9 +259,6 @@ int tutorialApiCpp()
// GUI (Display)
auto wUserOutput = std::make_shared<WUserOutput>();
// OpenPose wrapper
op::log("Configuring OpenPose...", op::Priority::High);
op::WrapperT<UserDatum> opWrapperT;
// Add custom input
const auto workerInputOnNewThread = false;
opWrapperT.setWorker(op::WorkerType::Input, wUserInput, workerInputOnNewThread);
......@@ -324,20 +306,33 @@ int tutorialApiCpp()
// Set to single-thread (for sequential processing and/or debugging and/or reducing latency)
if (FLAGS_disable_multi_thread)
opWrapperT.disableMultiThreading();
}
catch (const std::exception& e)
{
op::error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
int tutorialApiCpp()
{
try
{
op::log("Starting OpenPose demo...", op::Priority::High);
const auto opTimer = op::getTimerInit();
// OpenPose wrapper
op::log("Configuring OpenPose...", op::Priority::High);
op::WrapperT<UserDatum> opWrapperT;
configureWrapper(opWrapperT);
// Start, run, and stop processing - exec() blocks this thread until OpenPose wrapper has finished
op::log("Starting thread(s)...", op::Priority::High);
opWrapperT.exec();
// Measuring total time
const auto now = std::chrono::high_resolution_clock::now();
const auto totalTimeSec = double(
std::chrono::duration_cast<std::chrono::nanoseconds>(now-timerBegin).count()* 1e-9);
const auto message = "OpenPose demo successfully finished. Total time: "
+ std::to_string(totalTimeSec) + " seconds.";
op::log(message, op::Priority::High);
op::printTime(opTimer, "OpenPose demo successfully finished. Total time: ", " seconds.", op::Priority::High);
// Return successful message
// Return
return 0;
}
catch (const std::exception& e)
......
......@@ -4,15 +4,17 @@ set(EXAMPLE_FILES
03_keypoints_from_image.cpp
04_keypoints_from_images.cpp
05_keypoints_from_images_multi_gpu.cpp
06_asynchronous_custom_input.cpp
07_asynchronous_custom_output.cpp
08_asynchronous_custom_input_output_and_datum.cpp
09_face_from_image.cpp
10_hand_from_image.cpp
11_synchronous_custom_input.cpp
13_synchronous_custom_postprocessing.cpp
14_synchronous_custom_output.cpp
15_synchronous_custom_all.cpp)
06_face_from_image.cpp
07_hand_from_image.cpp
# 08_heatmaps_from_image.cpp
09_asynchronous_custom_input.cpp
10_asynchronous_custom_output.cpp
11_asynchronous_custom_input_output_and_datum.cpp
12_synchronous_custom_input.cpp
# 13_synchronous_custom_preprocessing.cpp
14_synchronous_custom_postprocessing.cpp
15_synchronous_custom_output.cpp
16_synchronous_custom_all_and_datum.cpp)
include(${CMAKE_SOURCE_DIR}/cmake/Utils.cmake)
......
......@@ -159,7 +159,7 @@ public:
// datumPtr->poseKeypoints: Array<float> with the estimated pose
if (datumsPtr != nullptr && !datumsPtr->empty())
{
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial Thread API", 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);
}
......
......@@ -21,10 +21,19 @@ namespace op
virtual ~ThreadManager();
/**
* It sets the maximum number of elements in the queue.
* For maximum speed, set to a very large number, but the trade-off would be:
* - Latency will hugely increase.
* - The program might go out of RAM memory (so the computer might freeze).
* For minimum latency while keeping an optimal speed, set to -1, that will automatically
* detect the ideal number based on how many elements are connected to that queue.
* @param defaultMaxSizeQueues long long element with the maximum number of elements on the queue.
*/
void setDefaultMaxSizeQueues(const long long defaultMaxSizeQueues = -1);
void add(const unsigned long long threadId, const std::vector<TWorker>& tWorkers, const unsigned long long queueInId,
const unsigned long long queueOutId);
void add(const unsigned long long threadId, const std::vector<TWorker>& tWorkers,
const unsigned long long queueInId, const unsigned long long queueOutId);
void add(const unsigned long long threadId, const TWorker& tWorker, const unsigned long long queueInId,
const unsigned long long queueOutId);
......
......@@ -133,6 +133,17 @@ namespace op
*/
bool isRunning() const;
/**
* It sets the maximum number of elements in the queue.
* For maximum speed, set to a very large number, but the trade-off would be:
* - Latency will hugely increase.
* - The program might go out of RAM memory (so the computer might freeze).
* For minimum latency while keeping an optimal speed, set to -1, that will automatically
* detect the ideal number based on how many elements are connected to that queue.
* @param defaultMaxSizeQueues long long element with the maximum number of elements on the queue.
*/
void setDefaultMaxSizeQueues(const long long defaultMaxSizeQueues = -1);
/**
* Emplace (move) an element on the first (input) queue.
* Only valid if ThreadManagerMode::Asynchronous or ThreadManagerMode::AsynchronousIn.
......@@ -459,6 +470,19 @@ namespace op
}
}
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
void WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::setDefaultMaxSizeQueues(const long long defaultMaxSizeQueues)
{
try
{
mThreadManager.setDefaultMaxSizeQueues(defaultMaxSizeQueues);
}
catch (const std::exception& e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
template<typename TDatum, typename TDatums, typename TDatumsSP, typename TWorker>
bool WrapperT<TDatum, TDatums, TDatumsSP, TWorker>::tryEmplace(TDatumsSP& tDatums)
{
......
......@@ -11,11 +11,11 @@ if [[ $RUN_EXAMPLES == true ]] ; then
echo " "
echo "OpenPose demo..."
./build/examples/openpose/openpose.bin --net_resolution -1x32 --image_dir examples/media/ --write_json output/ --write_images output/ --display 0 --render_pose 1
./build/examples/openpose/openpose.bin --image_dir examples/media/ --net_resolution -1x32 --write_json output/ --write_images output/ --display 0
echo " "
echo "Tutorial Add Module: Example 1..."
./build/examples/tutorial_add_module/1_custom_post_processing.bin --net_resolution -1x32 --image_dir examples/media/ --write_json output/ --write_images output/ --display 0 --render_pose 1
./build/examples/tutorial_add_module/1_custom_post_processing.bin --image_dir examples/media/ --net_resolution -1x32 --write_json output/ --write_images output/ --display 0
echo " "
# # Note: Examples 1-2 require the whole OpenPose resolution (too much RAM memory) and the GUI
......@@ -25,58 +25,67 @@ if [[ $RUN_EXAMPLES == true ]] ; then
# echo " "
echo "Tutorial API C++: Example 3..."
./build/examples/tutorial_api_cpp/03_keypoints_from_image.bin --no_display --net_resolution -1x32 --write_json output/
./build/examples/tutorial_api_cpp/03_keypoints_from_image.bin --net_resolution -1x32 --write_json output/ --write_images output/ --no_display
echo " "
echo "Tutorial API C++: Example 4..."
./build/examples/tutorial_api_cpp/04_keypoints_from_images.bin --no_display --net_resolution -1x32 --write_json output/
./build/examples/tutorial_api_cpp/04_keypoints_from_images.bin --net_resolution -1x32 --write_json output/ --write_images output/ --no_display
echo " "
echo "Tutorial API C++: Example 5..."
./build/examples/tutorial_api_cpp/05_keypoints_from_images_multi_gpu.bin --no_display --net_resolution -1x32 --write_json output/
./build/examples/tutorial_api_cpp/05_keypoints_from_images_multi_gpu.bin --net_resolution -1x32 --write_json output/ --write_images output/ --no_display
./build/examples/tutorial_api_cpp/05_keypoints_from_images_multi_gpu.bin --net_resolution -1x32 --write_json output/ --write_images output/ --no_display --latency_is_irrelevant_and_computer_with_lots_of_ram
echo " "
echo "Tutorial API C++: Example 6..."
./build/examples/tutorial_api_cpp/06_asynchronous_custom_input.bin --net_resolution -1x32 --image_dir examples/media/ --write_json output/ --write_images output/ --display 0 --render_pose 1
./build/examples/tutorial_api_cpp/06_face_from_image.bin --face_net_resolution 32x32 --write_json output/ --write_images output/ --no_display
echo " "
echo "Tutorial API C++: Example 7..."
./build/examples/tutorial_api_cpp/07_asynchronous_custom_output.bin --no_display --net_resolution -1x32 --image_dir examples/media/
./build/examples/tutorial_api_cpp/07_hand_from_image.bin --hand_net_resolution 32x32 --write_json output/ --write_images output/ --no_display
echo " "
echo "Tutorial API C++: Example 8..."
./build/examples/tutorial_api_cpp/08_asynchronous_custom_input_output_and_datum.bin --no_display --net_resolution -1x32 --image_dir examples/media/
echo " "
# echo "Tutorial API C++: Example 8..."
# ./build/examples/tutorial_api_cpp/08_heatmaps_from_image.bin --hand_net_resolution 32x32 --write_json output/ --write_images output/ --no_display
# echo " "
echo "Tutorial API C++: Example 9..."
./build/examples/tutorial_api_cpp/09_face_from_image.bin --no_display --face_net_resolution 32x32
./build/examples/tutorial_api_cpp/09_asynchronous_custom_input.bin --image_dir examples/media/ --net_resolution -1x32 --write_json output/ --write_images output/ --display 0
echo " "
echo "Tutorial API C++: Example 10..."
./build/examples/tutorial_api_cpp/10_hand_from_image.bin --no_display --hand_net_resolution 32x32
./build/examples/tutorial_api_cpp/10_asynchronous_custom_output.bin --image_dir examples/media/ --net_resolution -1x32 --write_json output/ --write_images output/ --no_display
echo " "
echo "Tutorial API C++: Example 11..."
./build/examples/tutorial_api_cpp/11_synchronous_custom_input.bin --net_resolution -1x32 --image_dir examples/media/ --write_json output/ --write_images output/ --display 0 --render_pose 1
./build/examples/tutorial_api_cpp/11_asynchronous_custom_input_output_and_datum.bin --image_dir examples/media/ --net_resolution -1x32 --write_json output/ --write_images output/ --no_display
echo " "
echo "Tutorial API C++: Example 13..."
./build/examples/tutorial_api_cpp/13_synchronous_custom_postprocessing.bin --net_resolution -1x32 --image_dir examples/media/ --write_json output/ --write_images output/ --display 0 --render_pose 1
echo "Tutorial API C++: Example 12..."
./build/examples/tutorial_api_cpp/12_synchronous_custom_input.bin --image_dir examples/media/ --net_resolution -1x32 --write_json output/ --write_images output/ --display 0
echo " "
# echo "Tutorial API C++: Example 13..."
# ./build/examples/tutorial_api_cpp/13_synchronous_custom_preprocessing.bin --image_dir examples/media/ --net_resolution -1x32 --write_json output/ --write_images output/ --display 0
# echo " "
echo "Tutorial API C++: Example 14..."
./build/examples/tutorial_api_cpp/14_synchronous_custom_output.bin --no_display --net_resolution -1x32 --image_dir examples/media/
./build/examples/tutorial_api_cpp/14_synchronous_custom_postprocessing.bin --image_dir examples/media/ --net_resolution -1x32 --write_json output/ --write_images output/ --display 0
echo " "
echo "Tutorial API C++: Example 15..."
./build/examples/tutorial_api_cpp/15_synchronous_custom_all.bin --no_display --net_resolution -1x32 --image_dir examples/media/
./build/examples/tutorial_api_cpp/15_synchronous_custom_output.bin --image_dir examples/media/ --net_resolution -1x32 --write_json output/ --write_images output/ --no_display
echo " "
echo "Tutorial API C++: Example 16..."
./build/examples/tutorial_api_cpp/16_synchronous_custom_all_and_datum.bin --image_dir examples/media/ --net_resolution -1x32 --write_json output/ --write_images output/ --no_display
echo " "
# Python examples
if [[ $WITH_PYTHON == true ]] ; then
echo "Tutorial API Python: OpenPose demo..."
cd build/examples/tutorial_api_python
python openpose_python.py --net_resolution -1x32 --image_dir ../../../examples/media/ --write_json output/ --write_images output/ --display 0 --render_pose 1
python openpose_python.py --image_dir ../../../examples/media/ --net_resolution -1x32 --write_json output/ --write_images output/ --display 0
echo " "
# Note: All Python examples require GUI
fi
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册