Skip to content

Commit 084d169

Browse files
Added and cleaned some examples
1 parent efdf39d commit 084d169

15 files changed

+323
-73
lines changed

doc/modules/python_module.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ To compile, enable `BUILD_PYTHON` in cmake. Pybind selects the latest version of
2525
## Installation
2626
Check [doc/installation.md#python-module](../installation.md#python-api) for installation steps.
2727

28-
The Python API requires Numpy for array management, and OpenCV for image loading. They can be installed via:
28+
The Python API requires python-dev, Numpy (for array management), and OpenCV (for image loading). They can be installed via:
2929

3030
```
3131
# Python 2
32+
sudo apt-get install python-dev
3233
sudo pip install numpy opencv-python
3334
# Python 3 (recommended)
35+
sudo apt-get install python3-dev
3436
sudo pip3 install numpy opencv-python
3537
```
3638

doc/release_notes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ OpenPose Library - Release Notes
314314
31. Replaced the old Python wrapper for an updated Pybind11 wrapper version, that includes all the functionality of the C++ API.
315315
32. Function getFilesOnDirectory() can extra all basic image file types at once without requiring to manually enumerate them.
316316
33. Added the flags `--face_detector` and `--hand_detector`, that enable the user to select the face/hand rectangle detector that is used for the later face/hand keypoint detection. It includes OpenCV (for face), and also allows the user to provide its own input. Flag `--hand_tracking` is removed and integrated into this flag too.
317+
34. Maximum queue size per OpenPose thread is configurable through the Wrapper class.
317318
2. Functions or parameters renamed:
318319
1. By default, python example `tutorial_developer/python_2_pose_from_heatmaps.py` was using 2 scales starting at -1x736, changed to 1 scale at -1x368.
319320
2. WrapperStructPose default parameters changed to match those of the OpenPose demo binary.

doc/standalone_face_or_hand_keypoint_detector.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ Note that this method will be faster than the current system if there is few peo
1010
```
1111

1212
## Custom Standalone Face or Hand Keypoint Detector
13-
Check the examples in `examples/tutorial_api_cpp/`, in particular [examples/tutorial_api_cpp/09_face_from_image.cpp](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/examples/tutorial_api_cpp/09_face_from_image.cpp) and [examples/tutorial_api_cpp/10_hand_from_image.cpp](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/examples/tutorial_api_cpp/10_hand_from_image.cpp). The provide examples of face and/or hand keypoint detection given a known bounding box or rectangle for the face and/or hand locations. These examples are equivalent to use the following flags:
13+
Check the examples in `examples/tutorial_api_cpp/`, in particular [examples/tutorial_api_cpp/06_face_from_image.cpp](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/examples/tutorial_api_cpp/06_face_from_image.cpp) and [examples/tutorial_api_cpp/07_hand_from_image.cpp](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/examples/tutorial_api_cpp/07_hand_from_image.cpp). The provide examples of face and/or hand keypoint detection given a known bounding box or rectangle for the face and/or hand locations. These examples are equivalent to use the following flags:
1414
```
1515
# Face
16-
examples/tutorial_api_cpp/09_face_from_image.cpp --body_disable --face --face_detector 2
16+
examples/tutorial_api_cpp/06_face_from_image.cpp --body_disable --face --face_detector 2
1717
# Hands
18-
examples/tutorial_api_cpp/10_hand_from_image.cpp --body_disable --hand --hand_detector 2
18+
examples/tutorial_api_cpp/07_hand_from_image.cpp --body_disable --hand --hand_detector 2
1919
```
2020

2121
Note: both `FaceExtractor` and `HandExtractor` classes requires as input **squared rectangles**.
2222

23-
Advance solution: If you wanna use the whole OpenPose framework, you can use the synchronous examples of the `tutorial_api_cpp` folder with the configuration used for [examples/tutorial_api_cpp/09_face_from_image.cpp](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/examples/tutorial_api_cpp/09_face_from_image.cpp) and [examples/tutorial_api_cpp/10_hand_from_image.cpp](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/examples/tutorial_api_cpp/10_hand_from_image.cpp).
23+
Advance solution: If you wanna use the whole OpenPose framework, you can use the synchronous examples of the `tutorial_api_cpp` folder with the configuration used for [examples/tutorial_api_cpp/06_face_from_image.cpp](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/examples/tutorial_api_cpp/06_face_from_image.cpp) and [examples/tutorial_api_cpp/07_hand_from_image.cpp](https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/examples/tutorial_api_cpp/07_hand_from_image.cpp).

examples/tutorial_api_cpp/01_body_from_image_default.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,30 +46,30 @@ void printKeypoints(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>
4646
if (datumsPtr != nullptr && !datumsPtr->empty())
4747
{
4848
// Alternative 1
49-
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString());
49+
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString(), op::Priority::High);
5050

5151
// // Alternative 2
52-
// op::log(datumsPtr->at(0).poseKeypoints);
52+
// op::log(datumsPtr->at(0).poseKeypoints, op::Priority::High);
5353

5454
// // Alternative 3
5555
// std::cout << datumsPtr->at(0).poseKeypoints << std::endl;
5656

5757
// // Alternative 4 - Accesing each element of the keypoints
58-
// op::log("\nKeypoints:");
58+
// op::log("\nKeypoints:", op::Priority::High);
5959
// const auto& poseKeypoints = datumsPtr->at(0).poseKeypoints;
60-
// op::log("Person pose keypoints:");
60+
// op::log("Person pose keypoints:", op::Priority::High);
6161
// for (auto person = 0 ; person < poseKeypoints.getSize(0) ; person++)
6262
// {
63-
// op::log("Person " + std::to_string(person) + " (x, y, score):");
63+
// op::log("Person " + std::to_string(person) + " (x, y, score):", op::Priority::High);
6464
// for (auto bodyPart = 0 ; bodyPart < poseKeypoints.getSize(1) ; bodyPart++)
6565
// {
6666
// std::string valueToPrint;
6767
// for (auto xyscore = 0 ; xyscore < poseKeypoints.getSize(2) ; xyscore++)
6868
// valueToPrint += std::to_string( poseKeypoints[{person, bodyPart, xyscore}] ) + " ";
69-
// op::log(valueToPrint);
69+
// op::log(valueToPrint, op::Priority::High);
7070
// }
7171
// }
72-
// op::log(" ");
72+
// op::log(" ", op::Priority::High);
7373
}
7474
else
7575
op::log("Nullptr or empty datumsPtr found.", op::Priority::High);

examples/tutorial_api_cpp/02_whole_body_from_image_default.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ void printKeypoints(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>
4545
// Example: How to use the pose keypoints
4646
if (datumsPtr != nullptr && !datumsPtr->empty())
4747
{
48-
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString());
49-
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString());
50-
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString());
51-
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString());
48+
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString(), op::Priority::High);
49+
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString(), op::Priority::High);
50+
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString(), op::Priority::High);
51+
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString(), op::Priority::High);
5252
}
5353
else
5454
op::log("Nullptr or empty datumsPtr found.", op::Priority::High);

examples/tutorial_api_cpp/03_keypoints_from_image.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// ----------------------- OpenPose C++ API Tutorial - Example 3 - Body from image configurable -----------------------
1+
// ----------------------- OpenPose C++ API Tutorial - Example 3 - Body from image -----------------------
22
// It reads an image, process it, and displays it with the pose (and optionally hand and face) keypoints. In addition,
33
// it includes all the OpenPose configuration flags (enable/disable hand, face, output saving, etc.).
44

@@ -47,10 +47,10 @@ void printKeypoints(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>
4747
// Example: How to use the pose keypoints
4848
if (datumsPtr != nullptr && !datumsPtr->empty())
4949
{
50-
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString());
51-
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString());
52-
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString());
53-
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString());
50+
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString(), op::Priority::High);
51+
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString(), op::Priority::High);
52+
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString(), op::Priority::High);
53+
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString(), op::Priority::High);
5454
}
5555
else
5656
op::log("Nullptr or empty datumsPtr found.", op::Priority::High);

examples/tutorial_api_cpp/04_keypoints_from_images.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// ----------------------- OpenPose C++ API Tutorial - Example 4 - Body from images configurable ----------------------
1+
// ----------------------- OpenPose C++ API Tutorial - Example 4 - Body from images ----------------------
22
// It reads images, process them, and display them with the pose (and optionally hand and face) keypoints. In addition,
33
// it includes all the OpenPose configuration flags (enable/disable hand, face, output saving, etc.).
44

@@ -25,15 +25,14 @@ bool display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& dat
2525
// User's displaying/saving/other processing here
2626
// datum.cvOutputData: rendered frame with pose or heatmaps
2727
// datum.poseKeypoints: Array<float> with the estimated pose
28-
char key = ' ';
2928
if (datumsPtr != nullptr && !datumsPtr->empty())
3029
{
3130
// Display image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
3231
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
33-
key = (char)cv::waitKey(1);
3432
}
3533
else
3634
op::log("Nullptr or empty datumsPtr found.", op::Priority::High);
35+
const auto key = (char)cv::waitKey(1);
3736
return (key == 27);
3837
}
3938
catch (const std::exception& e)
@@ -50,10 +49,10 @@ void printKeypoints(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>
5049
// Example: How to use the pose keypoints
5150
if (datumsPtr != nullptr && !datumsPtr->empty())
5251
{
53-
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString());
54-
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString());
55-
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString());
56-
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString());
52+
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString(), op::Priority::High);
53+
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString(), op::Priority::High);
54+
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString(), op::Priority::High);
55+
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString(), op::Priority::High);
5756
}
5857
else
5958
op::log("Nullptr or empty datumsPtr found.", op::Priority::High);

examples/tutorial_api_cpp/05_keypoints_from_images_multi_gpu.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// --------------- OpenPose C++ API Tutorial - Example 5 - Body from images configurable and multi GPU ---------------
1+
// --------------- OpenPose C++ API Tutorial - Example 5 - Body from images and multi GPU ---------------
22
// It reads images, process them, and display them with the pose (and optionally hand and face) keypoints. In addition,
33
// it includes all the OpenPose configuration flags (enable/disable hand, face, output saving, etc.).
44

@@ -31,15 +31,14 @@ bool display(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>>>& dat
3131
// User's displaying/saving/other processing here
3232
// datum.cvOutputData: rendered frame with pose or heatmaps
3333
// datum.poseKeypoints: Array<float> with the estimated pose
34-
char key = ' ';
3534
if (datumsPtr != nullptr && !datumsPtr->empty())
3635
{
3736
// Display image and sleeps at least 1 ms (it usually sleeps ~5-10 msec to display the image)
3837
cv::imshow(OPEN_POSE_NAME_AND_VERSION + " - Tutorial C++ API", datumsPtr->at(0)->cvOutputData);
39-
key = (char)cv::waitKey(1);
4038
}
4139
else
4240
op::log("Nullptr or empty datumsPtr found.", op::Priority::High);
41+
const auto key = (char)cv::waitKey(1);
4342
return (key == 27);
4443
}
4544
catch (const std::exception& e)
@@ -56,10 +55,10 @@ void printKeypoints(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>
5655
// Example: How to use the pose keypoints
5756
if (datumsPtr != nullptr && !datumsPtr->empty())
5857
{
59-
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString());
60-
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString());
61-
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString());
62-
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString());
58+
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString(), op::Priority::High);
59+
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString(), op::Priority::High);
60+
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString(), op::Priority::High);
61+
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString(), op::Priority::High);
6362
}
6463
else
6564
op::log("Nullptr or empty datumsPtr found.", op::Priority::High);
@@ -177,9 +176,6 @@ int tutorialApiCpp()
177176
// Read frames on directory
178177
const auto imagePaths = op::getFilesOnDirectory(FLAGS_image_dir, op::Extensions::Images);
179178

180-
// Read number of GPUs in your system
181-
const auto numberGPUs = op::getGpuNumber();
182-
183179
// Process and display images
184180
// Option a) Harder to implement but the fastest method
185181
// Create 2 different threads:
@@ -188,6 +184,9 @@ int tutorialApiCpp()
188184
// Option b) Much easier and faster to implement but slightly slower runtime performance
189185
if (!FLAGS_latency_is_irrelevant_and_computer_with_lots_of_ram)
190186
{
187+
// Read number of GPUs in your system
188+
const auto numberGPUs = op::getGpuNumber();
189+
191190
for (auto imageBaseId = 0u ; imageBaseId < imagePaths.size() ; imageBaseId+=numberGPUs)
192191
{
193192
// Read and push images into OpenPose wrapper

examples/tutorial_api_cpp/06_face_from_image.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ void printKeypoints(const std::shared_ptr<std::vector<std::shared_ptr<op::Datum>
5050
// Example: How to use the pose keypoints
5151
if (datumsPtr != nullptr && !datumsPtr->empty())
5252
{
53-
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString());
54-
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString());
55-
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString());
56-
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString());
53+
op::log("Body keypoints: " + datumsPtr->at(0)->poseKeypoints.toString(), op::Priority::High);
54+
op::log("Face keypoints: " + datumsPtr->at(0)->faceKeypoints.toString(), op::Priority::High);
55+
op::log("Left hand keypoints: " + datumsPtr->at(0)->handKeypoints[0].toString(), op::Priority::High);
56+
op::log("Right hand keypoints: " + datumsPtr->at(0)->handKeypoints[1].toString(), op::Priority::High);
5757
}
5858
else
5959
op::log("Nullptr or empty datumsPtr found.", op::Priority::High);
@@ -100,25 +100,23 @@ void configureWrapper(op::Wrapper& opWrapper)
100100
// >1 camera view?
101101
const auto multipleView = (FLAGS_3d || FLAGS_3d_views > 1);
102102
// Face and hand detectors
103-
const auto faceDetector = op::Detector::Provided;
103+
const auto faceDetector = op::flagsToDetector(FLAGS_face_detector);
104104
const auto handDetector = op::flagsToDetector(FLAGS_hand_detector);
105105
// Enabling Google Logging
106106
const bool enableGoogleLogging = true;
107107

108108
// Pose configuration (use WrapperStructPose{} for default and recommended configuration)
109-
const auto bodyEnable = false;
110109
const op::WrapperStructPose wrapperStructPose{
111-
bodyEnable, netInputSize, outputSize, keypointScaleMode, FLAGS_num_gpu, FLAGS_num_gpu_start,
110+
!FLAGS_body_disable, netInputSize, outputSize, keypointScaleMode, FLAGS_num_gpu, FLAGS_num_gpu_start,
112111
FLAGS_scale_number, (float)FLAGS_scale_gap, op::flagsToRenderMode(FLAGS_render_pose, multipleView),
113112
poseModel, !FLAGS_disable_blending, (float)FLAGS_alpha_pose, (float)FLAGS_alpha_heatmap,
114113
FLAGS_part_to_show, FLAGS_model_folder, heatMapTypes, heatMapScaleMode, FLAGS_part_candidates,
115114
(float)FLAGS_render_threshold, FLAGS_number_people_max, FLAGS_maximize_positives, FLAGS_fps_max,
116115
FLAGS_prototxt_path, FLAGS_caffemodel_path, enableGoogleLogging};
117116
opWrapper.configure(wrapperStructPose);
118117
// Face configuration (use op::WrapperStructFace{} to disable it)
119-
const auto face = true;
120118
const op::WrapperStructFace wrapperStructFace{
121-
face, faceDetector, faceNetInputSize,
119+
FLAGS_face, faceDetector, faceNetInputSize,
122120
op::flagsToRenderMode(FLAGS_face_render, multipleView, FLAGS_render_pose),
123121
(float)FLAGS_face_alpha_pose, (float)FLAGS_face_alpha_heatmap, (float)FLAGS_face_render_threshold};
124122
opWrapper.configure(wrapperStructFace);
@@ -158,6 +156,11 @@ int tutorialApiCpp()
158156
op::log("Starting OpenPose demo...", op::Priority::High);
159157
const auto opTimer = op::getTimerInit();
160158

159+
// Required flags to enable heatmaps
160+
FLAGS_body_disable = true;
161+
FLAGS_face = true;
162+
FLAGS_face_detector = 2;
163+
161164
// Configuring OpenPose
162165
op::log("Configuring OpenPose...", op::Priority::High);
163166
op::Wrapper opWrapper{op::ThreadManagerMode::Asynchronous};
@@ -196,7 +199,7 @@ int tutorialApiCpp()
196199
op::log("Image could not be processed.", op::Priority::High);
197200

198201
// Info
199-
op::log("NOTE: In addition with the user flags, this demo has auto-selected the following flags:"
202+
op::log("NOTE: In addition with the user flags, this demo has auto-selected the following flags:\n"
200203
" `--body_disable --face --face_detector 2`", op::Priority::High);
201204

202205
// Measuring total time

0 commit comments

Comments
 (0)