Skip to content

Commit efdf39d

Browse files
Queue size configurable through wrapper and cleaned examples
1 parent 5f768fe commit efdf39d

19 files changed

+308
-300
lines changed

examples/tutorial_api_cpp/01_body_from_image_default.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ void display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& dat
2626
if (datumsPtr != nullptr && !datumsPtr->empty())
2727
{
2828
// Display image
29-
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
29+
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
3030
cv::waitKey(0);
3131
}
3232
else

examples/tutorial_api_cpp/02_whole_body_from_image_default.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ void display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& dat
2626
if (datumsPtr != nullptr && !datumsPtr->empty())
2727
{
2828
// Display image
29-
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
29+
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
3030
cv::waitKey(0);
3131
}
3232
else

examples/tutorial_api_cpp/03_keypoints_from_image.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ void display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& dat
2828
if (datumsPtr != nullptr && !datumsPtr->empty())
2929
{
3030
// Display image
31-
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
31+
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
3232
cv::waitKey(0);
3333
}
3434
else

examples/tutorial_api_cpp/04_keypoints_from_images.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
// Custom OpenPose flags
1313
// Producer
14-
DEFINE_string(image_dir, "examples/media/",
14+
DEFINE_string(image_dir, "examples/media/",
1515
"Process a directory of images. Read all standard formats (jpg, png, bmp, etc.).");
1616
// Display
1717
DEFINE_bool(no_display, false,
@@ -29,7 +29,7 @@ bool display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& dat
2929
if (datumsPtr != nullptr && !datumsPtr->empty())
3030
{
3131
// Display image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
32-
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
32+
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
3333
key = (char)cv::waitKey(1);
3434
}
3535
else

examples/tutorial_api_cpp/05_keypoints_from_images_multi_gpu.cpp

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,14 @@
1111

1212
// Custom OpenPose flags
1313
// Producer
14-
DEFINE_string(image_dir, "examples/media/",
14+
DEFINE_string(image_dir, "examples/media/",
1515
"Process a directory of images. Read all standard formats (jpg, png, bmp, etc.).");
16+
// OpenPose
17+
DEFINE_bool(latency_is_irrelevant_and_computer_with_lots_of_ram, false,
18+
"If false, it will read and then then process images right away. If true, it will first store all the frames and"
19+
" later process them (slightly faster). However: 1) Latency will hugely increase (no frames will be processed"
20+
" until they have all been read). And 2) The program might go out of RAM memory with long videos or folders with"
21+
" many images (so the computer might freeze).");
1622
// Display
1723
DEFINE_bool(no_display, false,
1824
"Enable to disable the visual display.");
@@ -29,7 +35,7 @@ bool display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& dat
2935
if (datumsPtr != nullptr && !datumsPtr->empty())
3036
{
3137
// Display image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
32-
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
38+
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
3339
key = (char)cv::waitKey(1);
3440
}
3541
else
@@ -160,6 +166,9 @@ int tutorialApiCpp()
160166
op::log("Configuring OpenPose...", op::Priority::High);
161167
op::Wrapper opWrapper{op::ThreadManagerMode::Asynchronous};
162168
configureWrapper(opWrapper);
169+
// Increase maximum wrapper queue size
170+
if (FLAGS_latency_is_irrelevant_and_computer_with_lots_of_ram)
171+
opWrapper.setDefaultMaxSizeQueues(std::numeric_limits<long long>::max());
163172

164173
// Starting OpenPose
165174
op::log("Starting thread(s)...", op::Priority::High);
@@ -177,12 +186,63 @@ int tutorialApiCpp()
177186
// 1. One pushing images to OpenPose all the time.
178187
// 2. A second one retrieving those frames.
179188
// Option b) Much easier and faster to implement but slightly slower runtime performance
180-
for (auto imageId = 0u ; imageId < imagePaths.size() ; imageId+=numberGPUs)
189+
if (!FLAGS_latency_is_irrelevant_and_computer_with_lots_of_ram)
181190
{
182-
// Read and push images into OpenPose wrapper
183-
for (auto gpuId = 0 ; gpuId < numberGPUs ; gpuId++)
191+
for (auto imageBaseId = 0u ; imageBaseId < imagePaths.size() ; imageBaseId+=numberGPUs)
192+
{
193+
// Read and push images into OpenPose wrapper
194+
for (auto gpuId = 0 ; gpuId < numberGPUs ; gpuId++)
195+
{
196+
const auto imageId = imageBaseId+gpuId;
197+
if (imageId < imagePaths.size())
198+
{
199+
const auto& imagePath = imagePaths.at(imageId);
200+
// Faster alternative that moves imageToProcess
201+
auto imageToProcess = cv::imread(imagePath);
202+
opWrapper.waitAndEmplace(imageToProcess);
203+
// // Slower but safer alternative that copies imageToProcess
204+
// const auto imageToProcess = cv::imread(imagePath);
205+
// opWrapper.waitAndPush(imageToProcess);
206+
}
207+
}
208+
// Retrieve processed results from OpenPose wrapper
209+
for (auto gpuId = 0 ; gpuId < numberGPUs ; gpuId++)
210+
{
211+
const auto imageId = imageBaseId+gpuId;
212+
if (imageId < imagePaths.size())
213+
{
214+
std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>> datumProcessed;
215+
const auto status = opWrapper.waitAndPop(datumProcessed);
216+
if (status && datumProcessed != nullptr)
217+
{
218+
printKeypoints(datumProcessed);
219+
if (!FLAGS_no_display)
220+
{
221+
const auto userWantsToExit = display(datumProcessed);
222+
if (userWantsToExit)
223+
{
224+
op::log("User pressed Esc to exit demo.", op::Priority::High);
225+
break;
226+
}
227+
}
228+
}
229+
else
230+
op::log("Image could not be processed.", op::Priority::High);
231+
}
232+
}
233+
}
234+
}
235+
// Option c) Even easier and faster to implement than option b. In addition, its runtime performance should
236+
// be slightly faster too, but:
237+
// - Latency will hugely increase (no frames will be processed until they have all been read).
238+
// - The program might go out of RAM memory with long videos or folders with many images (so the computer
239+
// might freeze).
240+
else
241+
{
242+
// Read and push all images into OpenPose wrapper
243+
op::log("Loading images into OpenPose wrapper...", op::Priority::High);
244+
for (const auto& imagePath : imagePaths)
184245
{
185-
const auto& imagePath = imagePaths.at(imageId+gpuId);
186246
// Faster alternative that moves imageToProcess
187247
auto imageToProcess = cv::imread(imagePath);
188248
opWrapper.waitAndEmplace(imageToProcess);
@@ -191,7 +251,8 @@ int tutorialApiCpp()
191251
// opWrapper.waitAndPush(imageToProcess);
192252
}
193253
// Retrieve processed results from OpenPose wrapper
194-
for (auto gpuId = 0 ; gpuId < numberGPUs ; gpuId++)
254+
op::log("Retrieving results from OpenPose wrapper...", op::Priority::High);
255+
for (auto imageId = 0u ; imageId < imagePaths.size() ; imageId++)
195256
{
196257
std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>> datumProcessed;
197258
const auto status = opWrapper.waitAndPop(datumProcessed);

examples/tutorial_api_cpp/09_face_from_image.cpp renamed to examples/tutorial_api_cpp/06_face_from_image.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// ----------------------------- OpenPose C++ API Tutorial - Example 9 - Face from Image -----------------------------
1+
// ----------------------------- OpenPose C++ API Tutorial - Example 6 - Face from Image -----------------------------
22
// It reads an image and the face location, process it, and displays the face keypoints. In addition,
33
// it includes all the OpenPose configuration flags.
44
// 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
3131
if (datumsPtr != nullptr && !datumsPtr->empty())
3232
{
3333
// Display image
34-
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
34+
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
3535
cv::waitKey(0);
3636
}
3737
else

examples/tutorial_api_cpp/10_hand_from_image.cpp renamed to examples/tutorial_api_cpp/07_hand_from_image.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// ----------------------------- OpenPose C++ API Tutorial - Example 9 - Face from Image -----------------------------
1+
// ----------------------------- OpenPose C++ API Tutorial - Example 7 - Face from Image -----------------------------
22
// It reads an image and the hand location, process it, and displays the hand keypoints. In addition,
33
// it includes all the OpenPose configuration flags.
44
// 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
3131
if (datumsPtr != nullptr && !datumsPtr->empty())
3232
{
3333
// Display image
34-
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
34+
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
3535
cv::waitKey(0);
3636
}
3737
else

examples/tutorial_api_cpp/06_asynchronous_custom_input.cpp renamed to examples/tutorial_api_cpp/09_asynchronous_custom_input.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// ------------------------- OpenPose C++ API Tutorial - Example 6 - Custom Input -------------------------
1+
// ------------------------- OpenPose C++ API Tutorial - Example 9 - Custom Input -------------------------
22
// Asynchronous mode: ideal for fast prototyping when performance is not an issue.
33
// In this function, the user can implement its own way to create frames (e.g., reading his own folder of images)
44
// and emplaces/pushes the frames to OpenPose.
@@ -11,13 +11,9 @@
1111

1212
// Custom OpenPose flags
1313
// Producer
14-
DEFINE_string(image_dir, "examples/media/",
14+
DEFINE_string(image_dir, "examples/media/",
1515
"Process a directory of images. Read all standard formats (jpg, png, bmp, etc.).");
1616

17-
// The W-classes can be implemented either as a template or as simple classes given
18-
// that the user usually knows which kind of data he will move between the queues,
19-
// in this case we assume a std::shared_ptr of a std::vector of op::Datum
20-
2117
// This worker will just read and return all the basic image file formats in a directory
2218
class UserInputClass
2319
{

examples/tutorial_api_cpp/07_asynchronous_custom_output.cpp renamed to examples/tutorial_api_cpp/10_asynchronous_custom_output.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// ------------------------- OpenPose C++ API Tutorial - Example 7 - Custom Output -------------------------
1+
// ------------------------- OpenPose C++ API Tutorial - Example 10 - Custom Output -------------------------
22
// Asynchronous mode: ideal for fast prototyping when performance is not an issue.
3-
// In this function, the user can implement its own way to render/display the frames.
3+
// In this function, the user can implement its own way to render/display/storage the results.
44

55
// Command-line user intraface
66
#define OPENPOSE_FLAGS_DISABLE_DISPLAY
@@ -13,10 +13,6 @@
1313
DEFINE_bool(no_display, false,
1414
"Enable to disable the visual display.");
1515

16-
// The W-classes can be implemented either as a template or as simple classes given
17-
// that the user usually knows which kind of data he will move between the queues,
18-
// in this case we assume a std::shared_ptr of a std::vector of op::Datum
19-
2016
// This worker will just read and return all the jpg files in a directory
2117
class UserOutputClass
2218
{
@@ -29,7 +25,7 @@ class UserOutputClass
2925
char key = ' ';
3026
if (datumsPtr != nullptr && !datumsPtr->empty())
3127
{
32-
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
28+
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
3329
// Display image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
3430
key = (char)cv::waitKey(1);
3531
}

examples/tutorial_api_cpp/08_asynchronous_custom_input_output_and_datum.cpp renamed to examples/tutorial_api_cpp/11_asynchronous_custom_input_output_and_datum.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// ------------------------- OpenPose C++ API Tutorial - Example 8 - Custom Input and Output -------------------------
1+
// --------------------- OpenPose C++ API Tutorial - Example 11 - Custom Input, Output, and Datum ---------------------
22
// Asynchronous mode: ideal for fast prototyping when performance is not an issue.
33
// In this function, the user can implement its own way to create frames (e.g., reading his own folder of images)
44
// and its own way to render/display them after being processed by OpenPose.
@@ -12,7 +12,7 @@
1212

1313
// Custom OpenPose flags
1414
// Producer
15-
DEFINE_string(image_dir, "examples/media/",
15+
DEFINE_string(image_dir, "examples/media/",
1616
"Process a directory of images. Read all standard formats (jpg, png, bmp, etc.).");
1717
// Display
1818
DEFINE_bool(no_display, false,
@@ -31,10 +31,6 @@ struct UserDatum : public op::Datum
3131
{}
3232
};
3333

34-
// The W-classes can be implemented either as a template or as simple classes given
35-
// that the user usually knows which kind of data he will move between the queues,
36-
// in this case we assume a std::shared_ptr of a std::vector of UserDatum
37-
3834
// This worker will just read and return all the basic image file formats in a directory
3935
class UserInputClass
4036
{
@@ -111,7 +107,7 @@ class UserOutputClass
111107
if (datumsPtr != nullptr && !datumsPtr->empty())
112108
{
113109
// Display image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
114-
cv::imshow("User worker GUI", datumsPtr->at(0)->cvOutputData);
110+
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
115111
key = (char)cv::waitKey(1);
116112
}
117113
else

0 commit comments

Comments
 (0)