diff --git a/Makefile b/Makefile index 11b084aa..e94c768e 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ LIB_BUILD_DIR := $(BUILD_DIR)/lib STATIC_NAME := $(LIB_BUILD_DIR)/lib$(LIBRARY_NAME).a DYNAMIC_VERSION_MAJOR := 1 DYNAMIC_VERSION_MINOR := 0 -DYNAMIC_VERSION_REVISION := 0-rc2 +DYNAMIC_VERSION_REVISION := 0-rc3 DYNAMIC_NAME_SHORT := lib$(LIBRARY_NAME).so #DYNAMIC_SONAME_SHORT := $(DYNAMIC_NAME_SHORT).$(DYNAMIC_VERSION_MAJOR) DYNAMIC_VERSIONED_NAME_SHORT := $(DYNAMIC_NAME_SHORT).$(DYNAMIC_VERSION_MAJOR).$(DYNAMIC_VERSION_MINOR).$(DYNAMIC_VERSION_REVISION) diff --git a/README.md b/README.md index 4233bf98..eec0126c 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,19 @@ OpenPose ==================================== +## Latest News +- Apr 2017: Body released! +- May 2017: Windows version released! +- Jun 2017: Face released! +- Check all the [release notes](doc/release_notes.md). + + + ## Introduction OpenPose is a **library for real-time multi-person keypoint detection and multi-threading written in C++** using OpenCV and Caffe*, authored by [Gines Hidalgo](https://www.linkedin.com/in/gineshidalgo/), [Zhe Cao](http://www.andrew.cmu.edu/user/zhecao), [Tomas Simon](http://www.cs.cmu.edu/~tsimon/), [Shih-En Wei](https://scholar.google.com/citations?user=sFQD3k4AAAAJ&hl=en), [Hanbyul Joo](http://www.cs.cmu.edu/~hanbyulj/) and [Yaser Sheikh](http://www.cs.cmu.edu/~yaser/). -* It uses Caffe, but the code is ready to be ported to other frameworks (e.g., Tensorflow or Torch). If you implement any of those, please, make a pull request and we will add it! +\* It uses Caffe, but the code is ready to be ported to other frameworks (Tensorflow, Torch, etc.). If you implement any of those, feel free to make a pull request! OpenPose represents the **first real-time system to jointly detect human body, hand and facial keypoints (in total 130 keypoints) on single images**. In addition, the system computational performance on body keypoint estimation is invariant to the number of detected people in the image. @@ -15,11 +23,11 @@ OpenPose is freely available for free non-commercial use, and may be redistribut Library main functionality: -* Multi-person 15 or **18-keypoint body pose** estimation and rendering. +* Multi-person 15 or **18-keypoint body pose** estimation and rendering. **Running time invariant of number of people** on the image. -* Multi-person **2x21-keypoint hand** estimation and rendering (coming soon in around 1-2 months!). +* Multi-person **2x21-keypoint hand** estimation and rendering. Note: In this initial version, **running time** linearly **depends** on the **number of people** on the image. **Coming soon (in around 1-5 weeks)!** -* Multi-person **70-keypoint face** estimation and rendering (coming soon in around 2-3 months!). +* Multi-person **70-keypoint face** estimation and rendering. Note: In this initial version, **running time** linearly **depends** on the **number of people** on the image. * Flexible and easy-to-configure **multi-threading** module. @@ -42,6 +50,11 @@ The pose estimation work is based on the C++ code from [the ECCV 2016 demo](http

+### Body + Face Estimation +

+ +

+ ## Coming Soon (But Already Working!) ### Body + Hands + Face Estimation @@ -49,11 +62,6 @@ The pose estimation work is based on the C++ code from [the ECCV 2016 demo](http

-### Body + Face Estimation -

- -

- ### Body + Hands

@@ -132,7 +140,7 @@ doxygen doc_autogeneration.doxygen ## Output #### Output Format -There are 2 alternatives to save the **(x,y,score) body part locations**. The `write_pose` flag uses the OpenCV cv::FileStorage default formats (JSON, XML and YML). However, the JSON format is only available after OpenCV 3.0. Hence, `write_pose_json` saves the people pose data using a custom JSON writer. For the latter, each JSON file has a `people` array of objects, where each object has an array `body_parts` containing the body part locations and detection confidence formatted as `x1,y1,c1,x2,y2,c2,...`. The coordinates `x` and `y` can be normalized to the range [0,1], [-1,1], [0, source size], [0, output size], etc., depending on the flag `scale_mode`. In addition, `c` is the confidence in the range [0,1]. +There are 2 alternatives to save the **(x,y,score) body part locations**. The `write_keypoint` flag uses the OpenCV cv::FileStorage default formats (JSON, XML and YML). However, the JSON format is only available after OpenCV 3.0. Hence, `write_keypoint_json` saves the people pose data using a custom JSON writer. For the latter, each JSON file has a `people` array of objects, where each object has an array `body_parts` containing the body part locations and detection confidence formatted as `x1,y1,c1,x2,y2,c2,...`. The coordinates `x` and `y` can be normalized to the range [0,1], [-1,1], [0, source size], [0, output size], etc., depending on the flag `keypoint_scale`. In addition, `c` is the confidence in the range [0,1]. ``` { @@ -181,6 +189,16 @@ Where each index is the key value corresponding to each body part in `POSE_COCO_ #### Reading Saved Results We use standard formats (JSON, XML, PNG, JPG, ...) to save our results, so there will be lots of frameworks to read them later, but you might also directly use our functions in [include/openpose/filestream.hpp](include/openpose/filestream.hpp). In particular, `loadData` (for JSON, XML and YML files) and `loadImage` (for image formats such as PNG or JPG) to load the data into cv::Mat format. +#### Pose Output Format +

+ +

+ +#### Face Output Format +

+ +

+ ## OpenPose Benchmark diff --git a/doc/UML/1_0_0rc1/UML.mdj b/doc/UML/1_0_0rc3/UML.mdj similarity index 99% rename from doc/UML/1_0_0rc1/UML.mdj rename to doc/UML/1_0_0rc3/UML.mdj index 59660927..d72d4612 100755 --- a/doc/UML/1_0_0rc1/UML.mdj +++ b/doc/UML/1_0_0rc3/UML.mdj @@ -5917,7 +5917,7 @@ "_parent": { "$ref": "AAAAAAFbHDZmRV10zeE=" }, - "name": "scaleKeyPoints", + "name": "scaleKeypoints", "ownedElements": [ { "_type": "UMLDependency", @@ -6005,7 +6005,7 @@ "_parent": { "$ref": "AAAAAAFbHDZmRV10zeE=" }, - "name": "wKeyPointScaler.hpp", + "name": "wKeypointScaler.hpp", "ownedElements": [ { "_type": "UMLDependency", @@ -6076,7 +6076,7 @@ "_parent": { "$ref": "AAAAAAFbHDZmRV10zeE=" }, - "name": "KeyPointScaler", + "name": "KeypointScaler", "ownedElements": [ { "_type": "UMLDependency", @@ -6409,9 +6409,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 117, + "left": 141, "top": 231, - "width": 127, + "width": 103, "height": 13, "autoResize": false, "underline": false, @@ -6481,9 +6481,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 112, + "left": 136, "top": 224, - "width": 137, + "width": 113, "height": 25, "autoResize": false, "stereotypeLabel": { @@ -6517,9 +6517,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 112, + "left": 136, "top": 249, - "width": 137, + "width": 113, "height": 10, "autoResize": false }, @@ -6541,9 +6541,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 112, + "left": 136, "top": 259, - "width": 137, + "width": 113, "height": 10, "autoResize": false }, @@ -6608,9 +6608,9 @@ "showShadow": true, "containerChangeable": true, "containerExtending": false, - "left": 112, + "left": 136, "top": 224, - "width": 137, + "width": 113, "height": 45, "autoResize": false, "stereotypeDisplay": "label", @@ -6966,7 +6966,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 200, + "left": 152, "top": 72, "width": 0, "height": 13, @@ -6991,9 +6991,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 437, + "left": 413, "top": 231, - "width": 169, + "width": 113, "height": 13, "autoResize": false, "underline": false, @@ -7017,7 +7017,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 200, + "left": 152, "top": 72, "width": 72, "height": 13, @@ -7043,7 +7043,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 200, + "left": 152, "top": 72, "width": 0, "height": 13, @@ -7063,9 +7063,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 432, + "left": 408, "top": 224, - "width": 179, + "width": 123, "height": 25, "autoResize": false, "stereotypeLabel": { @@ -7099,9 +7099,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 432, + "left": 408, "top": 249, - "width": 179, + "width": 123, "height": 10, "autoResize": false }, @@ -7123,9 +7123,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 432, + "left": 408, "top": 259, - "width": 179, + "width": 123, "height": 10, "autoResize": false }, @@ -7147,7 +7147,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 120, + "left": 96, "top": -8, "width": 10, "height": 10, @@ -7171,7 +7171,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 120, + "left": 96, "top": -8, "width": 10, "height": 10, @@ -7190,9 +7190,9 @@ "showShadow": true, "containerChangeable": true, "containerExtending": false, - "left": 432, + "left": 408, "top": 224, - "width": 179, + "width": 123, "height": 45, "autoResize": false, "stereotypeDisplay": "label", @@ -8996,8 +8996,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 335, - "top": 314, + "left": 316, + "top": 312, "width": 0, "height": 13, "autoResize": false, @@ -9030,8 +9030,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 340, - "top": 328, + "left": 321, + "top": 326, "width": 0, "height": 13, "autoResize": false, @@ -9064,7 +9064,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 326, + "left": 305, "top": 285, "width": 0, "height": 13, @@ -9097,7 +9097,7 @@ "$ref": "AAAAAAFbHDibKUyHyzc=" }, "lineStyle": 1, - "points": "448:269;215:343", + "points": "408:269;215:342", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -9139,8 +9139,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 200, - "top": 289, + "left": 206, + "top": 291, "width": 0, "height": 13, "autoResize": false, @@ -9173,8 +9173,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 215, - "top": 287, + "left": 221, + "top": 290, "width": 0, "height": 13, "autoResize": false, @@ -9207,8 +9207,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 171, - "top": 294, + "left": 177, + "top": 292, "width": 0, "height": 13, "autoResize": false, @@ -9240,7 +9240,7 @@ "$ref": "AAAAAAFbHDieuEywuH8=" }, "lineStyle": 1, - "points": "183:269;190:327", + "points": "192:269;193:327", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -9568,8 +9568,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 182, - "top": 180, + "left": 188, + "top": 179, "width": 0, "height": 13, "autoResize": false, @@ -9602,8 +9602,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 197, - "top": 177, + "left": 202, + "top": 174, "width": 0, "height": 13, "autoResize": false, @@ -9636,8 +9636,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 153, - "top": 187, + "left": 159, + "top": 188, "width": 0, "height": 13, "autoResize": false, @@ -9669,7 +9669,7 @@ "$ref": "AAAAAAFbHDirkk2m0MU=" }, "lineStyle": 1, - "points": "161:157;175:223", + "points": "163:157;185:223", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -9711,8 +9711,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 543, - "top": 186, + "left": 515, + "top": 191, "width": 0, "height": 13, "autoResize": false, @@ -9745,8 +9745,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 558, - "top": 188, + "left": 528, + "top": 199, "width": 0, "height": 13, "autoResize": false, @@ -9779,8 +9779,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 514, - "top": 181, + "left": 490, + "top": 176, "width": 0, "height": 13, "autoResize": false, @@ -9812,7 +9812,7 @@ "$ref": "AAAAAAFbHDiqGk19SxU=" }, "lineStyle": 1, - "points": "534:157;524:223", + "points": "523:157;483:223", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -11032,8 +11032,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 153, - "top": 187, + "left": 159, + "top": 188, "width": 0, "height": 13, "autoResize": false, @@ -11066,8 +11066,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 138, - "top": 190, + "left": 145, + "top": 193, "width": 0, "height": 13, "autoResize": false, @@ -11100,8 +11100,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 182, - "top": 180, + "left": 188, + "top": 179, "width": 0, "height": 13, "autoResize": false, @@ -11134,8 +11134,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 154, - "top": 194, + "left": 162, + "top": 197, "width": 0, "height": 13, "autoResize": false, @@ -11168,8 +11168,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 141, - "top": 195, + "left": 149, + "top": 199, "width": 0, "height": 13, "autoResize": false, @@ -11202,8 +11202,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 182, - "top": 193, + "left": 190, + "top": 192, "width": 0, "height": 13, "autoResize": false, @@ -11236,8 +11236,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 151, - "top": 179, + "left": 156, + "top": 180, "width": 0, "height": 13, "autoResize": false, @@ -11270,8 +11270,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 139, - "top": 184, + "left": 145, + "top": 186, "width": 0, "height": 13, "autoResize": false, @@ -11304,8 +11304,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 177, - "top": 169, + "left": 181, + "top": 167, "width": 0, "height": 13, "autoResize": false, @@ -11385,7 +11385,7 @@ "$ref": "AAAAAAFbHDieuEywuH8=" }, "lineStyle": 1, - "points": "175:223;161:157", + "points": "185:223;163:157", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -11453,8 +11453,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 514, - "top": 181, + "left": 490, + "top": 176, "width": 0, "height": 13, "autoResize": false, @@ -11487,8 +11487,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 499, - "top": 179, + "left": 477, + "top": 168, "width": 0, "height": 13, "autoResize": false, @@ -11521,8 +11521,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 543, - "top": 186, + "left": 515, + "top": 191, "width": 0, "height": 13, "autoResize": false, @@ -11555,8 +11555,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 513, - "top": 189, + "left": 483, + "top": 187, "width": 0, "height": 13, "autoResize": false, @@ -11589,8 +11589,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 500, - "top": 184, + "left": 473, + "top": 178, "width": 0, "height": 13, "autoResize": false, @@ -11623,8 +11623,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 539, - "top": 197, + "left": 504, + "top": 204, "width": 0, "height": 13, "autoResize": false, @@ -11657,8 +11657,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 515, - "top": 174, + "left": 496, + "top": 165, "width": 0, "height": 13, "autoResize": false, @@ -11691,8 +11691,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 501, - "top": 174, + "left": 484, + "top": 160, "width": 0, "height": 13, "autoResize": false, @@ -11725,8 +11725,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 543, - "top": 174, + "left": 522, + "top": 175, "width": 0, "height": 13, "autoResize": false, @@ -11806,7 +11806,7 @@ "$ref": "AAAAAAFbHDibKUyHyzc=" }, "lineStyle": 1, - "points": "524:223;534:157", + "points": "483:223;523:157", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -12172,7 +12172,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 16, + "left": -32, "top": -1104, "width": 0, "height": 13, @@ -12197,9 +12197,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 285, + "left": 272, "top": 231, - "width": 124, + "width": 113, "height": 13, "autoResize": false, "underline": false, @@ -12223,7 +12223,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 16, + "left": -32, "top": -1104, "width": 72, "height": 13, @@ -12249,7 +12249,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 16, + "left": -32, "top": -1104, "width": 0, "height": 13, @@ -12269,9 +12269,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 280, + "left": 267, "top": 224, - "width": 134, + "width": 123, "height": 25, "autoResize": false, "stereotypeLabel": { @@ -12305,9 +12305,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 280, + "left": 267, "top": 249, - "width": 134, + "width": 123, "height": 10, "autoResize": false }, @@ -12329,9 +12329,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 280, + "left": 267, "top": 259, - "width": 134, + "width": 123, "height": 10, "autoResize": false }, @@ -12353,7 +12353,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 104, + "left": 80, "top": -696, "width": 10, "height": 10, @@ -12377,7 +12377,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 104, + "left": 80, "top": -696, "width": 10, "height": 10, @@ -12396,9 +12396,9 @@ "showShadow": true, "containerChangeable": true, "containerExtending": false, - "left": 280, + "left": 267, "top": 224, - "width": 134, + "width": 123, "height": 45, "autoResize": false, "stereotypeDisplay": "label", @@ -12599,8 +12599,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 271, - "top": 308, + "left": 265, + "top": 306, "width": 0, "height": 13, "autoResize": false, @@ -12633,8 +12633,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 279, - "top": 320, + "left": 274, + "top": 318, "width": 0, "height": 13, "autoResize": false, @@ -12667,7 +12667,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 254, + "left": 246, "top": 283, "width": 0, "height": 13, @@ -12700,7 +12700,7 @@ "$ref": "AAAAAAFbJy+z+E++48k=" }, "lineStyle": 1, - "points": "312:269;215:335", + "points": "298:269;215:333", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -12742,8 +12742,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 338, - "top": 181, + "left": 329, + "top": 179, "width": 0, "height": 13, "autoResize": false, @@ -12776,8 +12776,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 323, - "top": 179, + "left": 315, + "top": 175, "width": 0, "height": 13, "autoResize": false, @@ -12810,8 +12810,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 367, - "top": 186, + "left": 358, + "top": 188, "width": 0, "height": 13, "autoResize": false, @@ -12844,8 +12844,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 337, - "top": 189, + "left": 327, + "top": 187, "width": 0, "height": 13, "autoResize": false, @@ -12878,8 +12878,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 324, - "top": 185, + "left": 315, + "top": 181, "width": 0, "height": 13, "autoResize": false, @@ -12912,8 +12912,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 364, - "top": 197, + "left": 353, + "top": 199, "width": 0, "height": 13, "autoResize": false, @@ -12946,8 +12946,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 339, - "top": 174, + "left": 332, + "top": 171, "width": 0, "height": 13, "autoResize": false, @@ -12980,8 +12980,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 326, - "top": 175, + "left": 318, + "top": 170, "width": 0, "height": 13, "autoResize": false, @@ -13014,8 +13014,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 367, - "top": 174, + "left": 360, + "top": 175, "width": 0, "height": 13, "autoResize": false, @@ -13095,7 +13095,7 @@ "$ref": "AAAAAAFbJy+z+E++48k=" }, "lineStyle": 1, - "points": "349:223;358:157", + "points": "335:223;354:157", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -13163,8 +13163,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 367, - "top": 185, + "left": 358, + "top": 187, "width": 0, "height": 13, "autoResize": false, @@ -13197,8 +13197,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 382, - "top": 187, + "left": 372, + "top": 191, "width": 0, "height": 13, "autoResize": false, @@ -13231,8 +13231,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 338, - "top": 182, + "left": 329, + "top": 180, "width": 0, "height": 13, "autoResize": false, @@ -13264,7 +13264,7 @@ "$ref": "AAAAAAFbJy96y08MtFk=" }, "lineStyle": 1, - "points": "358:157;349:223", + "points": "354:157;335:223", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -13313,7 +13313,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 742, + "left": 678, "top": -504, "width": 0, "height": 13, @@ -13338,13 +13338,13 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 621, + "left": 589, "top": 231, - "width": 64, + "width": 95, "height": 13, "autoResize": false, "underline": false, - "text": "scaleKeyPoints", + "text": "scaleKeypoints", "horizontalAlignment": 2, "verticalAlignment": 5, "wordWrap": false @@ -13364,7 +13364,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 742, + "left": 678, "top": -504, "width": 72, "height": 13, @@ -13390,7 +13390,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 742, + "left": 678, "top": -504, "width": 0, "height": 13, @@ -13410,9 +13410,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 616, + "left": 584, "top": 224, - "width": 74, + "width": 105, "height": 25, "autoResize": false, "stereotypeLabel": { @@ -13446,9 +13446,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 616, + "left": 584, "top": 249, - "width": 74, + "width": 105, "height": 10, "autoResize": false }, @@ -13470,9 +13470,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 616, + "left": 584, "top": 259, - "width": 74, + "width": 105, "height": 10, "autoResize": false }, @@ -13494,7 +13494,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 87, + "left": 55, "top": -200, "width": 10, "height": 10, @@ -13518,7 +13518,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 87, + "left": 55, "top": -200, "width": 10, "height": 10, @@ -13537,9 +13537,9 @@ "showShadow": true, "containerChangeable": true, "containerExtending": false, - "left": 616, + "left": 584, "top": 224, - "width": 74, + "width": 105, "height": 45, "autoResize": false, "stereotypeDisplay": "label", @@ -13604,7 +13604,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": -329, + "left": -393, "top": -720, "width": 0, "height": 13, @@ -13629,13 +13629,13 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 661, + "left": 629, "top": 47, - "width": 114, + "width": 136, "height": 13, "autoResize": false, "underline": false, - "text": "wKeyPointScaler.hpp", + "text": "wKeypointScaler.hpp", "horizontalAlignment": 2, "verticalAlignment": 5, "wordWrap": false @@ -13655,7 +13655,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": -329, + "left": -393, "top": -720, "width": 72, "height": 13, @@ -13681,7 +13681,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": -329, + "left": -393, "top": -720, "width": 0, "height": 13, @@ -13701,9 +13701,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 656, + "left": 624, "top": 40, - "width": 124, + "width": 146, "height": 25, "autoResize": false, "stereotypeLabel": { @@ -13737,9 +13737,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 656, + "left": 624, "top": 65, - "width": 124, + "width": 146, "height": 10, "autoResize": false }, @@ -13761,9 +13761,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 656, + "left": 624, "top": 75, - "width": 124, + "width": 146, "height": 10, "autoResize": false }, @@ -13785,7 +13785,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": -480, + "left": -512, "top": -352, "width": 10, "height": 10, @@ -13809,7 +13809,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": -480, + "left": -512, "top": -352, "width": 10, "height": 10, @@ -13828,9 +13828,9 @@ "showShadow": true, "containerChangeable": true, "containerExtending": false, - "left": 656, + "left": 624, "top": 40, - "width": 124, + "width": 146, "height": 45, "autoResize": false, "stereotypeDisplay": "label", @@ -13888,8 +13888,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 708, - "top": 99, + "left": 704, + "top": 93, "width": 0, "height": 13, "autoResize": false, @@ -13922,8 +13922,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 721, - "top": 106, + "left": 719, + "top": 94, "width": 0, "height": 13, "autoResize": false, @@ -13956,8 +13956,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 681, - "top": 84, + "left": 675, + "top": 90, "width": 0, "height": 13, "autoResize": false, @@ -13989,7 +13989,7 @@ "$ref": "AAAAAAFbgmAJRXI9LpI=" }, "lineStyle": 1, - "points": "703:85;688:111", + "points": "692:85;689:111", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -14031,8 +14031,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 682, - "top": 84, + "left": 675, + "top": 89, "width": 0, "height": 13, "autoResize": false, @@ -14065,8 +14065,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 669, - "top": 76, + "left": 660, + "top": 87, "width": 0, "height": 13, "autoResize": false, @@ -14099,8 +14099,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 707, - "top": 99, + "left": 704, + "top": 94, "width": 0, "height": 13, "autoResize": false, @@ -14133,8 +14133,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 687, - "top": 75, + "left": 677, + "top": 77, "width": 0, "height": 13, "autoResize": false, @@ -14167,8 +14167,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 677, - "top": 66, + "left": 664, + "top": 73, "width": 0, "height": 13, "autoResize": false, @@ -14201,8 +14201,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 709, - "top": 92, + "left": 703, + "top": 84, "width": 0, "height": 13, "autoResize": false, @@ -14235,8 +14235,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 677, - "top": 94, + "left": 674, + "top": 103, "width": 0, "height": 13, "autoResize": false, @@ -14269,8 +14269,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 664, - "top": 89, + "left": 660, + "top": 103, "width": 0, "height": 13, "autoResize": false, @@ -14303,8 +14303,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 703, - "top": 103, + "left": 701, + "top": 101, "width": 0, "height": 13, "autoResize": false, @@ -14384,7 +14384,7 @@ "$ref": "AAAAAAFbgmGMA7e9i94=" }, "lineStyle": 1, - "points": "688:111;703:85", + "points": "689:111;692:85", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -14452,8 +14452,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 820, - "top": 133, + "left": 809, + "top": 132, "width": 0, "height": 13, "autoResize": false, @@ -14486,8 +14486,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 830, - "top": 122, + "left": 819, + "top": 121, "width": 0, "height": 13, "autoResize": false, @@ -14520,8 +14520,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 799, - "top": 154, + "left": 790, + "top": 155, "width": 0, "height": 13, "autoResize": false, @@ -14553,7 +14553,7 @@ "$ref": "AAAAAAFbgmAJRXI9LpI=" }, "lineStyle": 1, - "points": "741:85;880:215", + "points": "723:85;877:215", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -14629,11 +14629,11 @@ "containerExtending": false, "left": 637, "top": 119, - "width": 75, + "width": 97, "height": 13, "autoResize": false, "underline": false, - "text": "KeyPointScaler", + "text": "KeypointScaler", "horizontalAlignment": 2, "verticalAlignment": 5, "wordWrap": false @@ -14701,7 +14701,7 @@ "containerExtending": false, "left": 632, "top": 112, - "width": 85, + "width": 107, "height": 25, "autoResize": false, "stereotypeLabel": { @@ -14737,7 +14737,7 @@ "containerExtending": false, "left": 632, "top": 137, - "width": 85, + "width": 107, "height": 10, "autoResize": false }, @@ -14761,7 +14761,7 @@ "containerExtending": false, "left": 632, "top": 147, - "width": 85, + "width": 107, "height": 10, "autoResize": false }, @@ -14828,7 +14828,7 @@ "containerExtending": false, "left": 632, "top": 112, - "width": 85, + "width": 107, "height": 45, "autoResize": false, "stereotypeDisplay": "label", @@ -14886,8 +14886,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 418, - "top": 307, + "left": 402, + "top": 309, "width": 0, "height": 13, "autoResize": false, @@ -14920,8 +14920,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 421, - "top": 322, + "left": 405, + "top": 324, "width": 0, "height": 13, "autoResize": false, @@ -14954,8 +14954,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 411, - "top": 278, + "left": 395, + "top": 280, "width": 0, "height": 13, "autoResize": false, @@ -14987,7 +14987,7 @@ "$ref": "AAAAAAFbgmAJRnJHsH0=" }, "lineStyle": 1, - "points": "615:254;215:345", + "points": "583:258;215:345", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -15029,8 +15029,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 677, - "top": 186, + "left": 673, + "top": 189, "width": 0, "height": 13, "autoResize": false, @@ -15063,8 +15063,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 692, - "top": 189, + "left": 687, + "top": 195, "width": 0, "height": 13, "autoResize": false, @@ -15097,8 +15097,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 648, - "top": 181, + "left": 646, + "top": 178, "width": 0, "height": 13, "autoResize": false, @@ -15130,7 +15130,7 @@ "$ref": "AAAAAAFbgmGMA7e9i94=" }, "lineStyle": 1, - "points": "669:157;657:223", + "points": "675:157;646:223", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -25509,7 +25509,7 @@ "containerExtending": false, "left": 5, "top": 22, - "width": 1127, + "width": 1023, "height": 13, "autoResize": false, "underline": false, @@ -25581,7 +25581,7 @@ "containerExtending": false, "left": 0, "top": 15, - "width": 1137, + "width": 1033, "height": 25, "autoResize": false, "stereotypeLabel": { @@ -25656,7 +25656,7 @@ "containerExtending": false, "left": 0, "top": 0, - "width": 1137, + "width": 1033, "height": 625, "autoResize": false, "stereotypeDisplay": "label", @@ -29512,9 +29512,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 45, + "left": 73, "top": 567, - "width": 85, + "width": 57, "height": 13, "autoResize": false, "underline": false, @@ -29584,9 +29584,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 40, + "left": 68, "top": 560, - "width": 95, + "width": 67, "height": 25, "autoResize": false, "stereotypeLabel": { @@ -29620,9 +29620,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 40, + "left": 68, "top": 585, - "width": 95, + "width": 67, "height": 10, "autoResize": false }, @@ -29644,9 +29644,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 40, + "left": 68, "top": 595, - "width": 95, + "width": 67, "height": 10, "autoResize": false }, @@ -29711,9 +29711,9 @@ "showShadow": true, "containerChangeable": true, "containerExtending": false, - "left": 40, + "left": 68, "top": 560, - "width": 95, + "width": 67, "height": 45, "autoResize": false, "stereotypeDisplay": "label", @@ -29803,9 +29803,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 45, + "left": 73, "top": 463, - "width": 87, + "width": 59, "height": 13, "autoResize": false, "underline": false, @@ -29875,9 +29875,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 40, + "left": 68, "top": 456, - "width": 97, + "width": 69, "height": 25, "autoResize": false, "stereotypeLabel": { @@ -29911,9 +29911,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 40, + "left": 68, "top": 481, - "width": 97, + "width": 69, "height": 10, "autoResize": false }, @@ -29935,9 +29935,9 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 40, + "left": 68, "top": 491, - "width": 97, + "width": 69, "height": 10, "autoResize": false }, @@ -30002,9 +30002,9 @@ "showShadow": true, "containerChangeable": true, "containerExtending": false, - "left": 40, + "left": 68, "top": 456, - "width": 97, + "width": 69, "height": 45, "autoResize": false, "stereotypeDisplay": "label", @@ -30819,7 +30819,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 101, + "left": 115, "top": 523, "width": 0, "height": 13, @@ -30853,7 +30853,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 116, + "left": 130, "top": 523, "width": 0, "height": 13, @@ -30887,7 +30887,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 72, + "left": 86, "top": 524, "width": 0, "height": 13, @@ -30920,7 +30920,7 @@ "$ref": "AAAAAAFbHFy95Zfi54c=" }, "lineStyle": 1, - "points": "88:501;87:559", + "points": "102:501;101:559", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -32248,8 +32248,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 1968, - "top": -1104, + "left": 1792, + "top": -1168, "width": 0, "height": 13, "autoResize": false, @@ -32273,8 +32273,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 1157, - "top": 414, + "left": 1069, + "top": 382, "width": 199, "height": 13, "autoResize": false, @@ -32299,8 +32299,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 1968, - "top": -1104, + "left": 1792, + "top": -1168, "width": 72, "height": 13, "autoResize": false, @@ -32325,8 +32325,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 1968, - "top": -1104, + "left": 1792, + "top": -1168, "width": 0, "height": 13, "autoResize": false, @@ -32345,8 +32345,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 1152, - "top": 407, + "left": 1064, + "top": 375, "width": 209, "height": 25, "autoResize": false, @@ -32378,8 +32378,8 @@ "showShadow": true, "containerChangeable": true, "containerExtending": false, - "left": 1152, - "top": 392, + "left": 1064, + "top": 360, "width": 209, "height": 168, "autoResize": false, @@ -32428,8 +32428,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 2048, - "top": -888, + "left": 1872, + "top": -952, "width": 0, "height": 13, "autoResize": false, @@ -32453,8 +32453,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 1221, - "top": 463, + "left": 1133, + "top": 431, "width": 72, "height": 13, "autoResize": false, @@ -32479,8 +32479,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 2048, - "top": -888, + "left": 1872, + "top": -952, "width": 73, "height": 13, "autoResize": false, @@ -32505,8 +32505,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 2048, - "top": -888, + "left": 1872, + "top": -952, "width": 0, "height": 13, "autoResize": false, @@ -32525,8 +32525,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 1216, - "top": 456, + "left": 1128, + "top": 424, "width": 82, "height": 25, "autoResize": false, @@ -32561,8 +32561,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 1216, - "top": 481, + "left": 1128, + "top": 449, "width": 82, "height": 10, "autoResize": false @@ -32585,8 +32585,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 1216, - "top": 491, + "left": 1128, + "top": 459, "width": 82, "height": 10, "autoResize": false @@ -32609,8 +32609,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 1032, - "top": -392, + "left": 944, + "top": -424, "width": 10, "height": 10, "autoResize": false @@ -32633,8 +32633,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 1032, - "top": -392, + "left": 944, + "top": -424, "width": 10, "height": 10, "autoResize": false @@ -32652,8 +32652,8 @@ "showShadow": true, "containerChangeable": true, "containerExtending": false, - "left": 1216, - "top": 456, + "left": 1128, + "top": 424, "width": 82, "height": 45, "autoResize": false, @@ -32712,8 +32712,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 864, - "top": 309, + "left": 820, + "top": 293, "width": 0, "height": 13, "autoResize": false, @@ -32746,8 +32746,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 869, - "top": 295, + "left": 825, + "top": 279, "width": 0, "height": 13, "autoResize": false, @@ -32780,8 +32780,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 853, - "top": 338, + "left": 809, + "top": 322, "width": 0, "height": 13, "autoResize": false, @@ -32813,7 +32813,7 @@ "$ref": "AAAAAAFbHFyblZYYzdE=" }, "lineStyle": 1, - "points": "504:197;1215:463", + "points": "503:197;1127:431", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -32855,8 +32855,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 993, - "top": 306, + "left": 949, + "top": 291, "width": 0, "height": 13, "autoResize": false, @@ -32889,8 +32889,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 1000, - "top": 293, + "left": 957, + "top": 278, "width": 0, "height": 13, "autoResize": false, @@ -32923,8 +32923,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 978, - "top": 333, + "left": 934, + "top": 316, "width": 0, "height": 13, "autoResize": false, @@ -32956,7 +32956,7 @@ "$ref": "AAAAAAFbHFyaDpXvuYI=" }, "lineStyle": 1, - "points": "757:197;1215:455", + "points": "754:197;1130:423", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -34269,8 +34269,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 269, - "top": 384, + "left": 270, + "top": 386, "width": 0, "height": 13, "autoResize": false, @@ -34303,8 +34303,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 263, - "top": 370, + "left": 264, + "top": 372, "width": 0, "height": 13, "autoResize": false, @@ -34337,8 +34337,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 280, - "top": 411, + "left": 281, + "top": 413, "width": 0, "height": 13, "autoResize": false, @@ -34372,7 +34372,7 @@ "containerChangeable": false, "containerExtending": false, "left": 155, - "top": 429, + "top": 434, "width": 0, "height": 13, "autoResize": false, @@ -34406,7 +34406,7 @@ "containerChangeable": false, "containerExtending": false, "left": 152, - "top": 416, + "top": 421, "width": 0, "height": 13, "autoResize": false, @@ -34440,7 +34440,7 @@ "containerChangeable": false, "containerExtending": false, "left": 161, - "top": 456, + "top": 461, "width": 0, "height": 13, "autoResize": false, @@ -34473,8 +34473,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 384, - "top": 338, + "left": 386, + "top": 339, "width": 0, "height": 13, "autoResize": false, @@ -34507,7 +34507,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 377, + "left": 379, "top": 327, "width": 0, "height": 13, @@ -34541,7 +34541,7 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 398, + "left": 400, "top": 362, "width": 0, "height": 13, @@ -34622,7 +34622,7 @@ "$ref": "AAAAAAFbHFy95Zfi54c=" }, "lineStyle": 1, - "points": "137:459;414:349", + "points": "137:464;416:349", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, @@ -35532,8 +35532,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 280, - "top": 411, + "left": 281, + "top": 413, "width": 0, "height": 13, "autoResize": false, @@ -35566,8 +35566,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 286, - "top": 425, + "left": 287, + "top": 427, "width": 0, "height": 13, "autoResize": false, @@ -35600,8 +35600,8 @@ "showShadow": true, "containerChangeable": false, "containerExtending": false, - "left": 269, - "top": 384, + "left": 270, + "top": 386, "width": 0, "height": 13, "autoResize": false, @@ -35633,7 +35633,7 @@ "$ref": "AAAAAAFbHFzB0pg0a44=" }, "lineStyle": 1, - "points": "414:349;137:459", + "points": "416:349;137:464", "stereotypeDisplay": "label", "showVisibility": true, "showProperty": true, diff --git a/doc/UML/1_0_0rc1/UML.pdf b/doc/UML/1_0_0rc3/UML.pdf similarity index 56% rename from doc/UML/1_0_0rc1/UML.pdf rename to doc/UML/1_0_0rc3/UML.pdf index 0c551505..b643b206 100644 Binary files a/doc/UML/1_0_0rc1/UML.pdf and b/doc/UML/1_0_0rc3/UML.pdf differ diff --git a/doc/UML/1_0_0rc1/UML.png b/doc/UML/1_0_0rc3/UML.png similarity index 100% rename from doc/UML/1_0_0rc1/UML.png rename to doc/UML/1_0_0rc3/UML.png diff --git a/doc/demo_overview.md b/doc/demo_overview.md index eb1fe058..40f3d917 100644 --- a/doc/demo_overview.md +++ b/doc/demo_overview.md @@ -7,38 +7,65 @@ In order to learn how to use it, run `./build/examples/openpose/openpose.bin --h -## Other Important Options -Please, in order to check all the real time pose demo options and their details, run `./build/examples/openpose/openpose.bin --help`. We describe here some of the most important ones. +## All Flags +Each flag is divided into flag name, default value, and description. -`--video input.mp4`: Input video. If omitted, it will use the webcam. - -`--camera 3`: Choose webcam number (default: 0). If `--camera`, `--image_dir` and `--write_video` are omitted, it is equivalent to use `--camera 0`. - -`--image_dir path_to_images/`: Run on all images (jpg, png, bmp, etc.) in `path_to_images/`. You can test the program with the image directory `examples/media/`. - -`--write_video path.avi`: Render images with this prefix: `path.avi`. You can test the program with the example video `examples/media/video.avi`. - -`--write_pose path/`: Output JSON, XML or YML files with the people pose data on the `path/` folder. - -`--process_real_time`: It might skip frames in order to keep the final output displaying frames on real time. - -`--disable_blending`: If selected, it will only render the pose skeleton or desired heat maps, while blocking the original background. Also related: `part_to_show`, `alpha_pose`, and `alpha_pose`. - -`--part_to_show`: Select the prediction channel to visualize (default: 0). 0 to visualize all the body parts, 1-18 for each body part heat map, 19 for the background heat map, 20 for all the body part heat maps together, 21 for all the PAFs, 22-69 for each body part pair PAF. - -`--no_display`: Display window not opened. Useful if there is no X server and/or to slightly speed up the processing if visual output is not required. - -`--num_gpu 2 --num_gpu_start 0`: Parallelize over this number of GPUs starting by the desired device id. Default is 1 and 0, respectively. - -`--num_scales 3 --scale_gap 0.15`: Use 3 scales, 1, (1-0.15), (1-0.15*2). Default is one scale. If you want to change the initial scale, you actually want to multiply your desired initial scale by the `net_resolution`. - -`--net_resolution 656x368 --resolution 1280x720`: For HD images and video (default values). - -`--net_resolution 496x368 --resolution 640x480`: For VGA images and video. - -`--model_pose MPI`: It will use MPI (15 body keypoints). Default: COCO (18 body keypoints). MPI is slightly faster. The variation `MPI_4_layers` sacrifies accuracy in order to further increase speed. - -`--logging_level 3`: Logging messages threshold, range [0,255]: 0 will output any message & 255 will output none. Current messages in the range [1-4], 1 for low priority messages and 4 for important ones. +1. Debugging +- DEFINE_int32(logging_level, 3, "The logging level. Integer in the range [0, 255]. 0 will output any log() message, while 255 will not output any. Current OpenPose library messages are in the range 0-4: 1 for low priority messages and 4 for important ones."); +2. Producer +- DEFINE_int32(camera, 0, "The camera index for cv::VideoCapture. Integer in the range [0, 9]."); +- DEFINE_string(camera_resolution, "1280x720", "Size of the camera frames to ask for."); +- DEFINE_string(video, "", "Use a video file instead of the camera. Use `examples/media/video.avi` for our default example video."); +- DEFINE_string(image_dir, "", "Process a directory of images. Use `examples/media/` for our default example folder with 20 images."); +- DEFINE_uint64(frame_first, 0, "Start on desired frame number."); +- DEFINE_uint64(frame_last, -1, "Finish on desired frame number. Select -1 to disable this option."); +- DEFINE_bool(frame_flip, false, "Flip/mirror each frame (e.g. for real time webcam demonstrations)."); +- DEFINE_int32(frame_rotate, 0, "Rotate each frame, 4 possible values: 0, 90, 180, 270."); +- DEFINE_bool(frames_repeat, false, "Repeat frames when finished."); +3. OpenPose +- DEFINE_string(model_folder, "models/", "Folder where the pose models (COCO and MPI) are located."); +- DEFINE_string(resolution, "1280x720", "The image resolution (display and output). Use \"-1x-1\" to force the program to use the default images resolution."); +- DEFINE_int32(num_gpu, -1, "The number of GPU devices to use. If negative, it will use all the available GPUs in your machine."); +- DEFINE_int32(num_gpu_start, 0, "GPU device start number."); +- DEFINE_int32(keypoint_scale, 0, "Scaling of the (x,y) coordinates of the final pose data array, i.e. the scale of the (x,y) coordinates that will be saved with the `write_keypoint` & `write_keypoint_json` flags. Select `0` to scale it to the original source resolution, `1`to scale it to the net output size (set with `net_resolution`), `2` to scale it to the final output size (set with `resolution`), `3` to scale it in the range [0,1], and 4 for range [-1,1]. Non related with `num_scales` and `scale_gap`."); +4. OpenPose Body Pose +- DEFINE_string(model_pose, "COCO", "Model to be used (e.g. COCO, MPI, MPI_4_layers)."); +- DEFINE_string(net_resolution, "656x368", "Multiples of 16. If it is increased, the accuracy usually increases. If it is decreased, the speed increases."); +- DEFINE_int32(num_scales, 1, "Number of scales to average."); +- DEFINE_double(scale_gap, 0.3, "Scale gap between scales. No effect unless num_scales>1. Initial scale is always 1. If you want to change the initial scale, you actually want to multiply the `net_resolution` by your desired initial scale."); +- DEFINE_bool(heatmaps_add_parts, false, "If true, it will add the body part heatmaps to the final op::Datum::poseHeatMaps array (program speed will decrease). Not required for our library, enable it only if you intend to process this information later. If more than one `add_heatmaps_X` flag is enabled, it will place then in sequential memory order: body parts + bkg + PAFs. It will follow the order on POSE_BODY_PART_MAPPING in `include/openpose/pose/poseParameters.hpp`."); +- DEFINE_bool(heatmaps_add_bkg, false, "Same functionality as `add_heatmaps_parts`, but adding the heatmap corresponding to background."); +- DEFINE_bool(heatmaps_add_PAFs, false, "Same functionality as `add_heatmaps_parts`, but adding the PAFs."); +5. OpenPose Face +- DEFINE_bool(face, false, "Enables face keypoint detection. It will share some parameters from the body pose, e.g. `model_folder`."); +- DEFINE_string(face_net_resolution, "368x368", "Multiples of 16. Analogous to `net_resolution` but applied to the face keypoint detector. 320x320 usually works fine while giving a substantial speed up when multiple faces on the image."); +6. OpenPose Hand +7. OpenPose Rendering +- DEFINE_int32(part_to_show, 0, "Part to show from the start."); +- DEFINE_bool(disable_blending, false, "If blending is enabled, it will merge the results with the original frame. If disabled, it will only display the results."); +8. OpenPose Rendering Pose +- DEFINE_bool(no_render_pose, false, "If false, it will fill both `outputData` and `cvOutputData` with the original image + desired part to be shown. If true, it will leave them empty."); +- DEFINE_double(alpha_pose, 0.6, "Blending factor (range 0-1) for the body part rendering. 1 will show it completely, 0 will hide it."); +- DEFINE_double(alpha_heatmap, 0.7, "Blending factor (range 0-1) between heatmap and original frame. 1 will only show the heatmap, 0 will only show the frame."); +9. OpenPose Rendering Face +- DEFINE_bool(no_render_face, false, "Analogous to `no_render_pose` but applied to the face keypoints and heat maps."); +- DEFINE_double(alpha_face, 0.6, "Blending factor (range 0-1) for the body part rendering. 1 will show it completely, 0 will hide it."); +- DEFINE_double(alpha_heatmap_face, 0.7, "Blending factor (range 0-1) between heatmap and original frame. 1 will only show the heatmap, 0 will only show the frame."); +10. Display +- DEFINE_bool(fullscreen, false, "Run in full-screen mode (press f during runtime to toggle)."); +- DEFINE_bool(process_real_time, false, "Enable to keep the original source frame rate (e.g. for video). If the processing time is too long, it will skip frames. If it is too fast, it will slow it down."); +- DEFINE_bool(no_gui_verbose, false, "Do not write text on output images on GUI (e.g. number of current frame and people). It does not affect the pose rendering."); +- DEFINE_bool(no_display, false, "Do not open a display window."); +11. Result Saving +- DEFINE_string(write_images, "", "Directory to write rendered frames in `write_images_format` image format."); +- DEFINE_string(write_images_format, "png", "File extension and format for `write_images`, e.g. png, jpg or bmp. Check the OpenCV function cv::imwrite for all compatible extensions."); +- DEFINE_string(write_video, "", "Full file path to write rendered frames in motion JPEG video format. It might fail if the final path does not finish in `.avi`. It internally uses cv::VideoWriter."); +- DEFINE_string(write_keypoint, "", "Directory to write the people body pose keypoint data. Desired format on `write_keypoint_format`."); +- DEFINE_string(write_keypoint_format, "yml", "File extension and format for `write_keypoint`: json, xml, yaml and yml. Json not available for OpenCV < 3.0, use `write_keypoint_json` instead."); +- DEFINE_string(write_keypoint_json, "", "Directory to write people pose data with *.json format, compatible with any OpenCV version."); +- DEFINE_string(write_coco_json, "", "Full file path to write people pose data with *.json COCO validation format."); +- DEFINE_string(write_heatmaps, "", "Directory to write heatmaps with *.png format. At least 1 `add_heatmaps_X` flag must be enabled."); +- DEFINE_string(write_heatmaps_format, "png", "File extension and format for `write_heatmaps`, analogous to `write_images_format`. Recommended `png` or any compressed and lossless format."); ## Multiple Scales Running at multiple scales might drastically slow down the speed, but it will increase the accuracy. Given the CNN input size (set with `net_resolution`), `num_scales` and `scale_gap` configure the number of scales to use and the gap between them, respectively. For instance, `--num_scales 3 --scale_gap 0.15` means using 3 scales at resolution: (1), (1-0.15) and (1-2*0.15) times the `net_resolution`. @@ -51,6 +78,36 @@ The following command will save all the body part heat maps, background heat map +## Some Important Configuration Flags +Please, in order to check all the real time pose demo options and their details, run `./build/examples/openpose/openpose.bin --help`. We describe here some of the most important ones. + +- `--face`: If enabled, it will also detect the faces on the image. Note that this will considerable slow down the performance and increse the required GPU memory. In addition, the greater number of people on the image, the slower OpenPose will be. +- `--video input.mp4`: Input video. If omitted, it will use the webcam. +- `--camera 3`: Choose webcam number (default: 0). If `--camera`, `--image_dir` and `--write_video` are omitted, it is equivalent to use `--camera 0`. +- `--image_dir path_to_images/`: Run on all images (jpg, png, bmp, etc.) in `path_to_images/`. You can test the program with the image directory `examples/media/`. +- `--write_video path.avi`: Render images with this prefix: `path.avi`. You can test the program with the example video `examples/media/video.avi`. +- `--write_images folder_path`: Render images on the folder `folder_path`. +- `--write_keypoint path/`: Output JSON, XML or YML files with the people pose data on the `path/` folder. +- `--process_real_time`: It might skip frames in order to keep the final output displaying frames on real time. +- `--disable_blending`: If selected, it will only render the pose skeleton or desired heat maps, while blocking the original background. Also related: `part_to_show`, `alpha_pose`, and `alpha_pose`. +- `--part_to_show`: Select the prediction channel to visualize (default: 0). 0 to visualize all the body parts, 1-18 for each body part heat map, 19 for the background heat map, 20 for all the body part heat maps together, 21 for all the PAFs, 22-69 for each body part pair PAF. +- `--no_display`: Display window not opened. Useful if there is no X server and/or to slightly speed up the processing if visual output is not required. +- `--num_gpu 2 --num_gpu_start 0`: Parallelize over this number of GPUs starting by the desired device id. Default is 1 and 0, respectively. +- `--num_scales 3 --scale_gap 0.15`: Use 3 scales, 1, (1-0.15), (1-0.15*2). Default is one scale. If you want to change the initial scale, you actually want to multiply your desired initial scale by the `net_resolution`. +- `--net_resolution 656x368 --resolution 1280x720`: For HD images and video (default values). +- `--net_resolution 496x368 --resolution 640x480`: For VGA images and video. +- `--model_pose MPI`: It will use MPI (15 body keypoints). Default: COCO (18 body keypoints). MPI is slightly faster. The variation `MPI_4_layers` sacrifies accuracy in order to further increase speed. +- `--logging_level 3`: Logging messages threshold, range [0,255]: 0 will output any message & 255 will output none. Current messages in the range [1-4], 1 for low priority messages and 4 for important ones. + + + +## Rendering Face without Pose +``` +./build/examples/openpose/openpose.bin --face --no_render_pose +``` + + + ## Example The following example runs the video `vid.mp4`, renders image frames on `output/result.avi`, and outputs JSON files as `output/%12d.json`, parallelizing over 2 GPUs: ``` diff --git a/doc/installation.md b/doc/installation.md index 004c3f5b..fc3fb1e5 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -181,6 +181,20 @@ bin\OpenPoseDemo.exe --image_dir examples/media/ windows_project\x64\Release\OpenPoseDemo.exe --image_dir examples/media/ ``` +**4. Body Pose and Face Keypoint Detector (e.g. on Video)** +``` +# Ubuntu +./build/examples/openpose/openpose.bin --video examples/media/video.avi --face +``` +``` +:: Windows - Demo +bin\OpenPoseDemo.exe --video examples/media/video.avi --face +``` +``` +:: Windows - Library +windows_project\x64\Release\OpenPoseDemo.exe --video examples/media/video.avi --face +``` + The visual GUI should show the original image with the poses blended on it, similarly to the pose of this gif:

diff --git a/doc/library_overview.md b/doc/library_overview.md index 1b09fd19..7dd47775 100644 --- a/doc/library_overview.md +++ b/doc/library_overview.md @@ -180,7 +180,7 @@ The human body pose detection is wrapped into the `WPoseExtractor` worker and Currently, only `PoseExtractorCaffe` is implemented, which uses the Caffe framework. We might add other famous frameworks later (e.g. Torch or TensorFlow). If you compile our library with any other framework, please email us or make a pull request! We are really interested in adding any other Deep Net framework, and the code is mostly prepared for it. Just create the equivalent `PoseExtractorDesiredFramework` and make the pull request! #### Constructor -In order to be initialized, `PoseExtractorCaffe` has the following constructor and parameters: `PoseExtractorCaffe(const cv::Size& netInputSize, const cv::Size& netOutputSize, const cv::Size& outputSize, const int scaleNumber, const double scaleGap, const PoseModel poseModel, const std::string& modelsFolder, const int gpuId)`. +In order to be initialized, `PoseExtractorCaffe` has the following constructor and parameters: `PoseExtractorCaffe(const Point& netInputSize, const Point& netOutputSize, const Point& outputSize, const int scaleNumber, const double scaleGap, const PoseModel poseModel, const std::string& modelsFolder, const int gpuId)`. 1. `netInputSize` is the resolution of the first layer of the deep net. I.e., the frames given to this class must have that size. @@ -199,7 +199,7 @@ In order to be initialized, `PoseExtractorCaffe` has the following constructor a #### Detect Human Pose In order to detect the human pose: -1. First run the deep net over the desired target image, by using `forwardPass(const Array& inputNetData, const cv::Size& inputDataSize)`. `inputNetData` is the input image scaled to `netInputSize`, while `inputDataSize` indicates the original frame resolution before being rescaled to `netInputSize` (this is required given that we resize the images keeping the original aspect ratio). +1. First run the deep net over the desired target image, by using `forwardPass(const Array& inputNetData, const Point& inputDataSize)`. `inputNetData` is the input image scaled to `netInputSize`, while `inputDataSize` indicates the original frame resolution before being rescaled to `netInputSize` (this is required given that we resize the images keeping the original aspect ratio). 2. After, you can choose either to get: 1. The people pose as a op::Array: `Array getPose()`. @@ -213,13 +213,13 @@ Due to performance reasons, we only copy the people pose data given by `getPose( After estimating the pose, you usually desired to visualize it. `PoseRenderer` does this work for you. #### Constructor -In order to be initialized, `PoseRenderer` has the following constructor and parameters: `PoseRenderer(const cv::Size& netOutputSize, const cv::Size& outputSize, const PoseModel poseModel, const std::shared_ptr& poseExtractor, const float alphaPose, const float alphaHeatmap)`. +In order to be initialized, `PoseRenderer` has the following constructor and parameters: `PoseRenderer(const Point& netOutputSize, const Point& outputSize, const PoseModel poseModel, const std::shared_ptr& poseExtractor, const float alphaKeypoint, const float alphaHeatMap)`. 1. `netOutputSize`, `outputSize` and `poseModel` are the same as the ones used for `PoseExtractorCaffe`. 2. `poseExtractor` is the pose extractor used previously. It is only used for heatmap and PAFs rendering, since the GPU data is not copied to `op::Datum` for performance purposes. If any of the heatmaps are gonna be rendered, `PoseRenderer` must be placed in the same thread as `PoseExtractor`. Otherwise, it will throw a runtime exception. -3. `alphaPose` and `alphaHeatMap` controls the blending coefficient between original frame and rendered pose or heatmap/PAF respectively. A value `alphaPose = 1` will render the pose with no transparency at all, while `alphaPose = 0` will not be visible. In addition, `alphaHeatMap = 1` would only show the heatmap, while `alphaHeatMap = 0` would only show the original frame. +3. `alphaKeypoint` and `alphaHeatMap` controls the blending coefficient between original frame and rendered pose or heatmap/PAF respectively. A value `alphaKeypoint = 1` will render the pose with no transparency at all, while `alphaKeypoint = 0` will not be visible. In addition, `alphaHeatMap = 1` would only show the heatmap, while `alphaHeatMap = 0` would only show the original frame. #### Render Human Pose In order to render the detected human pose, run `std::pair renderPose(Array& outputData, const Array& pose, const double scaleNetToOutput)`. diff --git a/doc/media/keypoints_face.png b/doc/media/keypoints_face.png new file mode 100644 index 00000000..4af4f179 Binary files /dev/null and b/doc/media/keypoints_face.png differ diff --git a/doc/media/keypoints_pose.png b/doc/media/keypoints_pose.png new file mode 100644 index 00000000..10dd473c Binary files /dev/null and b/doc/media/keypoints_pose.png differ diff --git a/doc/media/paf_heat_maps.png b/doc/media/paf_heat_maps.png index 90d40443..ca2ebc45 100644 Binary files a/doc/media/paf_heat_maps.png and b/doc/media/paf_heat_maps.png differ diff --git a/doc/release_notes.md b/doc/release_notes.md new file mode 100644 index 00000000..1def04c5 --- /dev/null +++ b/doc/release_notes.md @@ -0,0 +1,43 @@ +OpenPose Library - Release Notes +==================================== + + + +## OpenPose 1.0.0rc1 +1. Initial version, main functionality: + 1. Body keypoint detection and rendering on Ubuntu 14 and 16. + 2. It can read an image directory, video or webcam. + 3. It can display the results or storing them on disk. + + + +## OpenPose 1.0.0rc2 +1. Main improvements: + 1. Rendering max resolution from 720p to >32k images. + 2. Highly improved documentation. +2. Functions or paremeters renamed: + 1. Demo renamed from rtpose to openpose. +3. Main bugs fixed: + 1. Demo uses exec instead of start, so it works with more OpenCV custom compiled versions. + + + +## OpenPose 1.0.0rc3 +1. Main improvements: + 1. Added face keypoint detection. + 2. Added Windows 10 compatibily. + 3. Auto-detection of the number of GPUs. + 4. MPI visualization more similar to COCO one. + 5. Rendering max resolution from 720p to >32k images. + 6. GUI info adder working when the worker TDatum has more than 1 Datum. + 7. It prints out the error description before throwing the exception (so that it is writen on the Windows cmd). + 8. Highly improved documentation. +2. Functions or paremeters renamed: + 1. Flag `write_pose` renamed as `write_keypoint` and it also applies to face and/or hands. + 2. Flag `write_pose_json` renamed as `write_keypoint_json` and it also applies to face and/or hands. + 3. Flag `write_pose_format` renamed as `write_keypoint_format` and it also applies to face and/or hands. + 4. PoseSaver and its JSON variant renamed as KeypointSaver. + 5. PoseJsonCocoSaver renamed as CocoJsonSaver. +3. Main bugs fixed: + 1. All visualization functions moved to same thread, so it works with most OpenCV custom compiled versions. + 2. Fixed error on debug mode: `Too many resources requested for launch`. diff --git a/examples/openpose/openpose.cpp b/examples/openpose/openpose.cpp index 3bc81549..02c2193a 100755 --- a/examples/openpose/openpose.cpp +++ b/examples/openpose/openpose.cpp @@ -2,11 +2,12 @@ // If the user wants to learn to use the OpenPose library, we highly recommend to start with the `examples/tutorial_*/` folders. // This example summarizes all the funcitonality of the OpenPose library: // 1. Read folder of images / video / webcam (`producer` module) - // 2. Extract and render pose / heatmap / PAF of that image (`pose` module) - // 3. Save the results on disc (`filestream` module) - // 4. Display the rendered pose (`gui` 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 disc (`filestream` module) + // 5. Display the rendered pose (`gui` module) // Everything in a multi-thread scenario (`thread` module) - // Points 2 to 4 are included in the `wrapper` 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 class that the `pose` module needs @@ -21,11 +22,9 @@ #include // std::string #include // std::this_thread #include // std::vector -// OpenCV dependencies -#include // cv::Mat & cv::Size // Other 3rdpary depencencies #include // DEFINE_bool, DEFINE_int32, DEFINE_int64, DEFINE_uint64, DEFINE_double, DEFINE_string -#include // google::InitGoogleLogging, CHECK, CHECK_EQ, LOG, VLOG, ... +#include // google::InitGoogleLogging // OpenPose dependencies // Option a) Importing all modules @@ -33,6 +32,7 @@ // Option b) Manually importing the desired modules. Recommended if you only intend to use a few modules. // #include // #include +// #include // #include // #include // #include @@ -41,13 +41,9 @@ // #include // #include -// Uncomment to avoid needing `op::` before each class and function of the OpenPose library. Analogously for OpenCV and the standard C++ library -// using namespace op; -// using namespace cv; -// using namespace std; - -// Gflags in the command line terminal. Check all the options by adding the flag `--help`, e.g. `openpose.bin --help`. -// Note: This command will show you flags for several files. Check only the flags for the file you are checking. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. +// See all the available parameter options withe the `--help` flag. E.g. `./build/examples/openpose/openpose.bin --help`. +// Note: This command will show you flags for other unnecessary 3rdparty files. Check only the flags for the OpenPose +// executable. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. // Debugging DEFINE_int32(logging_level, 3, "The logging level. Integer in the range [0, 255]. 0 will output any log() message, while 255 will not output any." " Current OpenPose library messages are in the range 0-4: 1 for low priority messages and 4 for important ones."); @@ -62,47 +58,59 @@ DEFINE_bool(frame_flip, false, "Flip/mirror each frame DEFINE_int32(frame_rotate, 0, "Rotate each frame, 4 possible values: 0, 90, 180, 270."); DEFINE_bool(frames_repeat, false, "Repeat frames when finished."); // OpenPose -DEFINE_string(model_pose, "COCO", "Model to be used (e.g. COCO, MPI, MPI_4_layers)."); DEFINE_string(model_folder, "models/", "Folder where the pose models (COCO and MPI) are located."); -DEFINE_string(net_resolution, "656x368", "Multiples of 16."); DEFINE_string(resolution, "1280x720", "The image resolution (display and output). Use \"-1x-1\" to force the program to use the default images resolution."); -DEFINE_int32(num_gpu, 1, "The number of GPU devices to use."); +DEFINE_int32(num_gpu, -1, "The number of GPU devices to use. If negative, it will use all the available GPUs in your machine."); DEFINE_int32(num_gpu_start, 0, "GPU device start number."); +DEFINE_int32(keypoint_scale, 0, "Scaling of the (x,y) coordinates of the final pose data array, i.e. the scale of the (x,y) coordinates that will be saved" + " with the `write_keypoint` & `write_keypoint_json` flags. Select `0` to scale it to the original source resolution, `1`to scale" + " it to the net output size (set with `net_resolution`), `2` to scale it to the final output size (set with `resolution`)," + " `3` to scale it in the range [0,1], and 4 for range [-1,1]. Non related with `num_scales` and `scale_gap`."); +// OpenPose Body Pose +DEFINE_string(model_pose, "COCO", "Model to be used (e.g. COCO, MPI, MPI_4_layers)."); +DEFINE_string(net_resolution, "656x368", "Multiples of 16. If it is increased, the accuracy usually increases. If it is decreased, the speed increases."); DEFINE_int32(num_scales, 1, "Number of scales to average."); DEFINE_double(scale_gap, 0.3, "Scale gap between scales. No effect unless num_scales>1. Initial scale is always 1. If you want to change the initial scale," " you actually want to multiply the `net_resolution` by your desired initial scale."); -DEFINE_int32(scale_mode, 0, "Scaling of the (x,y) coordinates of the final pose data array (op::Datum::pose), i.e. the scale of the (x,y) coordinates that" - " will be saved with the `write_pose` & `write_pose_json` flags. Select `0` to scale it to the original source resolution, `1`" - " to scale it to the net output size (set with `net_resolution`), `2` to scale it to the final output size (set with " - " `resolution`), `3` to scale it in the range [0,1], and 4 for range [-1,1]. Non related with `num_scales` and `scale_gap`."); DEFINE_bool(heatmaps_add_parts, false, "If true, it will add the body part heatmaps to the final op::Datum::poseHeatMaps array (program speed will decrease). Not" " required for our library, enable it only if you intend to process this information later. If more than one `add_heatmaps_X`" " flag is enabled, it will place then in sequential memory order: body parts + bkg + PAFs. It will follow the order on" " POSE_BODY_PART_MAPPING in `include/openpose/pose/poseParameters.hpp`."); DEFINE_bool(heatmaps_add_bkg, false, "Same functionality as `add_heatmaps_parts`, but adding the heatmap corresponding to background."); DEFINE_bool(heatmaps_add_PAFs, false, "Same functionality as `add_heatmaps_parts`, but adding the PAFs."); +// OpenPose Face +DEFINE_bool(face, false, "Enables face keypoint detection. It will share some parameters from the body pose, e.g. `model_folder`."); +DEFINE_string(face_net_resolution, "368x368", "Multiples of 16. Analogous to `net_resolution` but applied to the face keypoint detector. 320x320 usually works fine" + " while giving a substantial speed up when multiple faces on the image."); +// OpenPose Hand // OpenPose Rendering -DEFINE_bool(no_render_output, false, "If false, it will fill both `outputData` and `cvOutputData` with the original image + desired part to be shown." - " If true, it will leave them empty."); DEFINE_int32(part_to_show, 0, "Part to show from the start."); DEFINE_bool(disable_blending, false, "If blending is enabled, it will merge the results with the original frame. If disabled, it will only display the results."); +// OpenPose Rendering Pose +DEFINE_bool(no_render_pose, false, "If false, it will fill both `outputData` and `cvOutputData` with the original image + desired part to be shown." + " If true, it will leave them empty."); DEFINE_double(alpha_pose, 0.6, "Blending factor (range 0-1) for the body part rendering. 1 will show it completely, 0 will hide it."); DEFINE_double(alpha_heatmap, 0.7, "Blending factor (range 0-1) between heatmap and original frame. 1 will only show the heatmap, 0 will only show the frame."); -// Consumer +// OpenPose Rendering Face +DEFINE_bool(no_render_face, false, "Analogous to `no_render_pose` but applied to the face keypoints and heat maps."); +DEFINE_double(alpha_face, 0.6, "Blending factor (range 0-1) for the body part rendering. 1 will show it completely, 0 will hide it."); +DEFINE_double(alpha_heatmap_face, 0.7, "Blending factor (range 0-1) between heatmap and original frame. 1 will only show the heatmap, 0 will only show the frame."); +// Display DEFINE_bool(fullscreen, false, "Run in full-screen mode (press f during runtime to toggle)."); DEFINE_bool(process_real_time, false, "Enable to keep the original source frame rate (e.g. for video). If the processing time is too long, it will skip frames. If it is" " too fast, it will slow it down."); DEFINE_bool(no_gui_verbose, false, "Do not write text on output images on GUI (e.g. number of current frame and people). It does not affect the pose rendering."); DEFINE_bool(no_display, false, "Do not open a display window."); +// Result Saving DEFINE_string(write_images, "", "Directory to write rendered frames in `write_images_format` image format."); DEFINE_string(write_images_format, "png", "File extension and format for `write_images`, e.g. png, jpg or bmp. Check the OpenCV function cv::imwrite" " for all compatible extensions."); DEFINE_string(write_video, "", "Full file path to write rendered frames in motion JPEG video format. It might fail if the final path does" " not finish in `.avi`. It internally uses cv::VideoWriter."); -DEFINE_string(write_pose, "", "Directory to write the people pose data. Desired format on `write_pose_format`."); -DEFINE_string(write_pose_format, "yml", "File extension and format for `write_pose`: json, xml, yaml and yml. Json not available for OpenCV < 3.0," - " use `write_pose_json` instead."); -DEFINE_string(write_pose_json, "", "Directory to write people pose data with *.json format, compatible with any OpenCV version."); +DEFINE_string(write_keypoint, "", "Directory to write the people body pose keypoint data. Desired format on `write_keypoint_format`."); +DEFINE_string(write_keypoint_format, "yml", "File extension and format for `write_keypoint`: json, xml, yaml and yml. Json not available for OpenCV < 3.0," + " use `write_keypoint_json` instead."); +DEFINE_string(write_keypoint_json, "", "Directory to write people pose data with *.json format, compatible with any OpenCV version."); DEFINE_string(write_coco_json, "", "Full file path to write people pose data with *.json COCO validation format."); DEFINE_string(write_heatmaps, "", "Directory to write heatmaps with *.png format. At least 1 `add_heatmaps_X` flag must be enabled."); DEFINE_string(write_heatmaps_format, "png", "File extension and format for `write_heatmaps`, analogous to `write_images_format`. Recommended `png` or any compressed and" @@ -124,18 +132,18 @@ op::PoseModel gflagToPoseModel(const std::string& poseModeString) } } -op::ScaleMode gflagToScaleMode(const int scaleMode) +op::ScaleMode gflagToScaleMode(const int keypointScale) { op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); - if (scaleMode == 0) + if (keypointScale == 0) return op::ScaleMode::InputResolution; - else if (scaleMode == 1) + else if (keypointScale == 1) return op::ScaleMode::NetOutputResolution; - else if (scaleMode == 2) + else if (keypointScale == 2) return op::ScaleMode::OutputResolution; - else if (scaleMode == 3) + else if (keypointScale == 3) return op::ScaleMode::ZeroToOne; - else if (scaleMode == 4) + else if (keypointScale == 4) return op::ScaleMode::PlusMinusOne; else { @@ -166,7 +174,7 @@ op::ProducerType gflagsToProducerType(const std::string& imageDirectory, const s return op::ProducerType::Webcam; } -std::shared_ptr gflagsToProducer(const std::string& imageDirectory, const std::string& videoPath, const int webcamIndex, const cv::Size webcamResolution) +std::shared_ptr gflagsToProducer(const std::string& imageDirectory, const std::string& videoPath, const int webcamIndex, const op::Point webcamResolution) { op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); const auto type = gflagsToProducerType(imageDirectory, videoPath, webcamIndex); @@ -198,31 +206,35 @@ std::vector gflagToHeatMaps(const bool heatmaps_add_parts, cons } // Google flags into program variables -std::tuple, op::PoseModel, op::ScaleMode, std::vector> gflagsToOpParameters() +std::tuple, op::Point, op::Point, op::Point, std::shared_ptr, op::PoseModel, op::ScaleMode, std::vector> gflagsToOpParameters() { op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); // cameraFrameSize - cv::Size cameraFrameSize; - auto nRead = sscanf(FLAGS_camera_resolution.c_str(), "%dx%d", &cameraFrameSize.width, &cameraFrameSize.height); + op::Point cameraFrameSize; + auto nRead = sscanf(FLAGS_camera_resolution.c_str(), "%dx%d", &cameraFrameSize.x, &cameraFrameSize.y); op::checkE(nRead, 2, "Error, camera resolution format (" + FLAGS_camera_resolution + ") invalid, should be e.g., 1280x720", __LINE__, __FUNCTION__, __FILE__); // outputSize - cv::Size outputSize; - nRead = sscanf(FLAGS_resolution.c_str(), "%dx%d", &outputSize.width, &outputSize.height); + op::Point outputSize; + nRead = sscanf(FLAGS_resolution.c_str(), "%dx%d", &outputSize.x, &outputSize.y); op::checkE(nRead, 2, "Error, resolution format (" + FLAGS_resolution + ") invalid, should be e.g., 960x540 ", __LINE__, __FUNCTION__, __FILE__); // netInputSize - cv::Size netInputSize; - nRead = sscanf(FLAGS_net_resolution.c_str(), "%dx%d", &netInputSize.width, &netInputSize.height); + op::Point netInputSize; + nRead = sscanf(FLAGS_net_resolution.c_str(), "%dx%d", &netInputSize.x, &netInputSize.y); op::checkE(nRead, 2, "Error, net resolution format (" + FLAGS_net_resolution + ") invalid, should be e.g., 656x368 (multiples of 16)", __LINE__, __FUNCTION__, __FILE__); + // faceNetInputSize + op::Point faceNetInputSize; + nRead = sscanf(FLAGS_face_net_resolution.c_str(), "%dx%d", &faceNetInputSize.x, &faceNetInputSize.y); + op::checkE(nRead, 2, "Error, face net resolution format (" + FLAGS_face_net_resolution + ") invalid, should be e.g., 368x368 (multiples of 16)", __LINE__, __FUNCTION__, __FILE__); // producerType const auto producerSharedPtr = gflagsToProducer(FLAGS_image_dir, FLAGS_video, FLAGS_camera, cameraFrameSize); // poseModel const auto poseModel = gflagToPoseModel(FLAGS_model_pose); - // scaleMode - const auto scaleMode = gflagToScaleMode(FLAGS_scale_mode); + // keypointScale + const auto keypointScale = gflagToScaleMode(FLAGS_keypoint_scale); // heatmaps to add const auto heatMapTypes = gflagToHeatMaps(FLAGS_heatmaps_add_parts, FLAGS_heatmaps_add_bkg, FLAGS_heatmaps_add_PAFs); // Return - return std::make_tuple(cameraFrameSize, outputSize, netInputSize, producerSharedPtr, poseModel, scaleMode, heatMapTypes); + return std::make_tuple(cameraFrameSize, outputSize, netInputSize, faceNetInputSize, producerSharedPtr, poseModel, keypointScale, heatMapTypes); } int opRealTimePoseDemo() @@ -236,35 +248,41 @@ int opRealTimePoseDemo() const auto timerBegin = std::chrono::high_resolution_clock::now(); // Applying user defined configuration - cv::Size cameraFrameSize; - cv::Size outputSize; - cv::Size netInputSize; + op::Point cameraFrameSize; + op::Point outputSize; + op::Point netInputSize; + op::Point faceNetInputSize; std::shared_ptr producerSharedPtr; op::PoseModel poseModel; - op::ScaleMode scaleMode; + op::ScaleMode keypointScale; std::vector heatMapTypes; - std::tie(cameraFrameSize, outputSize, netInputSize, producerSharedPtr, poseModel, scaleMode, heatMapTypes) = gflagsToOpParameters(); + std::tie(cameraFrameSize, outputSize, netInputSize, faceNetInputSize, producerSharedPtr, poseModel, keypointScale, heatMapTypes) = gflagsToOpParameters(); // OpenPose wrapper op::log("Configuring OpenPose wrapper.", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); op::Wrapper> opWrapper; - const op::WrapperStructPose wrapperStructPose{netInputSize, outputSize, scaleMode, FLAGS_num_gpu, FLAGS_num_gpu_start, FLAGS_num_scales, (float)FLAGS_scale_gap, - !FLAGS_no_render_output, poseModel, !FLAGS_disable_blending, (float)FLAGS_alpha_pose, (float)FLAGS_alpha_heatmap, + // Pose configuration (use WrapperStructPose{} for default and recommended configuration) + const op::WrapperStructPose wrapperStructPose{netInputSize, outputSize, keypointScale, FLAGS_num_gpu, FLAGS_num_gpu_start, FLAGS_num_scales, (float)FLAGS_scale_gap, + !FLAGS_no_render_pose, poseModel, !FLAGS_disable_blending, (float)FLAGS_alpha_pose, (float)FLAGS_alpha_heatmap, FLAGS_part_to_show, FLAGS_model_folder, heatMapTypes, op::ScaleMode::UnsignedChar}; + // (Experimental, function and class names might change in next versions) Face configuration (use op::WrapperStructFace{} to disable it) + const op::WrapperStructFace wrapperStructFace{FLAGS_face, faceNetInputSize, !FLAGS_no_render_face, (float)FLAGS_alpha_face, (float)FLAGS_alpha_heatmap_face}; + // (Experimental, function and class names might change in next versions) Hand configuration (use op::WrapperStructFace{} to disable it) + const op::experimental::WrapperStructHand wrapperStructHand{false}; + // Producer (use default to disable any input) const op::WrapperStructInput wrapperStructInput{producerSharedPtr, FLAGS_frame_first, FLAGS_frame_last, FLAGS_process_real_time, FLAGS_frame_flip, FLAGS_frame_rotate, FLAGS_frames_repeat}; - const op::WrapperStructOutput wrapperStructOutput{!FLAGS_no_display, !FLAGS_no_gui_verbose, FLAGS_fullscreen, FLAGS_write_pose, op::stringToDataFormat(FLAGS_write_pose_format), - FLAGS_write_pose_json, FLAGS_write_coco_json, FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, - FLAGS_write_heatmaps, FLAGS_write_heatmaps_format}; - // Pose configuration (use WrapperStructPose{} for default and recommended configuration) - // Producer (use default to disable any input) // Consumer (comment or use default argument to disable any output) - opWrapper.configure(wrapperStructPose, wrapperStructInput, wrapperStructOutput); + const op::WrapperStructOutput wrapperStructOutput{!FLAGS_no_display, !FLAGS_no_gui_verbose, FLAGS_fullscreen, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format), + FLAGS_write_keypoint_json, FLAGS_write_coco_json, FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, + FLAGS_write_heatmaps, FLAGS_write_heatmaps_format}; + // Configure wrapper + opWrapper.configure(wrapperStructPose, wrapperStructFace, wrapperStructHand, wrapperStructInput, wrapperStructOutput); // Set to single-thread running (e.g. for debugging purposes) // opWrapper.disableMultiThreading(); // Start processing - // Two different ways of running the program on multithread enviroment + // Two different ways of running the program on multithread environment op::log("Starting thread(s)", op::Priority::Max); // Option a) Recommended - Also using the main thread (this thread) for processing (it saves 1 thread) // Start, run & stop threads diff --git a/examples/tutorial_pose/1_extract_from_image.cpp b/examples/tutorial_pose/1_extract_from_image.cpp index ddc7d43a..c23fb89c 100644 --- a/examples/tutorial_pose/1_extract_from_image.cpp +++ b/examples/tutorial_pose/1_extract_from_image.cpp @@ -10,7 +10,7 @@ // 3rdpary depencencies #include // DEFINE_bool, DEFINE_int32, DEFINE_int64, DEFINE_uint64, DEFINE_double, DEFINE_string -#include // google::InitGoogleLogging, CHECK, CHECK_EQ, LOG, VLOG, ... +#include // google::InitGoogleLogging // OpenPose dependencies #include #include @@ -18,8 +18,9 @@ #include #include -// Gflags in the command line terminal. Check all the options by adding the flag `--help`, e.g. `openpose.bin --help`. -// Note: This command will show you flags for several files. Check only the flags for the file you are checking. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. +// See all the available parameter options withe the `--help` flag. E.g. `./build/examples/openpose/openpose.bin --help`. +// Note: This command will show you flags for other unnecessary 3rdparty files. Check only the flags for the OpenPose +// executable. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. // Debugging DEFINE_int32(logging_level, 3, "The logging level. Integer in the range [0, 255]. 0 will output any log() message, while 255 will not output any." " Current OpenPose library messages are in the range 0-4: 1 for low priority messages and 4 for important ones."); @@ -28,7 +29,7 @@ DEFINE_string(image_path, "examples/media/COCO_val2014_00000000019 // OpenPose DEFINE_string(model_pose, "COCO", "Model to be used (e.g. COCO, MPI, MPI_4_layers)."); DEFINE_string(model_folder, "models/", "Folder where the pose models (COCO and MPI) are located."); -DEFINE_string(net_resolution, "656x368", "Multiples of 16."); +DEFINE_string(net_resolution, "656x368", "Multiples of 16. If it is increased, the accuracy usually increases. If it is decreased, the speed increases."); DEFINE_string(resolution, "1280x720", "The image resolution (display). Use \"-1x-1\" to force the program to use the default images resolution."); DEFINE_int32(num_gpu_start, 0, "GPU device start number."); DEFINE_double(scale_gap, 0.3, "Scale gap between scales. No effect unless num_scales>1. Initial scale is always 1. If you want to change the initial scale, " @@ -54,16 +55,16 @@ op::PoseModel gflagToPoseModel(const std::string& poseModeString) } // Google flags into program variables -std::tuple gflagsToOpParameters() +std::tuple, op::Point, op::Point, op::PoseModel> gflagsToOpParameters() { op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); // outputSize - cv::Size outputSize; - auto nRead = sscanf(FLAGS_resolution.c_str(), "%dx%d", &outputSize.width, &outputSize.height); + op::Point outputSize; + auto nRead = sscanf(FLAGS_resolution.c_str(), "%dx%d", &outputSize.x, &outputSize.y); op::checkE(nRead, 2, "Error, resolution format (" + FLAGS_resolution + ") invalid, should be e.g., 960x540 ", __LINE__, __FUNCTION__, __FILE__); // netInputSize - cv::Size netInputSize; - nRead = sscanf(FLAGS_net_resolution.c_str(), "%dx%d", &netInputSize.width, &netInputSize.height); + op::Point netInputSize; + nRead = sscanf(FLAGS_net_resolution.c_str(), "%dx%d", &netInputSize.x, &netInputSize.y); op::checkE(nRead, 2, "Error, net resolution format (" + FLAGS_net_resolution + ") invalid, should be e.g., 656x368 (multiples of 16)", __LINE__, __FUNCTION__, __FILE__); // netOutputSize const auto netOutputSize = netInputSize; @@ -89,9 +90,9 @@ int openPoseTutorialPose1() 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); // Step 2 - Read Google flags (user defined configuration) - cv::Size outputSize; - cv::Size netInputSize; - cv::Size netOutputSize; + op::Point outputSize; + op::Point netInputSize; + op::Point netOutputSize; op::PoseModel poseModel; std::tie(outputSize, netInputSize, netOutputSize, poseModel) = gflagsToOpParameters(); // Step 3 - Initialize all required classes @@ -101,7 +102,7 @@ int openPoseTutorialPose1() FLAGS_model_folder, FLAGS_num_gpu_start}; op::PoseRenderer poseRenderer{netOutputSize, outputSize, poseModel, nullptr, (float)FLAGS_alpha_pose}; op::OpOutputToCvMat opOutputToCvMat{outputSize}; - const cv::Size windowedSize = outputSize; + const op::Point windowedSize = outputSize; op::FrameDisplayer frameDisplayer{windowedSize, "OpenPose Tutorial - Example 1"}; // Step 4 - Initialize resources on desired thread (in this case single thread, i.e. we init resources here) poseExtractorCaffe.initializationOnThread(); @@ -117,11 +118,11 @@ int openPoseTutorialPose1() double scaleInputToOutput; op::Array outputArray; std::tie(scaleInputToOutput, outputArray) = cvMatToOpOutput.format(inputImage); - // Step 3 - Estimate poseKeyPoints - poseExtractorCaffe.forwardPass(netInputArray, inputImage.size()); - const auto poseKeyPoints = poseExtractorCaffe.getPoseKeyPoints(); - // Step 4 - Render poseKeyPoints - poseRenderer.renderPose(outputArray, poseKeyPoints); + // Step 3 - Estimate poseKeypoints + poseExtractorCaffe.forwardPass(netInputArray, {inputImage.cols, inputImage.rows}); + const auto poseKeypoints = poseExtractorCaffe.getPoseKeypoints(); + // Step 4 - Render poseKeypoints + poseRenderer.renderPose(outputArray, poseKeypoints); // Step 5 - OpenPose output format to cv::Mat auto outputImage = opOutputToCvMat.formatToCvMat(outputArray); diff --git a/examples/tutorial_pose/2_extract_pose_or_heatmat_from_image.cpp b/examples/tutorial_pose/2_extract_pose_or_heatmat_from_image.cpp index 0c429160..52fadcaf 100644 --- a/examples/tutorial_pose/2_extract_pose_or_heatmat_from_image.cpp +++ b/examples/tutorial_pose/2_extract_pose_or_heatmat_from_image.cpp @@ -10,7 +10,7 @@ // 3rdpary depencencies #include // DEFINE_bool, DEFINE_int32, DEFINE_int64, DEFINE_uint64, DEFINE_double, DEFINE_string -#include // google::InitGoogleLogging, CHECK, CHECK_EQ, LOG, VLOG, ... +#include // google::InitGoogleLogging // OpenPose dependencies #include #include @@ -18,8 +18,9 @@ #include #include -// Gflags in the command line terminal. Check all the options by adding the flag `--help`, e.g. `openpose.bin --help`. -// Note: This command will show you flags for several files. Check only the flags for the file you are checking. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. +// See all the available parameter options withe the `--help` flag. E.g. `./build/examples/openpose/openpose.bin --help`. +// Note: This command will show you flags for other unnecessary 3rdparty files. Check only the flags for the OpenPose +// executable. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. // Debugging DEFINE_int32(logging_level, 3, "The logging level. Integer in the range [0, 255]. 0 will output any log() message, while 255 will not output any." " Current OpenPose library messages are in the range 0-4: 1 for low priority messages and 4 for important ones."); @@ -28,7 +29,7 @@ DEFINE_string(image_path, "examples/media/COCO_val2014_00000000019 // OpenPose DEFINE_string(model_pose, "COCO", "Model to be used (e.g. COCO, MPI, MPI_4_layers)."); DEFINE_string(model_folder, "models/", "Folder where the pose models (COCO and MPI) are located."); -DEFINE_string(net_resolution, "656x368", "Multiples of 16."); +DEFINE_string(net_resolution, "656x368", "Multiples of 16. If it is increased, the accuracy usually increases. If it is decreased, the speed increases."); DEFINE_string(resolution, "1280x720", "The image resolution (display). Use \"-1x-1\" to force the program to use the default images resolution."); DEFINE_int32(num_gpu_start, 0, "GPU device start number."); DEFINE_double(scale_gap, 0.3, "Scale gap between scales. No effect unless num_scales>1. Initial scale is always 1. If you want to change the initial scale, " @@ -56,16 +57,16 @@ op::PoseModel gflagToPoseModel(const std::string& poseModeString) } // Google flags into program variables -std::tuple gflagsToOpParameters() +std::tuple, op::Point, op::Point, op::PoseModel> gflagsToOpParameters() { op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); // outputSize - cv::Size outputSize; - auto nRead = sscanf(FLAGS_resolution.c_str(), "%dx%d", &outputSize.width, &outputSize.height); + op::Point outputSize; + auto nRead = sscanf(FLAGS_resolution.c_str(), "%dx%d", &outputSize.x, &outputSize.y); op::checkE(nRead, 2, "Error, resolution format (" + FLAGS_resolution + ") invalid, should be e.g., 960x540 ", __LINE__, __FUNCTION__, __FILE__); // netInputSize - cv::Size netInputSize; - nRead = sscanf(FLAGS_net_resolution.c_str(), "%dx%d", &netInputSize.width, &netInputSize.height); + op::Point netInputSize; + nRead = sscanf(FLAGS_net_resolution.c_str(), "%dx%d", &netInputSize.x, &netInputSize.y); op::checkE(nRead, 2, "Error, net resolution format (" + FLAGS_net_resolution + ") invalid, should be e.g., 656x368 (multiples of 16)", __LINE__, __FUNCTION__, __FILE__); // netOutputSize const auto netOutputSize = netInputSize; @@ -91,9 +92,9 @@ int openPoseTutorialPose2() 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); // Step 2 - Read Google flags (user defined configuration) - cv::Size outputSize; - cv::Size netInputSize; - cv::Size netOutputSize; + op::Point outputSize; + op::Point netInputSize; + op::Point netOutputSize; op::PoseModel poseModel; std::tie(outputSize, netInputSize, netOutputSize, poseModel) = gflagsToOpParameters(); // Step 3 - Initialize all required classes @@ -105,7 +106,7 @@ int openPoseTutorialPose2() op::PoseRenderer poseRenderer{netOutputSize, outputSize, poseModel, poseExtractorPtr, (float)FLAGS_alpha_pose, (float)FLAGS_alpha_heatmap}; poseRenderer.setElementToRender(FLAGS_part_to_show); op::OpOutputToCvMat opOutputToCvMat{outputSize}; - const cv::Size windowedSize = outputSize; + const op::Point windowedSize = outputSize; op::FrameDisplayer frameDisplayer{windowedSize, "OpenPose Tutorial - Example 2"}; // Step 4 - Initialize resources on desired thread (in this case single thread, i.e. we init resources here) poseExtractorPtr->initializationOnThread(); @@ -121,12 +122,12 @@ int openPoseTutorialPose2() double scaleInputToOutput; op::Array outputArray; std::tie(scaleInputToOutput, outputArray) = cvMatToOpOutput.format(inputImage); - // Step 3 - Estimate poseKeyPoints - poseExtractorPtr->forwardPass(netInputArray, inputImage.size()); - const auto poseKeyPoints = poseExtractorPtr->getPoseKeyPoints(); + // Step 3 - Estimate poseKeypoints + poseExtractorPtr->forwardPass(netInputArray, {inputImage.cols, inputImage.rows}); + const auto poseKeypoints = poseExtractorPtr->getPoseKeypoints(); const auto scaleNetToOutput = poseExtractorPtr->getScaleNetToOutput(); // Step 4 - Render pose - poseRenderer.renderPose(outputArray, poseKeyPoints, scaleNetToOutput); + poseRenderer.renderPose(outputArray, poseKeypoints, scaleNetToOutput); // Step 5 - OpenPose output format to cv::Mat auto outputImage = opOutputToCvMat.formatToCvMat(outputArray); diff --git a/examples/tutorial_thread/1_openpose_read_and_display.cpp b/examples/tutorial_thread/1_openpose_read_and_display.cpp index df3769c3..11437cf3 100644 --- a/examples/tutorial_thread/1_openpose_read_and_display.cpp +++ b/examples/tutorial_thread/1_openpose_read_and_display.cpp @@ -9,7 +9,7 @@ // 3rdpary depencencies #include // DEFINE_bool, DEFINE_int32, DEFINE_int64, DEFINE_uint64, DEFINE_double, DEFINE_string -#include // google::InitGoogleLogging, CHECK, CHECK_EQ, LOG, VLOG, ... +#include // google::InitGoogleLogging // OpenPose dependencies #include #include @@ -17,8 +17,9 @@ #include #include -// Gflags in the command line terminal. Check all the options by adding the flag `--help`, e.g. `openpose.bin --help`. -// Note: This command will show you flags for several files. Check only the flags for the file you are checking. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. +// See all the available parameter options withe the `--help` flag. E.g. `./build/examples/openpose/openpose.bin --help`. +// Note: This command will show you flags for other unnecessary 3rdparty files. Check only the flags for the OpenPose +// executable. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. // Debugging DEFINE_int32(logging_level, 3, "The logging level. Integer in the range [0, 255]. 0 will output any log() message, while 255 will not output any." " Current OpenPose library messages are in the range 0-4: 1 for low priority messages and 4 for important ones."); @@ -55,7 +56,7 @@ op::ProducerType gflagsToProducerType(const std::string& imageDirectory, const s return op::ProducerType::Webcam; } -std::shared_ptr gflagsToProducer(const std::string& imageDirectory, const std::string& videoPath, const int webcamIndex, const cv::Size webcamResolution) +std::shared_ptr gflagsToProducer(const std::string& imageDirectory, const std::string& videoPath, const int webcamIndex, const op::Point webcamResolution) { op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); const auto type = gflagsToProducerType(imageDirectory, videoPath, webcamIndex); @@ -74,16 +75,16 @@ std::shared_ptr gflagsToProducer(const std::string& imageDirectory } // Google flags into program variables -std::tuple> gflagsToOpParameters() +std::tuple, op::Point, std::shared_ptr> gflagsToOpParameters() { op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); // cameraFrameSize - cv::Size cameraFrameSize; - auto nRead = sscanf(FLAGS_camera_resolution.c_str(), "%dx%d", &cameraFrameSize.width, &cameraFrameSize.height); + op::Point cameraFrameSize; + auto nRead = sscanf(FLAGS_camera_resolution.c_str(), "%dx%d", &cameraFrameSize.x, &cameraFrameSize.y); op::checkE(nRead, 2, "Error, camera resolution format (" + FLAGS_camera_resolution + ") invalid, should be e.g., 1280x720", __LINE__, __FUNCTION__, __FILE__); // outputSize - cv::Size outputSize; - nRead = sscanf(FLAGS_resolution.c_str(), "%dx%d", &outputSize.width, &outputSize.height); + op::Point outputSize; + nRead = sscanf(FLAGS_resolution.c_str(), "%dx%d", &outputSize.x, &outputSize.y); op::checkE(nRead, 2, "Error, resolution format (" + FLAGS_resolution + ") invalid, should be e.g., 960x540 ", __LINE__, __FUNCTION__, __FILE__); // producerType @@ -105,17 +106,17 @@ int openPoseTutorialThread1() 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); // Step 2 - Read Google flags (user defined configuration) - cv::Size cameraFrameSize; - cv::Size outputSize; + op::Point cameraFrameSize; + op::Point outputSize; std::shared_ptr producerSharedPtr; std::tie(cameraFrameSize, outputSize, producerSharedPtr) = gflagsToOpParameters(); // Step 3 - Setting producer auto videoSeekSharedPtr = std::make_shared, std::atomic>>(); videoSeekSharedPtr->first = false; videoSeekSharedPtr->second = 0; - const cv::Size producerSize{(int)producerSharedPtr->get(CV_CAP_PROP_FRAME_WIDTH), + const op::Point producerSize{(int)producerSharedPtr->get(CV_CAP_PROP_FRAME_WIDTH), (int)producerSharedPtr->get(CV_CAP_PROP_FRAME_HEIGHT)}; - if (outputSize.width == -1 || outputSize.height == -1) + if (outputSize.x == -1 || outputSize.y == -1) { if (producerSize.area() > 0) outputSize = producerSize; @@ -162,7 +163,7 @@ int openPoseTutorialThread1() // ------------------------- STARTING AND STOPPING THREADING ------------------------- op::log("Starting thread(s)", op::Priority::Max); - // Two different ways of running the program on multithread enviroment + // Two different ways of running the program on multithread environment // Option a) Using the main thread (this thread) for processing (it saves 1 thread, recommended) threadManager.exec(); // It blocks this thread until all threads have finished // Option b) Giving to the user the control of this thread diff --git a/examples/tutorial_thread/2_user_processing_function.cpp b/examples/tutorial_thread/2_user_processing_function.cpp index 79d3a9c5..faef043d 100644 --- a/examples/tutorial_thread/2_user_processing_function.cpp +++ b/examples/tutorial_thread/2_user_processing_function.cpp @@ -10,7 +10,7 @@ // 3rdpary depencencies #include // DEFINE_bool, DEFINE_int32, DEFINE_int64, DEFINE_uint64, DEFINE_double, DEFINE_string -#include // google::InitGoogleLogging, CHECK, CHECK_EQ, LOG, VLOG, ... +#include // google::InitGoogleLogging // OpenPose dependencies #include #include @@ -18,8 +18,9 @@ #include #include -// Gflags in the command line terminal. Check all the options by adding the flag `--help`, e.g. `openpose.bin --help`. -// Note: This command will show you flags for several files. Check only the flags for the file you are checking. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. +// See all the available parameter options withe the `--help` flag. E.g. `./build/examples/openpose/openpose.bin --help`. +// Note: This command will show you flags for other unnecessary 3rdparty files. Check only the flags for the OpenPose +// executable. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. // Debugging DEFINE_int32(logging_level, 3, "The logging level. Integer in the range [0, 255]. 0 will output any log() message, while 255 will not output any." " Current OpenPose library messages are in the range 0-4: 1 for low priority messages and 4 for important ones."); @@ -89,7 +90,7 @@ op::ProducerType gflagsToProducerType(const std::string& imageDirectory, const s return op::ProducerType::Webcam; } -std::shared_ptr gflagsToProducer(const std::string& imageDirectory, const std::string& videoPath, const int webcamIndex, const cv::Size webcamResolution) +std::shared_ptr gflagsToProducer(const std::string& imageDirectory, const std::string& videoPath, const int webcamIndex, const op::Point webcamResolution) { op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); const auto type = gflagsToProducerType(imageDirectory, videoPath, webcamIndex); @@ -108,16 +109,16 @@ std::shared_ptr gflagsToProducer(const std::string& imageDirectory } // Google flags into program variables -std::tuple> gflagsToOpParameters() +std::tuple, op::Point, std::shared_ptr> gflagsToOpParameters() { op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); // cameraFrameSize - cv::Size cameraFrameSize; - auto nRead = sscanf(FLAGS_camera_resolution.c_str(), "%dx%d", &cameraFrameSize.width, &cameraFrameSize.height); + op::Point cameraFrameSize; + auto nRead = sscanf(FLAGS_camera_resolution.c_str(), "%dx%d", &cameraFrameSize.x, &cameraFrameSize.y); op::checkE(nRead, 2, "Error, camera resolution format (" + FLAGS_camera_resolution + ") invalid, should be e.g., 1280x720", __LINE__, __FUNCTION__, __FILE__); // outputSize - cv::Size outputSize; - nRead = sscanf(FLAGS_resolution.c_str(), "%dx%d", &outputSize.width, &outputSize.height); + op::Point outputSize; + nRead = sscanf(FLAGS_resolution.c_str(), "%dx%d", &outputSize.x, &outputSize.y); op::checkE(nRead, 2, "Error, resolution format (" + FLAGS_resolution + ") invalid, should be e.g., 960x540 ", __LINE__, __FUNCTION__, __FILE__); // producerType @@ -139,17 +140,17 @@ int openPoseTutorialThread2() 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); // Step 2 - Read Google flags (user defined configuration) - cv::Size cameraFrameSize; - cv::Size outputSize; + op::Point cameraFrameSize; + op::Point outputSize; std::shared_ptr producerSharedPtr; std::tie(cameraFrameSize, outputSize, producerSharedPtr) = gflagsToOpParameters(); // Step 3 - Setting producer auto videoSeekSharedPtr = std::make_shared, std::atomic>>(); videoSeekSharedPtr->first = false; videoSeekSharedPtr->second = 0; - const cv::Size producerSize{(int)producerSharedPtr->get(CV_CAP_PROP_FRAME_WIDTH), + const op::Point producerSize{(int)producerSharedPtr->get(CV_CAP_PROP_FRAME_WIDTH), (int)producerSharedPtr->get(CV_CAP_PROP_FRAME_HEIGHT)}; - if (outputSize.width == -1 || outputSize.height == -1) + if (outputSize.x == -1 || outputSize.y == -1) { if (producerSize.area() > 0) outputSize = producerSize; @@ -204,7 +205,7 @@ int openPoseTutorialThread2() // ------------------------- STARTING AND STOPPING THREADING ------------------------- op::log("Starting thread(s)", op::Priority::Max); - // Two different ways of running the program on multithread enviroment + // Two different ways of running the program on multithread environment // Option a) Using the main thread (this thread) for processing (it saves 1 thread, recommended) threadManager.exec(); // It blocks this thread until all threads have finished // Option b) Giving to the user the control of this thread diff --git a/examples/tutorial_thread/3_user_input_processing_and_output.cpp b/examples/tutorial_thread/3_user_input_processing_and_output.cpp index c9667040..afefbc1a 100644 --- a/examples/tutorial_thread/3_user_input_processing_and_output.cpp +++ b/examples/tutorial_thread/3_user_input_processing_and_output.cpp @@ -10,7 +10,7 @@ // 3rdpary depencencies #include // DEFINE_bool, DEFINE_int32, DEFINE_int64, DEFINE_uint64, DEFINE_double, DEFINE_string -#include // google::InitGoogleLogging, CHECK, CHECK_EQ, LOG, VLOG, ... +#include // google::InitGoogleLogging // OpenPose dependencies // Option a) Importing all modules #include @@ -23,8 +23,9 @@ // #include // #include -// Gflags in the command line terminal. Check all the options by adding the flag `--help`, e.g. `openpose.bin --help`. -// Note: This command will show you flags for several files. Check only the flags for the file you are checking. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. +// See all the available parameter options withe the `--help` flag. E.g. `./build/examples/openpose/openpose.bin --help`. +// Note: This command will show you flags for other unnecessary 3rdparty files. Check only the flags for the OpenPose +// executable. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. // Debugging DEFINE_int32(logging_level, 3, "The logging level. Integer in the range [0, 255]. 0 will output any log() message, while 255 will not output any." " Current OpenPose library messages are in the range 0-4: 1 for low priority messages and 4 for important ones."); @@ -114,7 +115,7 @@ public: { // User's post-processing (after OpenPose processing & before OpenPose outputs) here // datum.cvOutputData: rendered frame with pose or heatmaps - // datum.poseKeyPoints: Array with the estimated pose + // datum.poseKeypoints: Array with the estimated pose try { if (datumsPtr != nullptr && !datumsPtr->empty()) @@ -142,7 +143,7 @@ public: { // User's displaying/saving/other processing here // datum.cvOutputData: rendered frame with pose or heatmaps - // datum.poseKeyPoints: Array with the estimated pose + // datum.poseKeypoints: Array with the estimated pose if (datumsPtr != nullptr && !datumsPtr->empty()) { cv::imshow("User worker GUI", datumsPtr->at(0).cvOutputData); @@ -195,7 +196,7 @@ int openPoseTutorialThread3() // ------------------------- STARTING AND STOPPING THREADING ------------------------- op::log("Starting thread(s)", op::Priority::Max); - // Two different ways of running the program on multithread enviroment + // Two different ways of running the program on multithread environment // Option a) Using the main thread (this thread) for processing (it saves 1 thread, recommended) threadManager.exec(); // It blocks this thread until all threads have finished // Option b) Giving to the user the control of this thread diff --git a/examples/tutorial_thread/4_user_input_processing_output_and_datum.cpp b/examples/tutorial_thread/4_user_input_processing_output_and_datum.cpp index 4b09ecad..6d590a96 100644 --- a/examples/tutorial_thread/4_user_input_processing_output_and_datum.cpp +++ b/examples/tutorial_thread/4_user_input_processing_output_and_datum.cpp @@ -10,7 +10,7 @@ // 3rdpary depencencies #include // DEFINE_bool, DEFINE_int32, DEFINE_int64, DEFINE_uint64, DEFINE_double, DEFINE_string -#include // google::InitGoogleLogging, CHECK, CHECK_EQ, LOG, VLOG, ... +#include // google::InitGoogleLogging // OpenPose dependencies // Option a) Importing all modules #include @@ -23,8 +23,9 @@ // #include // #include -// Gflags in the command line terminal. Check all the options by adding the flag `--help`, e.g. `openpose.bin --help`. -// Note: This command will show you flags for several files. Check only the flags for the file you are checking. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. +// See all the available parameter options withe the `--help` flag. E.g. `./build/examples/openpose/openpose.bin --help`. +// Note: This command will show you flags for other unnecessary 3rdparty files. Check only the flags for the OpenPose +// executable. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. // Debugging DEFINE_int32(logging_level, 3, "The logging level. Integer in the range [0, 255]. 0 will output any log() message, while 255 will not output any." " Current OpenPose library messages are in the range 0-4: 1 for low priority messages and 4 for important ones."); @@ -126,7 +127,7 @@ public: { // User's post-processing (after OpenPose processing & before OpenPose outputs) here // datum.cvOutputData: rendered frame with pose or heatmaps - // datum.poseKeyPoints: Array with the estimated pose + // datum.poseKeypoints: Array with the estimated pose try { if (datumsPtr != nullptr && !datumsPtr->empty()) @@ -154,7 +155,7 @@ public: { // User's displaying/saving/other processing here // datum.cvOutputData: rendered frame with pose or heatmaps - // datum.poseKeyPoints: Array with the estimated pose + // datum.poseKeypoints: Array with the estimated pose if (datumsPtr != nullptr && !datumsPtr->empty()) { cv::imshow("User worker GUI", datumsPtr->at(0).cvOutputData); @@ -207,7 +208,7 @@ int openPoseTutorialThread4() // ------------------------- STARTING AND STOPPING THREADING ------------------------- op::log("Starting thread(s)", op::Priority::Max); - // Two different ways of running the program on multithread enviroment + // Two different ways of running the program on multithread environment // Option a) Using the main thread (this thread) for processing (it saves 1 thread, recommended) threadManager.exec(); // It blocks this thread until all threads have finished // Option b) Giving to the user the control of this thread diff --git a/examples/tutorial_wrapper/1_user_asynchronous.cpp b/examples/tutorial_wrapper/1_user_asynchronous.cpp index b2e14f5f..b6ca99b6 100644 --- a/examples/tutorial_wrapper/1_user_asynchronous.cpp +++ b/examples/tutorial_wrapper/1_user_asynchronous.cpp @@ -2,7 +2,7 @@ // Asynchronous mode: ideal for fast prototyping when performance is not an issue. The user emplaces/pushes and pops frames from the OpenPose wrapper when he desires to. // This example shows the user how to use the OpenPose wrapper class: - // 1. Extract and render pose / heatmap / PAF of that image + // 1. Extract and render keypoint / heatmap / PAF of that image // 2. Save the results on disc // 3. Display the rendered pose // Everything in a multi-thread scenario @@ -20,11 +20,9 @@ #include // std::string #include // std::this_thread #include // std::vector -// OpenCV dependencies -#include // cv::Mat & cv::Size // Other 3rdpary depencencies #include // DEFINE_bool, DEFINE_int32, DEFINE_int64, DEFINE_uint64, DEFINE_double, DEFINE_string -#include // google::InitGoogleLogging, CHECK, CHECK_EQ, LOG, VLOG, ... +#include // google::InitGoogleLogging // OpenPose dependencies // Option a) Importing all modules @@ -32,6 +30,7 @@ // Option b) Manually importing the desired modules. Recommended if you only intend to use a few modules. // #include // #include +// #include // #include // #include // #include @@ -40,56 +39,63 @@ // #include // #include -// Uncomment to avoid needing `op::` before each class and function of the OpenPose library. Analogously for OpenCV and the standard C++ library -// using namespace op; -// using namespace cv; -// using namespace std; - -// Gflags in the command line terminal. Check all the options by adding the flag `--help`, e.g. `openpose.bin --help`. -// Note: This command will show you flags for several files. Check only the flags for the file you are checking. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. +// See all the available parameter options withe the `--help` flag. E.g. `./build/examples/openpose/openpose.bin --help`. +// Note: This command will show you flags for other unnecessary 3rdparty files. Check only the flags for the OpenPose +// executable. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. // Debugging DEFINE_int32(logging_level, 3, "The logging level. Integer in the range [0, 255]. 0 will output any log() message, while 255 will not output any." " Current OpenPose library messages are in the range 0-4: 1 for low priority messages and 4 for important ones."); // Producer DEFINE_string(image_dir, "examples/media/", "Process a directory of images."); // OpenPose -DEFINE_string(model_pose, "COCO", "Model to be used (e.g. COCO, MPI, MPI_4_layers)."); DEFINE_string(model_folder, "models/", "Folder where the pose models (COCO and MPI) are located."); -DEFINE_string(net_resolution, "656x368", "Multiples of 16."); -DEFINE_string(resolution, "1280x720", "The image resolution (display and output)."); -DEFINE_int32(num_gpu, 1, "The number of GPU devices to use."); +DEFINE_string(resolution, "1280x720", "The image resolution (display and output). Use \"-1x-1\" to force the program to use the default images resolution."); +DEFINE_int32(num_gpu, -1, "The number of GPU devices to use. If negative, it will use all the available GPUs in your machine."); DEFINE_int32(num_gpu_start, 0, "GPU device start number."); +DEFINE_int32(keypoint_scale, 0, "Scaling of the (x,y) coordinates of the final pose data array, i.e. the scale of the (x,y) coordinates that will be saved" + " with the `write_keypoint` & `write_keypoint_json` flags. Select `0` to scale it to the original source resolution, `1`to scale" + " it to the net output size (set with `net_resolution`), `2` to scale it to the final output size (set with `resolution`)," + " `3` to scale it in the range [0,1], and 4 for range [-1,1]. Non related with `num_scales` and `scale_gap`."); +// OpenPose Body Pose +DEFINE_string(model_pose, "COCO", "Model to be used (e.g. COCO, MPI, MPI_4_layers)."); +DEFINE_string(net_resolution, "656x368", "Multiples of 16. If it is increased, the accuracy usually increases. If it is decreased, the speed increases."); DEFINE_int32(num_scales, 1, "Number of scales to average."); DEFINE_double(scale_gap, 0.3, "Scale gap between scales. No effect unless num_scales>1. Initial scale is always 1. If you want to change the initial scale," " you actually want to multiply the `net_resolution` by your desired initial scale."); -DEFINE_int32(scale_mode, 0, "Scaling of the (x,y) coordinates of the final pose data array (op::Datum::pose), i.e. the scale of the (x,y) coordinates that" - " will be saved with the `write_pose` & `write_pose_json` flags. Select `0` to scale it to the original source resolution, `1`" - " to scale it to the net output size (set with `net_resolution`), `2` to scale it to the final output size (set with " - " `resolution`), `3` to scale it in the range [0,1], and 4 for range [-1,1]. Non related with `num_scales` and `scale_gap`."); DEFINE_bool(heatmaps_add_parts, false, "If true, it will add the body part heatmaps to the final op::Datum::poseHeatMaps array (program speed will decrease). Not" " required for our library, enable it only if you intend to process this information later. If more than one `add_heatmaps_X`" " flag is enabled, it will place then in sequential memory order: body parts + bkg + PAFs. It will follow the order on" " POSE_BODY_PART_MAPPING in `include/openpose/pose/poseParameters.hpp`."); DEFINE_bool(heatmaps_add_bkg, false, "Same functionality as `add_heatmaps_parts`, but adding the heatmap corresponding to background."); DEFINE_bool(heatmaps_add_PAFs, false, "Same functionality as `add_heatmaps_parts`, but adding the PAFs."); -DEFINE_int32(heatmaps_scale_mode, 2, "Set 0 to scale op::Datum::poseHeatMaps in the range [0,1], 1 for [-1,1]; and 2 for integer rounded [0,255]."); +DEFINE_int32(heatmaps_scale, 2, "Set 0 to scale op::Datum::poseHeatMaps in the range [0,1], 1 for [-1,1]; and 2 for integer rounded [0,255]."); +// OpenPose Face +DEFINE_bool(face, false, "Enables face keypoint detection. It will share some parameters from the body pose, e.g. `model_folder`."); +DEFINE_string(face_net_resolution, "368x368", "Multiples of 16. Analogous to `net_resolution` but applied to the face keypoint detector. 320x320 usually works fine" + " while giving a substantial speed up when multiple faces on the image."); +// OpenPose Hand // OpenPose Rendering -DEFINE_bool(no_render_output, false, "If false, it will fill both `outputData` and `cvOutputData` with the original image + desired part to be shown." - " If true, it will leave them empty."); DEFINE_int32(part_to_show, 0, "Part to show from the start."); -DEFINE_bool(disable_blending, false, "If false, it will blend the results with the original frame. If true, it will only display the results."); +DEFINE_bool(disable_blending, false, "If blending is enabled, it will merge the results with the original frame. If disabled, it will only display the results."); +// OpenPose Rendering Pose +DEFINE_bool(no_render_pose, false, "If false, it will fill both `outputData` and `cvOutputData` with the original image + desired part to be shown." + " If true, it will leave them empty."); DEFINE_double(alpha_pose, 0.6, "Blending factor (range 0-1) for the body part rendering. 1 will show it completely, 0 will hide it."); DEFINE_double(alpha_heatmap, 0.7, "Blending factor (range 0-1) between heatmap and original frame. 1 will only show the heatmap, 0 will only show the frame."); -// Consumer +// OpenPose Rendering Face +DEFINE_bool(no_render_face, false, "Analogous to `no_render_pose` but applied to the face keypoints and heat maps."); +DEFINE_double(alpha_face, 0.6, "Blending factor (range 0-1) for the body part rendering. 1 will show it completely, 0 will hide it."); +DEFINE_double(alpha_heatmap_face, 0.7, "Blending factor (range 0-1) between heatmap and original frame. 1 will only show the heatmap, 0 will only show the frame."); +// Result Saving DEFINE_string(write_images, "", "Directory to write rendered frames in `write_images_format` image format."); DEFINE_string(write_images_format, "png", "File extension and format for `write_images`, e.g. png, jpg or bmp. Check the OpenCV function cv::imwrite" " for all compatible extensions."); DEFINE_string(write_video, "", "Full file path to write rendered frames in motion JPEG video format. It might fail if the final path does" " not finish in `.avi`. It internally uses cv::VideoWriter."); -DEFINE_string(write_pose, "", "Directory to write the people pose data. Desired format on `write_pose_format`."); -DEFINE_string(write_pose_format, "yml", "File extension and format for `write_pose`: json, xml, yaml and yml. Json not available for OpenCV < 3.0," - " use `write_pose_json` instead."); -DEFINE_string(write_pose_json, "", "Directory to write people pose data with *.json format, compatible with any OpenCV version."); +DEFINE_string(write_keypoint, "", "Directory to write the people body pose keypoint data. Desired format on `write_keypoint_format`."); +DEFINE_string(write_keypoint_format, "yml", "File extension and format for `write_keypoint`: json, xml, yaml and yml. Json not available for OpenCV < 3.0," + " use `write_keypoint_json` instead."); +DEFINE_string(write_keypoint_json, "", "Directory to write people pose data with *.json format, compatible with any OpenCV version."); DEFINE_string(write_coco_json, "", "Full file path to write people pose data with *.json COCO validation format."); DEFINE_string(write_heatmaps, "", "Directory to write heatmaps with *.png format. At least 1 `add_heatmaps_X` flag must be enabled."); DEFINE_string(write_heatmaps_format, "png", "File extension and format for `write_heatmaps`, analogous to `write_images_format`. Recommended `png` or any compressed and" @@ -176,7 +182,7 @@ public: { // User's displaying/saving/other processing here // datum.cvOutputData: rendered frame with pose or heatmaps - // datum.poseKeyPoints: Array with the estimated pose + // datum.poseKeypoints: Array with the estimated pose if (datumsPtr != nullptr && !datumsPtr->empty()) { cv::imshow("User worker GUI", datumsPtr->at(0).cvOutputData); @@ -203,18 +209,18 @@ op::PoseModel gflagToPoseModel(const std::string& poseModeString) } } -op::ScaleMode gflagToScaleMode(const int scaleMode) +op::ScaleMode gflagToScaleMode(const int keypointScale) { op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); - if (scaleMode == 0) + if (keypointScale == 0) return op::ScaleMode::InputResolution; - else if (scaleMode == 1) + else if (keypointScale == 1) return op::ScaleMode::NetOutputResolution; - else if (scaleMode == 2) + else if (keypointScale == 2) return op::ScaleMode::OutputResolution; - else if (scaleMode == 3) + else if (keypointScale == 3) return op::ScaleMode::ZeroToOne; - else if (scaleMode == 4) + else if (keypointScale == 4) return op::ScaleMode::PlusMinusOne; else { @@ -238,27 +244,31 @@ std::vector gflagToHeatMaps(const bool heatmaps_add_parts, cons } // Google flags into program variables -std::tuple, op::ScaleMode> gflagsToOpParameters() +std::tuple, op::Point, op::Point, op::PoseModel, op::ScaleMode, std::vector, op::ScaleMode> gflagsToOpParameters() { op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); // outputSize - cv::Size outputSize; - auto nRead = sscanf(FLAGS_resolution.c_str(), "%dx%d", &outputSize.width, &outputSize.height); + op::Point outputSize; + auto nRead = sscanf(FLAGS_resolution.c_str(), "%dx%d", &outputSize.x, &outputSize.y); op::checkE(nRead, 2, "Error, resolution format (" + FLAGS_resolution + ") invalid, should be e.g., 960x540 ", __LINE__, __FUNCTION__, __FILE__); // netInputSize - cv::Size netInputSize; - nRead = sscanf(FLAGS_net_resolution.c_str(), "%dx%d", &netInputSize.width, &netInputSize.height); + op::Point netInputSize; + nRead = sscanf(FLAGS_net_resolution.c_str(), "%dx%d", &netInputSize.x, &netInputSize.y); op::checkE(nRead, 2, "Error, net resolution format (" + FLAGS_net_resolution + ") invalid, should be e.g., 656x368 (multiples of 16)", __LINE__, __FUNCTION__, __FILE__); + // faceNetInputSize + op::Point faceNetInputSize; + nRead = sscanf(FLAGS_face_net_resolution.c_str(), "%dx%d", &faceNetInputSize.x, &faceNetInputSize.y); + op::checkE(nRead, 2, "Error, face net resolution format (" + FLAGS_face_net_resolution + ") invalid, should be e.g., 368x368 (multiples of 16)", __LINE__, __FUNCTION__, __FILE__); // poseModel const auto poseModel = gflagToPoseModel(FLAGS_model_pose); - // scaleMode - const auto scaleMode = gflagToScaleMode(FLAGS_scale_mode); + // keypointScale + const auto keypointScale = gflagToScaleMode(FLAGS_keypoint_scale); // heatmaps to add const auto heatMapTypes = gflagToHeatMaps(FLAGS_heatmaps_add_parts, FLAGS_heatmaps_add_bkg, FLAGS_heatmaps_add_PAFs); - op::check(FLAGS_heatmaps_scale_mode >= 0 && FLAGS_heatmaps_scale_mode <= 2, "Non valid `heatmaps_scale_mode`.", __LINE__, __FUNCTION__, __FILE__); - const auto heatMapsScaleMode = (FLAGS_heatmaps_scale_mode == 0 ? op::ScaleMode::PlusMinusOne : (FLAGS_heatmaps_scale_mode == 1 ? op::ScaleMode::ZeroToOne : op::ScaleMode::UnsignedChar )); + op::check(FLAGS_heatmaps_scale >= 0 && FLAGS_heatmaps_scale <= 2, "Non valid `heatmaps_scale`.", __LINE__, __FUNCTION__, __FILE__); + const auto heatMapScale = (FLAGS_heatmaps_scale == 0 ? op::ScaleMode::PlusMinusOne : (FLAGS_heatmaps_scale == 1 ? op::ScaleMode::ZeroToOne : op::ScaleMode::UnsignedChar )); // return - return std::make_tuple(outputSize, netInputSize, poseModel, scaleMode, heatMapTypes, heatMapsScaleMode); + return std::make_tuple(outputSize, netInputSize, faceNetInputSize, poseModel, keypointScale, heatMapTypes, heatMapScale); } int openPoseTutorialWrapper1() @@ -272,13 +282,14 @@ int openPoseTutorialWrapper1() const auto timerBegin = std::chrono::high_resolution_clock::now(); // Applying user defined configuration - cv::Size outputSize; - cv::Size netInputSize; + op::Point outputSize; + op::Point netInputSize; + op::Point faceNetInputSize; op::PoseModel poseModel; - op::ScaleMode scaleMode; + op::ScaleMode keypointScale; std::vector heatMapTypes; - op::ScaleMode heatMapsScaleMode; - std::tie(outputSize, netInputSize, poseModel, scaleMode, heatMapTypes, heatMapsScaleMode) = gflagsToOpParameters(); + op::ScaleMode heatMapScale; + std::tie(outputSize, netInputSize, faceNetInputSize, poseModel, keypointScale, heatMapTypes, heatMapScale) = gflagsToOpParameters(); op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); // Configure OpenPose @@ -286,16 +297,19 @@ int openPoseTutorialWrapper1() const bool displayGui = false; const bool guiVerbose = false; const bool fullScreen = false; - const op::WrapperStructPose wrapperStructPose{netInputSize, outputSize, scaleMode, FLAGS_num_gpu, FLAGS_num_gpu_start, FLAGS_num_scales, (float)FLAGS_scale_gap, - !FLAGS_no_render_output, poseModel, !FLAGS_disable_blending, (float)FLAGS_alpha_pose, (float)FLAGS_alpha_heatmap, - FLAGS_part_to_show, FLAGS_model_folder, heatMapTypes, heatMapsScaleMode}; - const op::WrapperStructOutput wrapperStructOutput{displayGui, guiVerbose, fullScreen, FLAGS_write_pose, op::stringToDataFormat(FLAGS_write_pose_format), - FLAGS_write_pose_json, FLAGS_write_coco_json, FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, - FLAGS_write_heatmaps, FLAGS_write_heatmaps_format}; - // Pose configuration (use WrapperStructPose{} for default and recommended configuration) - // Producer (use default to disable any input) + const op::WrapperStructPose wrapperStructPose{netInputSize, outputSize, keypointScale, FLAGS_num_gpu, FLAGS_num_gpu_start, FLAGS_num_scales, (float)FLAGS_scale_gap, + !FLAGS_no_render_pose, poseModel, !FLAGS_disable_blending, (float)FLAGS_alpha_pose, (float)FLAGS_alpha_heatmap, + FLAGS_part_to_show, FLAGS_model_folder, heatMapTypes, heatMapScale}; + // (Experimental, function and class names might change in next versions) Face configuration (use op::WrapperStructFace{} to disable it) + const op::WrapperStructFace wrapperStructFace{FLAGS_face, faceNetInputSize, !FLAGS_no_render_face, (float)FLAGS_alpha_face, (float)FLAGS_alpha_heatmap_face}; + // (Experimental, function and class names might change in next versions) Hand configuration (use op::WrapperStructFace{} to disable it) + const op::experimental::WrapperStructHand wrapperStructHand{false}; // Consumer (comment or use default argument to disable any output) - opWrapper.configure(wrapperStructPose, op::WrapperStructInput{}, wrapperStructOutput); + const op::WrapperStructOutput wrapperStructOutput{displayGui, guiVerbose, fullScreen, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format), + FLAGS_write_keypoint_json, FLAGS_write_coco_json, FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, + FLAGS_write_heatmaps, FLAGS_write_heatmaps_format}; + // Configure wrapper + opWrapper.configure(wrapperStructPose, wrapperStructFace, wrapperStructHand, op::WrapperStructInput{}, wrapperStructOutput); // Set to single-thread running (e.g. for debugging purposes) // opWrapper.disableMultiThreading(); diff --git a/examples/tutorial_wrapper/2_user_synchronous.cpp b/examples/tutorial_wrapper/2_user_synchronous.cpp index aa4a222a..3a5f00d1 100644 --- a/examples/tutorial_wrapper/2_user_synchronous.cpp +++ b/examples/tutorial_wrapper/2_user_synchronous.cpp @@ -2,7 +2,7 @@ // 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. Extract and render pose / heatmap / PAF of that image + // 1. Extract and render keypoint / heatmap / PAF of that image // 2. Save the results on disc // 3. Display the rendered pose // Everything in a multi-thread scenario @@ -20,11 +20,9 @@ #include // std::string #include // std::this_thread #include // std::vector -// OpenCV dependencies -#include // cv::Mat & cv::Size // Other 3rdpary depencencies #include // DEFINE_bool, DEFINE_int32, DEFINE_int64, DEFINE_uint64, DEFINE_double, DEFINE_string -#include // google::InitGoogleLogging, CHECK, CHECK_EQ, LOG, VLOG, ... +#include // google::InitGoogleLogging // OpenPose dependencies // Option a) Importing all modules @@ -32,6 +30,7 @@ // Option b) Manually importing the desired modules. Recommended if you only intend to use a few modules. // #include // #include +// #include // #include // #include // #include @@ -40,56 +39,63 @@ // #include // #include -// Uncomment to avoid needing `op::` before each class and function of the OpenPose library. Analogously for OpenCV and the standard C++ library -// using namespace op; -// using namespace cv; -// using namespace std; - -// Gflags in the command line terminal. Check all the options by adding the flag `--help`, e.g. `openpose.bin --help`. -// Note: This command will show you flags for several files. Check only the flags for the file you are checking. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. +// See all the available parameter options withe the `--help` flag. E.g. `./build/examples/openpose/openpose.bin --help`. +// Note: This command will show you flags for other unnecessary 3rdparty files. Check only the flags for the OpenPose +// executable. E.g. for `openpose.bin`, look for `Flags from examples/openpose/openpose.cpp:`. // Debugging DEFINE_int32(logging_level, 3, "The logging level. Integer in the range [0, 255]. 0 will output any log() message, while 255 will not output any." " Current OpenPose library messages are in the range 0-4: 1 for low priority messages and 4 for important ones."); // Producer DEFINE_string(image_dir, "examples/media/", "Process a directory of images."); // OpenPose -DEFINE_string(model_pose, "COCO", "Model to be used (e.g. COCO, MPI, MPI_4_layers)."); DEFINE_string(model_folder, "models/", "Folder where the pose models (COCO and MPI) are located."); -DEFINE_string(net_resolution, "656x368", "Multiples of 16."); -DEFINE_string(resolution, "1280x720", "The image resolution (display and output)."); -DEFINE_int32(num_gpu, 1, "The number of GPU devices to use."); +DEFINE_string(resolution, "1280x720", "The image resolution (display and output). Use \"-1x-1\" to force the program to use the default images resolution."); +DEFINE_int32(num_gpu, -1, "The number of GPU devices to use. If negative, it will use all the available GPUs in your machine."); DEFINE_int32(num_gpu_start, 0, "GPU device start number."); +DEFINE_int32(keypoint_scale, 0, "Scaling of the (x,y) coordinates of the final pose data array, i.e. the scale of the (x,y) coordinates that will be saved" + " with the `write_keypoint` & `write_keypoint_json` flags. Select `0` to scale it to the original source resolution, `1`to scale" + " it to the net output size (set with `net_resolution`), `2` to scale it to the final output size (set with `resolution`)," + " `3` to scale it in the range [0,1], and 4 for range [-1,1]. Non related with `num_scales` and `scale_gap`."); +// OpenPose Body Pose +DEFINE_string(model_pose, "COCO", "Model to be used (e.g. COCO, MPI, MPI_4_layers)."); +DEFINE_string(net_resolution, "656x368", "Multiples of 16. If it is increased, the accuracy usually increases. If it is decreased, the speed increases."); DEFINE_int32(num_scales, 1, "Number of scales to average."); DEFINE_double(scale_gap, 0.3, "Scale gap between scales. No effect unless num_scales>1. Initial scale is always 1. If you want to change the initial scale," " you actually want to multiply the `net_resolution` by your desired initial scale."); -DEFINE_int32(scale_mode, 0, "Scaling of the (x,y) coordinates of the final pose data array (op::Datum::pose), i.e. the scale of the (x,y) coordinates that" - " will be saved with the `write_pose` & `write_pose_json` flags. Select `0` to scale it to the original source resolution, `1`" - " to scale it to the net output size (set with `net_resolution`), `2` to scale it to the final output size (set with " - " `resolution`), `3` to scale it in the range [0,1], and 4 for range [-1,1]. Non related with `num_scales` and `scale_gap`."); DEFINE_bool(heatmaps_add_parts, false, "If true, it will add the body part heatmaps to the final op::Datum::poseHeatMaps array (program speed will decrease). Not" " required for our library, enable it only if you intend to process this information later. If more than one `add_heatmaps_X`" " flag is enabled, it will place then in sequential memory order: body parts + bkg + PAFs. It will follow the order on" " POSE_BODY_PART_MAPPING in `include/openpose/pose/poseParameters.hpp`."); DEFINE_bool(heatmaps_add_bkg, false, "Same functionality as `add_heatmaps_parts`, but adding the heatmap corresponding to background."); DEFINE_bool(heatmaps_add_PAFs, false, "Same functionality as `add_heatmaps_parts`, but adding the PAFs."); -DEFINE_int32(heatmaps_scale_mode, 2, "Set 0 to scale op::Datum::poseHeatMaps in the range [0,1], 1 for [-1,1]; and 2 for integer rounded [0,255]."); +DEFINE_int32(heatmaps_scale, 2, "Set 0 to scale op::Datum::poseHeatMaps in the range [0,1], 1 for [-1,1]; and 2 for integer rounded [0,255]."); +// OpenPose Face +DEFINE_bool(face, false, "Enables face keypoint detection. It will share some parameters from the body pose, e.g. `model_folder`."); +DEFINE_string(face_net_resolution, "368x368", "Multiples of 16. Analogous to `net_resolution` but applied to the face keypoint detector. 320x320 usually works fine" + " while giving a substantial speed up when multiple faces on the image."); +// OpenPose Hand // OpenPose Rendering -DEFINE_bool(no_render_output, false, "If false, it will fill both `outputData` and `cvOutputData` with the original image + desired part to be shown." - " If true, it will leave them empty."); DEFINE_int32(part_to_show, 0, "Part to show from the start."); -DEFINE_bool(disable_blending, false, "If false, it will blend the results with the original frame. If true, it will only display the results."); +DEFINE_bool(disable_blending, false, "If blending is enabled, it will merge the results with the original frame. If disabled, it will only display the results."); +// OpenPose Rendering Pose +DEFINE_bool(no_render_pose, false, "If false, it will fill both `outputData` and `cvOutputData` with the original image + desired part to be shown." + " If true, it will leave them empty."); DEFINE_double(alpha_pose, 0.6, "Blending factor (range 0-1) for the body part rendering. 1 will show it completely, 0 will hide it."); DEFINE_double(alpha_heatmap, 0.7, "Blending factor (range 0-1) between heatmap and original frame. 1 will only show the heatmap, 0 will only show the frame."); -// Consumer +// OpenPose Rendering Face +DEFINE_bool(no_render_face, false, "Analogous to `no_render_pose` but applied to the face keypoints and heat maps."); +DEFINE_double(alpha_face, 0.6, "Blending factor (range 0-1) for the body part rendering. 1 will show it completely, 0 will hide it."); +DEFINE_double(alpha_heatmap_face, 0.7, "Blending factor (range 0-1) between heatmap and original frame. 1 will only show the heatmap, 0 will only show the frame."); +// Result Saving DEFINE_string(write_images, "", "Directory to write rendered frames in `write_images_format` image format."); DEFINE_string(write_images_format, "png", "File extension and format for `write_images`, e.g. png, jpg or bmp. Check the OpenCV function cv::imwrite" " for all compatible extensions."); DEFINE_string(write_video, "", "Full file path to write rendered frames in motion JPEG video format. It might fail if the final path does" " not finish in `.avi`. It internally uses cv::VideoWriter."); -DEFINE_string(write_pose, "", "Directory to write the people pose data. Desired format on `write_pose_format`."); -DEFINE_string(write_pose_format, "yml", "File extension and format for `write_pose`: json, xml, yaml and yml. Json not available for OpenCV < 3.0," - " use `write_pose_json` instead."); -DEFINE_string(write_pose_json, "", "Directory to write people pose data with *.json format, compatible with any OpenCV version."); +DEFINE_string(write_keypoint, "", "Directory to write the people body pose keypoint data. Desired format on `write_keypoint_format`."); +DEFINE_string(write_keypoint_format, "yml", "File extension and format for `write_keypoint`: json, xml, yaml and yml. Json not available for OpenCV < 3.0," + " use `write_keypoint_json` instead."); +DEFINE_string(write_keypoint_json, "", "Directory to write people pose data with *.json format, compatible with any OpenCV version."); DEFINE_string(write_coco_json, "", "Full file path to write people pose data with *.json COCO validation format."); DEFINE_string(write_heatmaps, "", "Directory to write heatmaps with *.png format. At least 1 `add_heatmaps_X` flag must be enabled."); DEFINE_string(write_heatmaps_format, "png", "File extension and format for `write_heatmaps`, analogous to `write_images_format`. Recommended `png` or any compressed and" @@ -188,7 +194,7 @@ public: { // User's post-processing (after OpenPose processing & before OpenPose outputs) here // datum.cvOutputData: rendered frame with pose or heatmaps - // datum.poseKeyPoints: Array with the estimated pose + // datum.poseKeypoints: Array with the estimated pose try { if (datumsPtr != nullptr && !datumsPtr->empty()) @@ -216,7 +222,7 @@ public: { // User's displaying/saving/other processing here // datum.cvOutputData: rendered frame with pose or heatmaps - // datum.poseKeyPoints: Array with the estimated pose + // datum.poseKeypoints: Array with the estimated pose if (datumsPtr != nullptr && !datumsPtr->empty()) { cv::imshow("User worker GUI", datumsPtr->at(0).cvOutputData); @@ -248,18 +254,18 @@ op::PoseModel gflagToPoseModel(const std::string& poseModeString) } } -op::ScaleMode gflagToScaleMode(const int scaleMode) +op::ScaleMode gflagToScaleMode(const int keypointScale) { op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); - if (scaleMode == 0) + if (keypointScale == 0) return op::ScaleMode::InputResolution; - else if (scaleMode == 1) + else if (keypointScale == 1) return op::ScaleMode::NetOutputResolution; - else if (scaleMode == 2) + else if (keypointScale == 2) return op::ScaleMode::OutputResolution; - else if (scaleMode == 3) + else if (keypointScale == 3) return op::ScaleMode::ZeroToOne; - else if (scaleMode == 4) + else if (keypointScale == 4) return op::ScaleMode::PlusMinusOne; else { @@ -283,27 +289,31 @@ std::vector gflagToHeatMaps(const bool heatmaps_add_parts, cons } // Google flags into program variables -std::tuple, op::ScaleMode> gflagsToOpParameters() +std::tuple, op::Point, op::Point, op::PoseModel, op::ScaleMode, std::vector, op::ScaleMode> gflagsToOpParameters() { op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); // outputSize - cv::Size outputSize; - auto nRead = sscanf(FLAGS_resolution.c_str(), "%dx%d", &outputSize.width, &outputSize.height); + op::Point outputSize; + auto nRead = sscanf(FLAGS_resolution.c_str(), "%dx%d", &outputSize.x, &outputSize.y); op::checkE(nRead, 2, "Error, resolution format (" + FLAGS_resolution + ") invalid, should be e.g., 960x540 ", __LINE__, __FUNCTION__, __FILE__); // netInputSize - cv::Size netInputSize; - nRead = sscanf(FLAGS_net_resolution.c_str(), "%dx%d", &netInputSize.width, &netInputSize.height); + op::Point netInputSize; + nRead = sscanf(FLAGS_net_resolution.c_str(), "%dx%d", &netInputSize.x, &netInputSize.y); op::checkE(nRead, 2, "Error, net resolution format (" + FLAGS_net_resolution + ") invalid, should be e.g., 656x368 (multiples of 16)", __LINE__, __FUNCTION__, __FILE__); + // faceNetInputSize + op::Point faceNetInputSize; + nRead = sscanf(FLAGS_face_net_resolution.c_str(), "%dx%d", &faceNetInputSize.x, &faceNetInputSize.y); + op::checkE(nRead, 2, "Error, face net resolution format (" + FLAGS_face_net_resolution + ") invalid, should be e.g., 368x368 (multiples of 16)", __LINE__, __FUNCTION__, __FILE__); // poseModel const auto poseModel = gflagToPoseModel(FLAGS_model_pose); - // scaleMode - const auto scaleMode = gflagToScaleMode(FLAGS_scale_mode); + // keypointScale + const auto keypointScale = gflagToScaleMode(FLAGS_keypoint_scale); // heatmaps to add const auto heatMapTypes = gflagToHeatMaps(FLAGS_heatmaps_add_parts, FLAGS_heatmaps_add_bkg, FLAGS_heatmaps_add_PAFs); - op::check(FLAGS_heatmaps_scale_mode >= 0 && FLAGS_heatmaps_scale_mode <= 2, "Non valid `heatmaps_scale_mode`.", __LINE__, __FUNCTION__, __FILE__); - const auto heatMapsScaleMode = (FLAGS_heatmaps_scale_mode == 0 ? op::ScaleMode::PlusMinusOne : (FLAGS_heatmaps_scale_mode == 1 ? op::ScaleMode::ZeroToOne : op::ScaleMode::UnsignedChar )); + op::check(FLAGS_heatmaps_scale >= 0 && FLAGS_heatmaps_scale <= 2, "Non valid `heatmaps_scale`.", __LINE__, __FUNCTION__, __FILE__); + const auto heatMapScale = (FLAGS_heatmaps_scale == 0 ? op::ScaleMode::PlusMinusOne : (FLAGS_heatmaps_scale == 1 ? op::ScaleMode::ZeroToOne : op::ScaleMode::UnsignedChar )); // return - return std::make_tuple(outputSize, netInputSize, poseModel, scaleMode, heatMapTypes, heatMapsScaleMode); + return std::make_tuple(outputSize, netInputSize, faceNetInputSize, poseModel, keypointScale, heatMapTypes, heatMapScale); } int openPoseTutorialWrapper2() @@ -317,13 +327,14 @@ int openPoseTutorialWrapper2() const auto timerBegin = std::chrono::high_resolution_clock::now(); // Applying user defined configuration - cv::Size outputSize; - cv::Size netInputSize; + op::Point outputSize; + op::Point netInputSize; + op::Point faceNetInputSize; op::PoseModel poseModel; - op::ScaleMode scaleMode; + op::ScaleMode keypointScale; std::vector heatMapTypes; - op::ScaleMode heatMapsScaleMode; - std::tie(outputSize, netInputSize, poseModel, scaleMode, heatMapTypes, heatMapsScaleMode) = gflagsToOpParameters(); + op::ScaleMode heatMapScale; + std::tie(outputSize, netInputSize, faceNetInputSize, poseModel, keypointScale, heatMapTypes, heatMapScale) = gflagsToOpParameters(); op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__); // Initializing the user custom classes @@ -348,21 +359,24 @@ int openPoseTutorialWrapper2() const bool displayGui = false; const bool guiVerbose = false; const bool fullScreen = false; - const op::WrapperStructPose wrapperStructPose{netInputSize, outputSize, scaleMode, FLAGS_num_gpu, FLAGS_num_gpu_start, FLAGS_num_scales, (float)FLAGS_scale_gap, - !FLAGS_no_render_output, poseModel, !FLAGS_disable_blending, (float)FLAGS_alpha_pose, (float)FLAGS_alpha_heatmap, - FLAGS_part_to_show, FLAGS_model_folder, heatMapTypes, heatMapsScaleMode}; - const op::WrapperStructOutput wrapperStructOutput{displayGui, guiVerbose, fullScreen, FLAGS_write_pose, op::stringToDataFormat(FLAGS_write_pose_format), - FLAGS_write_pose_json, FLAGS_write_coco_json, FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, - FLAGS_write_heatmaps, FLAGS_write_heatmaps_format}; - // Pose configuration (use WrapperStructPose{} for default and recommended configuration) - // Producer (use default to disable any input) + const op::WrapperStructPose wrapperStructPose{netInputSize, outputSize, keypointScale, FLAGS_num_gpu, FLAGS_num_gpu_start, FLAGS_num_scales, (float)FLAGS_scale_gap, + !FLAGS_no_render_pose, poseModel, !FLAGS_disable_blending, (float)FLAGS_alpha_pose, (float)FLAGS_alpha_heatmap, + FLAGS_part_to_show, FLAGS_model_folder, heatMapTypes, heatMapScale}; + // (Experimental, function and class names might change in next versions) Face configuration (use op::WrapperStructFace{} to disable it) + const op::WrapperStructFace wrapperStructFace{FLAGS_face, faceNetInputSize, !FLAGS_no_render_face, (float)FLAGS_alpha_face, (float)FLAGS_alpha_heatmap_face}; + // (Experimental, function and class names might change in next versions) Hand configuration (use op::WrapperStructFace{} to disable it) + const op::experimental::WrapperStructHand wrapperStructHand{false}; // Consumer (comment or use default argument to disable any output) - opWrapper.configure(wrapperStructPose, op::WrapperStructInput{}, wrapperStructOutput); + const op::WrapperStructOutput wrapperStructOutput{displayGui, guiVerbose, fullScreen, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format), + FLAGS_write_keypoint_json, FLAGS_write_coco_json, FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, + FLAGS_write_heatmaps, FLAGS_write_heatmaps_format}; + // Configure wrapper + opWrapper.configure(wrapperStructPose, wrapperStructFace, wrapperStructHand, op::WrapperStructInput{}, wrapperStructOutput); // Set to single-thread running (e.g. for debugging purposes) // opWrapper.disableMultiThreading(); op::log("Starting thread(s)", op::Priority::Max); - // Two different ways of running the program on multithread enviroment + // Two different ways of running the program on multithread environment // // Option a) Recommended - Also using the main thread (this thread) for processing (it saves 1 thread) // // Start, run & stop threads opWrapper.exec(); // It blocks this thread until all threads have finished diff --git a/include/openpose/core/array.hpp b/include/openpose/core/array.hpp index 6e5c5934..e9a77518 100644 --- a/include/openpose/core/array.hpp +++ b/include/openpose/core/array.hpp @@ -1,8 +1,8 @@ -#ifndef OPENPOSE__CORE__ARRAY_HPP -#define OPENPOSE__CORE__ARRAY_HPP +#ifndef OPENPOSE_CORE_ARRAY_HPP +#define OPENPOSE_CORE_ARRAY_HPP #include -#include +#include // cv::Mat #include // Note: std::shared_ptr not (fully) supported for array pointers: http://stackoverflow.com/questions/8947579/ namespace op @@ -327,6 +327,20 @@ namespace op return at(getIndexAndCheck(indexes)); } + /** + * It returns a string with the whole array data. Useful for debugging. + * The format is: values separated by a space, and a enter for each dimension. E.g.: + * For the Array{2, 2, 3}, it will print: + * Array::toString(): + * x1 x2 x3 + * x4 x5 x6 + * + * x7 x8 x9 + * x10 x11 x12 + * @return A string with the array values in the above format. + */ + const std::string toString() const; + private: std::vector mSize; size_t mVolume; @@ -363,4 +377,4 @@ namespace op }; } -#endif // OPENPOSE__CORE__ARRAY_HPP +#endif // OPENPOSE_CORE_ARRAY_HPP diff --git a/include/openpose/core/cvMatToOpInput.hpp b/include/openpose/core/cvMatToOpInput.hpp index ba2d867a..50fc2e1d 100644 --- a/include/openpose/core/cvMatToOpInput.hpp +++ b/include/openpose/core/cvMatToOpInput.hpp @@ -1,16 +1,17 @@ -#ifndef OPENPOSE__CORE__CV_MAT_TO_OP_INPUT_HPP -#define OPENPOSE__CORE__CV_MAT_TO_OP_INPUT_HPP +#ifndef OPENPOSE_CORE_CV_MAT_TO_OP_INPUT_HPP +#define OPENPOSE_CORE_CV_MAT_TO_OP_INPUT_HPP #include -#include +#include // cv::Mat #include "array.hpp" +#include "point.hpp" namespace op { class CvMatToOpInput { public: - CvMatToOpInput(const cv::Size& netInputResolution, const int scaleNumber = 1, const float scaleGap = 0.25); + CvMatToOpInput(const Point& netInputResolution, const int scaleNumber = 1, const float scaleGap = 0.25); Array format(const cv::Mat& cvInputData) const; @@ -21,4 +22,4 @@ namespace op }; } -#endif // OPENPOSE__CORE__CV_MAT_TO_OP_INPUT_HPP +#endif // OPENPOSE_CORE_CV_MAT_TO_OP_INPUT_HPP diff --git a/include/openpose/core/cvMatToOpOutput.hpp b/include/openpose/core/cvMatToOpOutput.hpp index 4b98c25f..d33dc1a9 100644 --- a/include/openpose/core/cvMatToOpOutput.hpp +++ b/include/openpose/core/cvMatToOpOutput.hpp @@ -1,16 +1,17 @@ -#ifndef OPENPOSE__CORE__CV_MAT_TO_OP_OUTPUT_HPP -#define OPENPOSE__CORE__CV_MAT_TO_OP_OUTPUT_HPP +#ifndef OPENPOSE_CORE_CV_MAT_TO_OP_OUTPUT_HPP +#define OPENPOSE_CORE_CV_MAT_TO_OP_OUTPUT_HPP #include -#include +#include // cv::Mat #include "array.hpp" +#include "point.hpp" namespace op { class CvMatToOpOutput { public: - CvMatToOpOutput(const cv::Size& outputResolution, const bool generateOutput = true); + CvMatToOpOutput(const Point& outputResolution, const bool generateOutput = true); std::tuple> format(const cv::Mat& cvInputData) const; @@ -20,4 +21,4 @@ namespace op }; } -#endif // OPENPOSE__CORE__CV_MAT_TO_OP_OUTPUT_HPP +#endif // OPENPOSE_CORE_CV_MAT_TO_OP_OUTPUT_HPP diff --git a/include/openpose/core/datum.hpp b/include/openpose/core/datum.hpp index 22e558f1..b85e5011 100644 --- a/include/openpose/core/datum.hpp +++ b/include/openpose/core/datum.hpp @@ -1,9 +1,12 @@ -#ifndef OPENPOSE__CORE__DATUM_HPP -#define OPENPOSE__CORE__DATUM_HPP +#ifndef OPENPOSE_CORE_DATUM_HPP +#define OPENPOSE_CORE_DATUM_HPP +#include // std::shared_ptr #include // std::string #include // cv::Mat #include "array.hpp" +#include "point.hpp" +#include "rectangle.hpp" namespace op { @@ -17,7 +20,7 @@ namespace op // -------------------------------------------------- ID parameters -------------------------------------------------- // unsigned long long id; /**< Datum ID. Internally used to sort the Datums if multi-threading is used. */ - std::string name; /**< Name used when saving the data to disk (e.g. `write_images` or `write_pose` flags in the demo). */ + std::string name; /**< Name used when saving the data to disk (e.g. `write_images` or `write_keypoint` flags in the demo). */ // -------------------------------------------------- Input image and rendered version parameters -------------------------------------------------- // /** @@ -37,7 +40,7 @@ namespace op /** * Rendered image in Array format. * It consists of a blending of the inputNetData and the pose/body part(s) heatmap/PAF(s). - * If rendering is disabled (e.g. `no_render_output` flag in the demo), then outputData will be empty. + * If rendering is disabled (e.g. `no_render_pose` flag in the demo), then outputData will be empty. * Size: 3 x output_net_height x output_net_width */ Array outputData; @@ -57,31 +60,38 @@ namespace op * If outputData is empty, then cvOutputData will also be empty. * Size: #people x #body parts (e.g. 18 for COCO or 15 for MPI) x 3 ((x,y) coordinates + score) */ - Array poseKeyPoints; + Array poseKeypoints; /** * Body pose heatmaps (body parts, background and/or PAFs) for the whole image. * This parameters is by default empty and disabled for performance. Each group (body parts, background and PAFs) can be individually enabled. * #heatmaps = #body parts (if enabled) + 1 (if background enabled) + 2 x #PAFs (if enabled). Each PAF has 2 consecutive channels, one for x- and one for y-coordinates. * Order heatmaps: body parts + background (as appears in POSE_BODY_PART_MAPPING) + (x,y) channel of each PAF (sorted as appears in POSE_BODY_PART_PAIRS). See `pose/poseParameters.hpp`. - * The user can choose the heatmaps normalization: ranges [0, 1], [-1, 1] or [0, 255]. Check the `heatmaps_scale_mode` flag in the examples/tutorial_wrapper/ for more details. + * The user can choose the heatmaps normalization: ranges [0, 1], [-1, 1] or [0, 255]. Check the `heatmaps_scale` flag in the examples/tutorial_wrapper/ for more details. * Size: #heatmaps x output_net_height x output_net_width */ Array poseHeatMaps; /** - * Experimental (NOT IMPLEMENTED YET) - * Face code is in development phase. Not included in this version. - * Size: #people's faces to render x #face parts (71) x 3 ((x,y) coordinates + score) + * Face detection locations (x,y,width,height) for each person in the image. + * It has been resized to the same resolution as `poseKeypoints`. + * Size: #people */ - Array faceKeyPoints; + std::vector> faceRectangles; + + /** + * Face keypoints (x,y,score) locations for each person in the image. + * It has been resized to the same resolution as `poseKeypoints`. + * Size: #people x #face parts (70) x 3 ((x,y) coordinates + score) + */ + Array faceKeypoints; /** * Experimental (NOT IMPLEMENTED YET) * Hands code is in development phase. Not included in this version. * Size: #people's hands to render x 2 (right and left hand) x #hand parts (21) x 3 ((x,y) coordinates + score) */ - Array handKeyPoints; + Array handKeypoints; // -------------------------------------------------- Other parameters -------------------------------------------------- // double scaleInputToOutput; /**< Scale ratio between the input Datum::cvInputData and the output Datum::cvOutputData. */ @@ -209,4 +219,4 @@ namespace op }; } -#endif // OPENPOSE__CORE__DATUM_HPP +#endif // OPENPOSE_CORE_DATUM_HPP diff --git a/include/openpose/core/enumClasses.hpp b/include/openpose/core/enumClasses.hpp index a2e8b184..f7821883 100644 --- a/include/openpose/core/enumClasses.hpp +++ b/include/openpose/core/enumClasses.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__CORE__ENUM_CLASSES_HPP -#define OPENPOSE__CORE__ENUM_CLASSES_HPP +#ifndef OPENPOSE_CORE_ENUM_CLASSES_HPP +#define OPENPOSE_CORE_ENUM_CLASSES_HPP namespace op { @@ -21,4 +21,4 @@ namespace op }; } -#endif // OPENPOSE__CORE__ENUM_CLASSES_HPP +#endif // OPENPOSE_CORE_ENUM_CLASSES_HPP diff --git a/include/openpose/core/headers.hpp b/include/openpose/core/headers.hpp index 1075cf7c..89655e5e 100644 --- a/include/openpose/core/headers.hpp +++ b/include/openpose/core/headers.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__CORE__HEADERS_HPP -#define OPENPOSE__CORE__HEADERS_HPP +#ifndef OPENPOSE_CORE_HEADERS_HPP +#define OPENPOSE_CORE_HEADERS_HPP // core module #include "array.hpp" @@ -7,19 +7,21 @@ #include "cvMatToOpOutput.hpp" #include "datum.hpp" #include "enumClasses.hpp" -#include "keyPointScaler.hpp" +#include "keypointScaler.hpp" #include "net.hpp" #include "netCaffe.hpp" #include "nmsBase.hpp" #include "nmsCaffe.hpp" #include "opOutputToCvMat.hpp" +#include "point.hpp" +#include "rectangle.hpp" #include "renderer.hpp" #include "resizeAndMergeBase.hpp" #include "resizeAndMergeCaffe.hpp" -#include "scaleKeyPoints.hpp" +#include "scaleKeypoints.hpp" #include "wCvMatToOpInput.hpp" #include "wCvMatToOpOutput.hpp" -#include "wKeyPointScaler.hpp" +#include "wKeypointScaler.hpp" #include "wOpOutputToCvMat.hpp" -#endif // OPENPOSE__CORE__HEADERS_HPP +#endif // OPENPOSE_CORE_HEADERS_HPP diff --git a/include/openpose/core/keyPointScaler.hpp b/include/openpose/core/keypointScaler.hpp similarity index 50% rename from include/openpose/core/keyPointScaler.hpp rename to include/openpose/core/keypointScaler.hpp index 9ed2e139..1046aee4 100644 --- a/include/openpose/core/keyPointScaler.hpp +++ b/include/openpose/core/keypointScaler.hpp @@ -1,24 +1,25 @@ -#ifndef OPENPOSE__CORE__KEY_POINT_SCALER_HPP -#define OPENPOSE__CORE__KEY_POINT_SCALER_HPP +#ifndef OPENPOSE_CORE_KEYPOINT_SCALER_HPP +#define OPENPOSE_CORE_KEYPOINT_SCALER_HPP #include #include "array.hpp" +#include "point.hpp" #include "enumClasses.hpp" namespace op { - class KeyPointScaler + class KeypointScaler { public: - explicit KeyPointScaler(const ScaleMode scaleMode); + explicit KeypointScaler(const ScaleMode scaleMode); - void scale(Array& arrayToScale, const float scaleInputToOutput, const float scaleNetToOutput, const cv::Size& producerSize) const; + void scale(Array& arrayToScale, const float scaleInputToOutput, const float scaleNetToOutput, const Point& producerSize) const; - void scale(std::vector>& arraysToScale, const float scaleInputToOutput, const float scaleNetToOutput, const cv::Size& producerSize) const; + void scale(std::vector>& arraysToScale, const float scaleInputToOutput, const float scaleNetToOutput, const Point& producerSize) const; private: const ScaleMode mScaleMode; }; } -#endif // OPENPOSE__CORE__KEY_POINT_SCALER_HPP +#endif // OPENPOSE_CORE_KEYPOINT_SCALER_HPP diff --git a/include/openpose/core/net.hpp b/include/openpose/core/net.hpp index 6bb76222..fe8035d1 100644 --- a/include/openpose/core/net.hpp +++ b/include/openpose/core/net.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__CORE__NET_HPP -#define OPENPOSE__CORE__NET_HPP +#ifndef OPENPOSE_CORE_NET_HPP +#define OPENPOSE_CORE_NET_HPP namespace op { @@ -18,4 +18,4 @@ namespace op }; } -#endif // OPENPOSE__CORE__NET_HPP +#endif // OPENPOSE_CORE_NET_HPP diff --git a/include/openpose/core/netCaffe.hpp b/include/openpose/core/netCaffe.hpp index 6f271f60..38615492 100644 --- a/include/openpose/core/netCaffe.hpp +++ b/include/openpose/core/netCaffe.hpp @@ -1,6 +1,6 @@ #ifdef USE_CAFFE -#ifndef OPENPOSE__CORE__NET_CAFFE_HPP -#define OPENPOSE__CORE__NET_CAFFE_HPP +#ifndef OPENPOSE_CORE_NET_CAFFE_HPP +#define OPENPOSE_CORE_NET_CAFFE_HPP #include #include // std::shared_ptr @@ -47,5 +47,5 @@ namespace op }; } -#endif // OPENPOSE__CORE__NET_CAFFE_HPP +#endif // OPENPOSE_CORE_NET_CAFFE_HPP #endif diff --git a/include/openpose/core/nmsBase.hpp b/include/openpose/core/nmsBase.hpp index 069decf9..b591b659 100644 --- a/include/openpose/core/nmsBase.hpp +++ b/include/openpose/core/nmsBase.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__CORE__NMS_BASE_HPP -#define OPENPOSE__CORE__NMS_BASE_HPP +#ifndef OPENPOSE_CORE_NMS_BASE_HPP +#define OPENPOSE_CORE_NMS_BASE_HPP #include @@ -12,4 +12,4 @@ namespace op void nmsGpu(T* targetPtr, int* kernelPtr, const T* const sourcePtr, const T threshold, const std::array& targetSize, const std::array& sourceSize); } -#endif // OPENPOSE__CORE__NMS_BASE_HPP +#endif // OPENPOSE_CORE_NMS_BASE_HPP diff --git a/include/openpose/core/nmsCaffe.hpp b/include/openpose/core/nmsCaffe.hpp index 5fcbe8a8..cc393f20 100644 --- a/include/openpose/core/nmsCaffe.hpp +++ b/include/openpose/core/nmsCaffe.hpp @@ -1,6 +1,6 @@ #ifdef USE_CAFFE -#ifndef OPENPOSE__CORE__NMS_CAFFE_HPP -#define OPENPOSE__CORE__NMS_CAFFE_HPP +#ifndef OPENPOSE_CORE_NMS_CAFFE_HPP +#define OPENPOSE_CORE_NMS_CAFFE_HPP #include #include "caffe/blob.hpp" @@ -39,5 +39,5 @@ namespace op }; } -#endif // OPENPOSE__CORE__NMS_CAFFE_HPP +#endif // OPENPOSE_CORE_NMS_CAFFE_HPP #endif diff --git a/include/openpose/core/opOutputToCvMat.hpp b/include/openpose/core/opOutputToCvMat.hpp index 30a41977..b3e60d62 100644 --- a/include/openpose/core/opOutputToCvMat.hpp +++ b/include/openpose/core/opOutputToCvMat.hpp @@ -1,21 +1,22 @@ -#ifndef OPENPOSE__CORE__OP_OUTPUT_TO_CV_MAT_HPP -#define OPENPOSE__CORE__OP_OUTPUT_TO_CV_MAT_HPP +#ifndef OPENPOSE_CORE_OP_OUTPUT_TO_CV_MAT_HPP +#define OPENPOSE_CORE_OP_OUTPUT_TO_CV_MAT_HPP -#include +#include // cv::Mat #include "array.hpp" +#include "point.hpp" namespace op { class OpOutputToCvMat { public: - explicit OpOutputToCvMat(const cv::Size& outputResolution); + explicit OpOutputToCvMat(const Point& outputResolution); cv::Mat formatToCvMat(const Array& outputData) const; private: - const cv::Size mOutputResolution; + const Point mOutputResolution; }; } -#endif // OPENPOSE__CORE__OP_OUTPUT_TO_CV_MAT_HPP +#endif // OPENPOSE_CORE_OP_OUTPUT_TO_CV_MAT_HPP diff --git a/include/openpose/core/point.hpp b/include/openpose/core/point.hpp new file mode 100644 index 00000000..f979bad6 --- /dev/null +++ b/include/openpose/core/point.hpp @@ -0,0 +1,136 @@ +#ifndef OPENPOSE_CORE_POINT_HPP +#define OPENPOSE_CORE_POINT_HPP + +namespace op +{ + template + struct Point + { + T x; + T y; + + Point(const T x = -1, const T y = -1); + + /** + * Copy constructor. + * It performs `fast copy`: For performance purpose, copying a Point or Point or cv::Mat just copies the reference, it still shares the same internal data. + * Modifying the copied element will modify the original one. + * Use clone() for a slower but real copy, similarly to cv::Mat and Point. + * @param point Point to be copied. + */ + Point(const Point& point); + + /** + * Copy assignment. + * Similar to Point(const Point& point). + * @param point Point to be copied. + * @return The resulting Point. + */ + Point& operator=(const Point& point); + + /** + * Move constructor. + * It destroys the original Point to be moved. + * @param point Point to be moved. + */ + Point(Point&& point); + + /** + * Move assignment. + * Similar to Point(Point&& point). + * @param point Point to be moved. + * @return The resulting Point. + */ + Point& operator=(Point&& point); + + inline T area() const + { + return x * y; + } + + + + + + // -------------------------------------------------- Comparison operators -------------------------------------------------- // + /** + * Less comparison operator. + * @param point Point to be compared. + * @result Whether the instance satisfies the condition with respect to point. + */ + inline bool operator<(const Point& point) const + { + return area() < point.area(); + } + + /** + * Greater comparison operator. + * @param point Point to be compared. + * @result Whether the instance satisfies the condition with respect to point. + */ + inline bool operator>(const Point& point) const + { + return area() > point.area(); + } + + /** + * Less or equal comparison operator. + * @param point Point to be compared. + * @result Whether the instance satisfies the condition with respect to point. + */ + inline bool operator<=(const Point& point) const + { + return area() <= point.area(); + } + + /** + * Greater or equal comparison operator. + * @param point Point to be compared. + * @result Whether the instance satisfies the condition with respect to point. + */ + inline bool operator>=(const Point& point) const + { + return area() >= point.area(); + } + + /** + * Equal comparison operator. + * @param point Point to be compared. + * @result Whether the instance satisfies the condition with respect to point. + */ + inline bool operator==(const Point& point) const + { + return area() == point.area(); + } + + /** + * Not equal comparison operator. + * @param point Point to be compared. + * @result Whether the instance satisfies the condition with respect to point. + */ + inline bool operator!=(const Point& point) const + { + return area() != point.area(); + } + + + + + + // -------------------------------------------------- Basic Operators -------------------------------------------------- // + Point& operator+=(const Point& point); + + Point& operator+=(const T value); + + Point& operator-=(const Point& point); + + Point& operator-=(const T value); + + Point& operator*=(const T value); + + Point& operator/=(const T value); + + }; +} + +#endif // OPENPOSE_CORE_POINT_HPP diff --git a/include/openpose/core/rectangle.hpp b/include/openpose/core/rectangle.hpp new file mode 100644 index 00000000..99422b15 --- /dev/null +++ b/include/openpose/core/rectangle.hpp @@ -0,0 +1,66 @@ +#ifndef OPENPOSE_CORE_RECTANGLE_HPP +#define OPENPOSE_CORE_RECTANGLE_HPP + +#include "point.hpp" + +namespace op +{ + template + struct Rectangle + { + T x; + T y; + T width; + T height; + + Rectangle(const T x = 0, const T y = 0, const T width = 0, const T height = 0); + + /** + * Copy constructor. + * It performs `fast copy`: For performance purpose, copying a Rectangle or Datum or cv::Mat just copies the reference, it still shares the same internal data. + * Modifying the copied element will modify the original one. + * Use clone() for a slower but real copy, similarly to cv::Mat and Rectangle. + * @param rectangle Rectangle to be copied. + */ + Rectangle(const Rectangle& rectangle); + + /** + * Copy assignment. + * Similar to Rectangle(const Rectangle& rectangle). + * @param rectangle Rectangle to be copied. + * @return The resulting Rectangle. + */ + Rectangle& operator=(const Rectangle& rectangle); + + /** + * Move constructor. + * It destroys the original Rectangle to be moved. + * @param rectangle Rectangle to be moved. + */ + Rectangle(Rectangle&& rectangle); + + /** + * Move assignment. + * Similar to Rectangle(Rectangle&& rectangle). + * @param rectangle Rectangle to be moved. + * @return The resulting Rectangle. + */ + Rectangle& operator=(Rectangle&& rectangle); + + Point center() const; + + inline Point topLeft() const + { + return Point{x, y}; + } + + Point bottomRight() const; + + inline T area() const + { + return width * height; + } + }; +} + +#endif // OPENPOSE_CORE_RECTANGLE_HPP diff --git a/include/openpose/core/renderer.hpp b/include/openpose/core/renderer.hpp index f3867a5e..b3d717b1 100644 --- a/include/openpose/core/renderer.hpp +++ b/include/openpose/core/renderer.hpp @@ -1,6 +1,7 @@ -#ifndef OPENPOSE__CORE__RENDERER_HPP -#define OPENPOSE__CORE__RENDERER_HPP +#ifndef OPENPOSE_CORE_RENDERER_HPP +#define OPENPOSE_CORE_RENDERER_HPP +#include #include // std::shared_ptr #include @@ -9,18 +10,34 @@ namespace op class Renderer { public: - explicit Renderer(const unsigned long long volume); + explicit Renderer(const unsigned long long volume, const float alphaKeypoint, const float alphaHeatMap, const unsigned int elementToRender = 0u, + const unsigned int numberElementsToRender = 0u); ~Renderer(); void initializationOnThread(); - std::pair, std::shared_ptr> getGpuMemoryAndSetAsFirst(); + void increaseElementToRender(const int increment); - void setGpuMemoryAndSetIfLast(const std::pair, std::shared_ptr>& gpuMemory, const bool isLast); + void setElementToRender(const int elementToRender); + + std::tuple, std::shared_ptr, std::shared_ptr>, std::shared_ptr> getSharedParameters(); + + void setSharedParametersAndIfLast(const std::tuple, std::shared_ptr, std::shared_ptr>, + std::shared_ptr>& tuple, const bool isLast); + + float getAlphaKeypoint() const; + + void setAlphaKeypoint(const float alphaKeypoint); + + float getAlphaHeatMap() const; + + void setAlphaHeatMap(const float alphaHeatMap); protected: std::shared_ptr spGpuMemoryPtr; + std::shared_ptr> spElementToRender; + std::shared_ptr spNumberElementsToRender; void cpuToGpuMemoryIfNotCopiedYet(const float* const cpuMemory); @@ -28,6 +45,8 @@ namespace op private: const unsigned long long mVolume; + float mAlphaKeypoint; + float mAlphaHeatMap; bool mIsFirstRenderer; bool mIsLastRenderer; std::shared_ptr spGpuMemoryAllocated; @@ -36,4 +55,4 @@ namespace op }; } -#endif // OPENPOSE__CORE__RENDERER_HPP +#endif // OPENPOSE_CORE_RENDERER_HPP diff --git a/include/openpose/core/resizeAndMergeBase.hpp b/include/openpose/core/resizeAndMergeBase.hpp index ce69c035..b36d51a5 100644 --- a/include/openpose/core/resizeAndMergeBase.hpp +++ b/include/openpose/core/resizeAndMergeBase.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__CORE__RESIZE_AND_MERGE_BASE_HPP -#define OPENPOSE__CORE__RESIZE_AND_MERGE_BASE_HPP +#ifndef OPENPOSE_CORE_RESIZE_AND_MERGE_BASE_HPP +#define OPENPOSE_CORE_RESIZE_AND_MERGE_BASE_HPP #include @@ -12,4 +12,4 @@ namespace op void resizeAndMergeGpu(T* targetPtr, const T* const sourcePtr, const std::array& targetSize, const std::array& sourceSize, const T scaleGap = 0.f); } -#endif // OPENPOSE__CORE__RESIZE_AND_MERGE_BASE_HPP +#endif // OPENPOSE_CORE_RESIZE_AND_MERGE_BASE_HPP diff --git a/include/openpose/core/resizeAndMergeCaffe.hpp b/include/openpose/core/resizeAndMergeCaffe.hpp index 371841cf..2e1d1ef6 100644 --- a/include/openpose/core/resizeAndMergeCaffe.hpp +++ b/include/openpose/core/resizeAndMergeCaffe.hpp @@ -1,6 +1,6 @@ #ifdef USE_CAFFE -#ifndef OPENPOSE__CORE__RESIZE_AND_MERGE_CAFFE_HPP -#define OPENPOSE__CORE__RESIZE_AND_MERGE_CAFFE_HPP +#ifndef OPENPOSE_CORE_RESIZE_AND_MERGE_CAFFE_HPP +#define OPENPOSE_CORE_RESIZE_AND_MERGE_CAFFE_HPP #include #include @@ -41,5 +41,5 @@ namespace op }; } -#endif // OPENPOSE__CORE__RESIZE_AND_MERGE_CAFFE_HPP +#endif // OPENPOSE_CORE_RESIZE_AND_MERGE_CAFFE_HPP #endif diff --git a/include/openpose/core/scaleKeyPoints.hpp b/include/openpose/core/scaleKeyPoints.hpp deleted file mode 100644 index 91689c10..00000000 --- a/include/openpose/core/scaleKeyPoints.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef OPENPOSE__CORE__SCALE_KEY_POINTS_HPP -#define OPENPOSE__CORE__SCALE_KEY_POINTS_HPP - -#include "array.hpp" - -namespace op -{ - void scaleKeyPoints(Array& keyPoints, const float scale); - - void scaleKeyPoints(Array& keyPoints, const float scaleX, const float scaleY); - - void scaleKeyPoints(Array& keyPoints, const float scaleX, const float scaleY, const float offsetX, const float offsetY); -} - -#endif // OPENPOSE__CORE__SCALE_KEY_POINTS_HPP diff --git a/include/openpose/core/scaleKeypoints.hpp b/include/openpose/core/scaleKeypoints.hpp new file mode 100644 index 00000000..3c1a7e54 --- /dev/null +++ b/include/openpose/core/scaleKeypoints.hpp @@ -0,0 +1,15 @@ +#ifndef OPENPOSE_CORE_SCALE_KEYPOINTS_HPP +#define OPENPOSE_CORE_SCALE_KEYPOINTS_HPP + +#include "array.hpp" + +namespace op +{ + void scaleKeypoints(Array& keypoints, const float scale); + + void scaleKeypoints(Array& keypoints, const float scaleX, const float scaleY); + + void scaleKeypoints(Array& keypoints, const float scaleX, const float scaleY, const float offsetX, const float offsetY); +} + +#endif // OPENPOSE_CORE_SCALE_KEYPOINTS_HPP diff --git a/include/openpose/core/wCvMatToOpInput.hpp b/include/openpose/core/wCvMatToOpInput.hpp index 917f6726..06bd7cec 100644 --- a/include/openpose/core/wCvMatToOpInput.hpp +++ b/include/openpose/core/wCvMatToOpInput.hpp @@ -1,8 +1,7 @@ -#ifndef OPENPOSE__CORE__W_CV_MAT_TO_OP_INPUT_HPP -#define OPENPOSE__CORE__W_CV_MAT_TO_OP_INPUT_HPP +#ifndef OPENPOSE_CORE_W_CV_MAT_TO_OP_INPUT_HPP +#define OPENPOSE_CORE_W_CV_MAT_TO_OP_INPUT_HPP #include // std::shared_ptr -#include #include #include "cvMatToOpInput.hpp" @@ -80,4 +79,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WCvMatToOpInput); } -#endif // OPENPOSE__CORE__W_CV_MAT_TO_OP_INPUT_HPP +#endif // OPENPOSE_CORE_W_CV_MAT_TO_OP_INPUT_HPP diff --git a/include/openpose/core/wCvMatToOpOutput.hpp b/include/openpose/core/wCvMatToOpOutput.hpp index 1ff63fe0..4caea653 100644 --- a/include/openpose/core/wCvMatToOpOutput.hpp +++ b/include/openpose/core/wCvMatToOpOutput.hpp @@ -1,8 +1,7 @@ -#ifndef OPENPOSE__CORE__W_CV_MAT_TO_OP_OUTPUT_HPP -#define OPENPOSE__CORE__W_CV_MAT_TO_OP_OUTPUT_HPP +#ifndef OPENPOSE_CORE_W_CV_MAT_TO_OP_OUTPUT_HPP +#define OPENPOSE_CORE_W_CV_MAT_TO_OP_OUTPUT_HPP #include // std::shared_ptr -#include #include #include "cvMatToOpOutput.hpp" @@ -82,4 +81,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WCvMatToOpOutput); } -#endif // OPENPOSE__CORE__W_CV_MAT_TO_OP_OUTPUT_HPP +#endif // OPENPOSE_CORE_W_CV_MAT_TO_OP_OUTPUT_HPP diff --git a/include/openpose/core/wKeyPointScaler.hpp b/include/openpose/core/wKeypointScaler.hpp similarity index 62% rename from include/openpose/core/wKeyPointScaler.hpp rename to include/openpose/core/wKeypointScaler.hpp index 831e2fdf..64f159a0 100644 --- a/include/openpose/core/wKeyPointScaler.hpp +++ b/include/openpose/core/wKeypointScaler.hpp @@ -1,24 +1,24 @@ -#ifndef OPENPOSE__CORE__W_KEY_POINT_SCALER_HPP -#define OPENPOSE__CORE__W_KEY_POINT_SCALER_HPP +#ifndef OPENPOSE_CORE_W_KEYPOINT_SCALER_HPP +#define OPENPOSE_CORE_W_KEYPOINT_SCALER_HPP #include -#include "keyPointScaler.hpp" -#include "scaleKeyPoints.hpp" +#include "keypointScaler.hpp" +#include "scaleKeypoints.hpp" namespace op { template - class WKeyPointScaler : public Worker + class WKeypointScaler : public Worker { public: - explicit WKeyPointScaler(const std::shared_ptr& keyPointScaler); + explicit WKeypointScaler(const std::shared_ptr& keypointScaler); void initializationOnThread(); void work(TDatums& tDatums); private: - std::shared_ptr spKeyPointScaler; + std::shared_ptr spKeypointScaler; }; } @@ -34,18 +34,18 @@ namespace op namespace op { template - WKeyPointScaler::WKeyPointScaler(const std::shared_ptr& keyPointScaler) : - spKeyPointScaler{keyPointScaler} + WKeypointScaler::WKeypointScaler(const std::shared_ptr& keypointScaler) : + spKeypointScaler{keypointScaler} { } template - void WKeyPointScaler::initializationOnThread() + void WKeypointScaler::initializationOnThread() { } template - void WKeyPointScaler::work(TDatums& tDatums) + void WKeypointScaler::work(TDatums& tDatums) { try { @@ -58,8 +58,8 @@ namespace op // Rescale pose data for (auto& tDatum : *tDatums) { - std::vector> arraysToScale{tDatum.poseKeyPoints, tDatum.handKeyPoints, tDatum.faceKeyPoints}; - spKeyPointScaler->scale(arraysToScale, (float)tDatum.scaleInputToOutput, (float)tDatum.scaleNetToOutput, tDatum.cvInputData.size()); + std::vector> arraysToScale{tDatum.poseKeypoints, tDatum.handKeypoints, tDatum.faceKeypoints}; + spKeypointScaler->scale(arraysToScale, (float)tDatum.scaleInputToOutput, (float)tDatum.scaleNetToOutput, Point{tDatum.cvInputData.cols, tDatum.cvInputData.rows}); } // Profiling speed Profiler::timerEnd(profilerKey); @@ -76,7 +76,7 @@ namespace op } } - COMPILE_TEMPLATE_DATUM(WKeyPointScaler); + COMPILE_TEMPLATE_DATUM(WKeypointScaler); } -#endif // OPENPOSE__CORE__W_KEY_POINT_SCALER_HPP +#endif // OPENPOSE_CORE_W_KEYPOINT_SCALER_HPP diff --git a/include/openpose/core/wOpOutputToCvMat.hpp b/include/openpose/core/wOpOutputToCvMat.hpp index 513e8012..c8ea1ccd 100644 --- a/include/openpose/core/wOpOutputToCvMat.hpp +++ b/include/openpose/core/wOpOutputToCvMat.hpp @@ -1,8 +1,7 @@ -#ifndef OPENPOSE__CORE__W_OP_OUTPUT_TO_CV_MAT_HPP -#define OPENPOSE__CORE__W_OP_OUTPUT_TO_CV_MAT_HPP +#ifndef OPENPOSE_CORE_W_OP_OUTPUT_TO_CV_MAT_HPP +#define OPENPOSE_CORE_W_OP_OUTPUT_TO_CV_MAT_HPP #include // std::shared_ptr -#include #include #include "opOutputToCvMat.hpp" @@ -80,4 +79,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WOpOutputToCvMat); } -#endif // OPENPOSE__CORE__W_OP_OUTPUT_TO_CV_MAT_HPP +#endif // OPENPOSE_CORE_W_OP_OUTPUT_TO_CV_MAT_HPP diff --git a/include/openpose/experimental/face/enumClasses.hpp b/include/openpose/experimental/face/enumClasses.hpp deleted file mode 100644 index be06948e..00000000 --- a/include/openpose/experimental/face/enumClasses.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef OPENPOSE__FACE__ENUM_CLASSES_HPP -#define OPENPOSE__FACE__ENUM_CLASSES_HPP - -namespace op -{ - enum class FaceProperty : bool - { - NMSThreshold = 0, - Size, - }; -} - -#endif // OPENPOSE__FACE__ENUM_CLASSES_HPP - diff --git a/include/openpose/experimental/face/faceExtractor.hpp b/include/openpose/experimental/face/faceExtractor.hpp deleted file mode 100644 index 8c6a96ef..00000000 --- a/include/openpose/experimental/face/faceExtractor.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef OPENPOSE__FACE__FACE_EXTRACTOR_HPP -#define OPENPOSE__FACE__FACE_EXTRACTOR_HPP - -#include -#include -#include // std::shared_ptr -#include -#include -#include -#include -#include -#include -#include -#include "enumClasses.hpp" - -namespace op -{ - namespace experimental - { - class FaceExtractor - { - public: - explicit FaceExtractor(const std::string& modelFolder, const int gpuId, const PoseModel poseModel); - - void initializationOnThread(); - - void forwardPass(const Array& poseKeyPoints, const cv::Mat& cvInputData); - - Array getFaceKeyPoints() const; - - double get(const FaceProperty property) const; - - void set(const FaceProperty property, const double value); - - void increase(const FaceProperty property, const double value); - - private: - const cv::Size mNetOutputSize; - const cv::Size mOutputSize; - const unsigned int mNeck; - const unsigned int mNose; - const unsigned int mLEar; - const unsigned int mREar; - const unsigned int mLEye; - const unsigned int mREye; - std::array, (int)FaceProperty::Size> mProperties; - std::shared_ptr spNet; - std::shared_ptr> spResizeAndMergeCaffe; - std::shared_ptr> spNmsCaffe; - Array mFaceImageCrop; - Array mFaceKeyPoints; - float mScaleFace; - // Init with thread - boost::shared_ptr> spCaffeNetOutputBlob; - std::shared_ptr> spHeatMapsBlob; - std::shared_ptr> spPeaksBlob; - std::thread::id mThreadId; - - void checkThread() const; - - DELETE_COPY(FaceExtractor); - }; - } -} - -#endif // OPENPOSE__FACE__FACE_EXTRACTOR_HPP diff --git a/include/openpose/experimental/face/faceRenderGpu.hpp b/include/openpose/experimental/face/faceRenderGpu.hpp deleted file mode 100644 index 80cdaab7..00000000 --- a/include/openpose/experimental/face/faceRenderGpu.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef OPENPOSE__FACE__GPU_FACE_RENDER_HPP -#define OPENPOSE__FACE__GPU_FACE_RENDER_HPP - -#include -#include "faceParameters.hpp" - -namespace op -{ - void renderFaceGpu(float* framePtr, const cv::Size& frameSize, const float* const facePtr, const int numberFace, const float alphaColorToAdd = FACE_DEFAULT_ALPHA_FACE); -} - -#endif // OPENPOSE__FACE__GPU_FACE_RENDER_HPP diff --git a/include/openpose/experimental/face/faceRenderer.hpp b/include/openpose/experimental/face/faceRenderer.hpp deleted file mode 100644 index 102af65c..00000000 --- a/include/openpose/experimental/face/faceRenderer.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef OPENPOSE__FACE__FACE_RENDERER_HPP -#define OPENPOSE__FACE__FACE_RENDERER_HPP - -#include -#include -#include -#include - -namespace op -{ - namespace experimental - { - class FaceRenderer : public Renderer - { - public: - explicit FaceRenderer(const cv::Size& frameSize); - - ~FaceRenderer(); - - void initializationOnThread(); - - void renderFace(Array& outputData, const Array& faceKeyPoints); - - private: - const cv::Size mFrameSize; - float* pGpuFace; // GPU aux memory - - DELETE_COPY(FaceRenderer); - }; - } -} - -#endif // OPENPOSE__FACE__FACE_RENDERER_HPP diff --git a/include/openpose/experimental/face/wFaceExtractor.hpp b/include/openpose/experimental/face/wFaceExtractor.hpp deleted file mode 100644 index 06b6addc..00000000 --- a/include/openpose/experimental/face/wFaceExtractor.hpp +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef OPENPOSE__FACE__W_FACE_EXTRACTOR_HPP -#define OPENPOSE__FACE__W_FACE_EXTRACTOR_HPP - -#include // std::shared_ptr -#include -#include "faceRenderer.hpp" - -namespace op -{ - namespace experimental - { - template - class WFaceExtractor : public Worker - { - public: - explicit WFaceExtractor(const std::shared_ptr& faceExtractor); - - void initializationOnThread(); - - void work(TDatums& tDatums); - - private: - std::shared_ptr spFaceExtractor; - - DELETE_COPY(WFaceExtractor); - }; - } -} - - - - - -// Implementation -#include -#include -#include -#include -namespace op -{ - namespace experimental - { - template - WFaceExtractor::WFaceExtractor(const std::shared_ptr& faceExtractor) : - spFaceExtractor{faceExtractor} - { - } - - template - void WFaceExtractor::initializationOnThread() - { - spFaceExtractor->initializationOnThread(); - } - - template - void WFaceExtractor::work(TDatums& tDatums) - { - try - { - if (checkNoNullNorEmpty(tDatums)) - { - // Debugging log - dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); - // Profiling speed - const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); - // Extract people face - for (auto& tDatum : *tDatums) - { - spFaceExtractor->forwardPass(tDatum.poseKeyPoints, tDatum.cvInputData); - tDatum.faceKeyPoints = spFaceExtractor->getFaceKeyPoints(); - } - // Profiling speed - Profiler::timerEnd(profilerKey); - Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); - // Debugging log - dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); - } - } - catch (const std::exception& e) - { - this->stop(); - tDatums = nullptr; - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - - COMPILE_TEMPLATE_DATUM(WFaceExtractor); - } -} - -#endif // OPENPOSE__FACE__W_FACE_EXTRACTOR_HPP diff --git a/include/openpose/experimental/face/wFaceRenderer.hpp b/include/openpose/experimental/face/wFaceRenderer.hpp deleted file mode 100644 index 07eeb71d..00000000 --- a/include/openpose/experimental/face/wFaceRenderer.hpp +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef OPENPOSE__FACE__W_FACE_RENDERER_HPP -#define OPENPOSE__FACE__W_FACE_RENDERER_HPP - -#include // std::shared_ptr -#include -#include "faceRenderer.hpp" - -namespace op -{ - namespace experimental - { - template - class WFaceRenderer : public Worker - { - public: - explicit WFaceRenderer(const std::shared_ptr& faceRenderer); - - void initializationOnThread(); - - void work(TDatums& tDatums); - - private: - std::shared_ptr spFaceRenderer; - - DELETE_COPY(WFaceRenderer); - }; - } -} - - - - - -// Implementation -#include -#include -#include -#include -namespace op -{ - namespace experimental - { - template - WFaceRenderer::WFaceRenderer(const std::shared_ptr& faceRenderer) : - spFaceRenderer{faceRenderer} - { - } - - template - void WFaceRenderer::initializationOnThread() - { - spFaceRenderer->initializationOnThread(); - } - - template - void WFaceRenderer::work(TDatums& tDatums) - { - try - { - if (checkNoNullNorEmpty(tDatums)) - { - // Debugging log - dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); - // Profiling speed - const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); - // Render people face - for (auto& tDatum : *tDatums) - spFaceRenderer->renderFace(tDatum.outputData, tDatum.faceKeyPoints); - // Profiling speed - Profiler::timerEnd(profilerKey); - Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); - // Debugging log - dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); - } - } - catch (const std::exception& e) - { - this->stop(); - tDatums = nullptr; - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - - COMPILE_TEMPLATE_DATUM(WFaceRenderer); - } -} - -#endif // OPENPOSE__FACE__W_FACE_RENDERER_HPP diff --git a/include/openpose/experimental/filestream/headers.hpp b/include/openpose/experimental/filestream/headers.hpp index 7bc7214c..d7bf287f 100644 --- a/include/openpose/experimental/filestream/headers.hpp +++ b/include/openpose/experimental/filestream/headers.hpp @@ -1,7 +1,7 @@ -#ifndef OPENPOSE__EXPERIMENTAL__FILESTREAM__HEADERS_HPP -#define OPENPOSE__EXPERIMENTAL__FILESTREAM__HEADERS_HPP +#ifndef OPENPOSE_EXPERIMENTAL_FILESTREAM_HEADERS_HPP +#define OPENPOSE_EXPERIMENTAL_FILESTREAM_HEADERS_HPP // storage module -#include "wPoseJsonCocoSaver.hpp" +#include "wCocoJsonSaver.hpp" -#endif // OPENPOSE__EXPERIMENTAL__FILESTREAM__HEADERS_HPP +#endif // OPENPOSE_EXPERIMENTAL_FILESTREAM_HEADERS_HPP diff --git a/include/openpose/experimental/filestream/wPoseJsonCocoSaver.hpp b/include/openpose/experimental/filestream/wCocoJsonSaver.hpp similarity index 74% rename from include/openpose/experimental/filestream/wPoseJsonCocoSaver.hpp rename to include/openpose/experimental/filestream/wCocoJsonSaver.hpp index b3c1bf53..dd57814d 100644 --- a/include/openpose/experimental/filestream/wPoseJsonCocoSaver.hpp +++ b/include/openpose/experimental/filestream/wCocoJsonSaver.hpp @@ -1,11 +1,11 @@ // THE CLASSES INSIDE THE experimental NAMESPACE ARE STILL BEING DEVELOPED, WE HIGHLY RECOMMEND NOT TO USE THEM -// The results are not the same as the one obtained with Matlab, so there is a bug somewhere in this class or in PoseJsonCocoSaver. +// The results are not the same as the one obtained with Matlab, so there is a bug somewhere in this class or in CocoJsonSaver. -#ifndef OPENPOSE__EXPERIMENTAL__FILESTREAM__W_POSE_JSON_COCO_SAVER_HPP -#define OPENPOSE__EXPERIMENTAL__FILESTREAM__W_POSE_JSON_COCO_SAVER_HPP +#ifndef OPENPOSE_FILESTREAM_W_COCO_JSON_SAVER_HPP +#define OPENPOSE_FILESTREAM_W_COCO_JSON_SAVER_HPP #include // std::shared_ptr -#include +#include #include namespace op @@ -13,19 +13,19 @@ namespace op namespace experimental { template - class WPoseJsonCocoSaver : public WorkerConsumer + class WCocoJsonSaver : public WorkerConsumer { public: - explicit WPoseJsonCocoSaver(const std::shared_ptr& poseJsonCocoSaver); + explicit WCocoJsonSaver(const std::shared_ptr& cocoJsonSaver); void initializationOnThread(); void workConsumer(const TDatums& tDatums); private: - std::shared_ptr spPoseJsonCocoSaver; + std::shared_ptr spCocoJsonSaver; - DELETE_COPY(WPoseJsonCocoSaver); + DELETE_COPY(WCocoJsonSaver); }; } } @@ -44,18 +44,18 @@ namespace op namespace experimental { template - WPoseJsonCocoSaver::WPoseJsonCocoSaver(const std::shared_ptr& poseJsonCocoSaver) : - spPoseJsonCocoSaver{poseJsonCocoSaver} + WCocoJsonSaver::WCocoJsonSaver(const std::shared_ptr& cocoJsonSaver) : + spCocoJsonSaver{cocoJsonSaver} { } template - void WPoseJsonCocoSaver::initializationOnThread() + void WCocoJsonSaver::initializationOnThread() { } template - void WPoseJsonCocoSaver::workConsumer(const TDatums& tDatums) + void WCocoJsonSaver::workConsumer(const TDatums& tDatums) { try { @@ -78,7 +78,7 @@ namespace op if (imageId <= 50006) // 3559 images ~ 4 min at 15fps // move this to producer as --frame_last 50006 { // Record json in COCO format if file within desired range of images - spPoseJsonCocoSaver->record(tDatum.poseKeyPoints, imageId); + spCocoJsonSaver->record(tDatum.poseKeypoints, imageId); // Profiling speed Profiler::timerEnd(profilerKey); Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); @@ -101,8 +101,8 @@ namespace op } } - COMPILE_TEMPLATE_DATUM(WPoseJsonCocoSaver); + COMPILE_TEMPLATE_DATUM(WCocoJsonSaver); } } -#endif // OPENPOSE__EXPERIMENTAL__FILESTREAM__W_POSE_JSON_COCO_SAVER_HPP +#endif // OPENPOSE_FILESTREAM_W_COCO_JSON_SAVER_HPP diff --git a/include/openpose/experimental/hand/enumClasses.hpp b/include/openpose/experimental/hand/enumClasses.hpp index 4b81d924..4ab92057 100644 --- a/include/openpose/experimental/hand/enumClasses.hpp +++ b/include/openpose/experimental/hand/enumClasses.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__HAND__ENUM_CLASSES_HPP -#define OPENPOSE__HAND__ENUM_CLASSES_HPP +#ifndef OPENPOSE_HAND_ENUM_CLASSES_HPP +#define OPENPOSE_HAND_ENUM_CLASSES_HPP namespace op { @@ -10,4 +10,4 @@ namespace op }; } -#endif // OPENPOSE__HAND__ENUM_CLASSES_HPP +#endif // OPENPOSE_HAND_ENUM_CLASSES_HPP diff --git a/include/openpose/experimental/hand/handExtractor.hpp b/include/openpose/experimental/hand/handExtractor.hpp index 4c8a4f74..1a39cfdc 100644 --- a/include/openpose/experimental/hand/handExtractor.hpp +++ b/include/openpose/experimental/hand/handExtractor.hpp @@ -1,12 +1,13 @@ -#ifndef OPENPOSE__HAND__HAND_EXTRACTOR_HPP -#define OPENPOSE__HAND__HAND_EXTRACTOR_HPP +#ifndef OPENPOSE_HAND_HAND_EXTRACTOR_HPP +#define OPENPOSE_HAND_HAND_EXTRACTOR_HPP #include #include #include // std::shared_ptr #include -#include +#include // cv::Mat #include +#include #include #include #include @@ -24,9 +25,9 @@ namespace op void initializationOnThread(); - void forwardPass(const Array& poseKeyPoints, const cv::Mat& cvInputData); + void forwardPass(const Array& poseKeypoints, const cv::Mat& cvInputData); - Array getHandKeyPoints() const; + Array getHandKeypoints() const; double get(const HandsProperty property) const; @@ -35,8 +36,8 @@ namespace op void increase(const HandsProperty property, const double value); private: - const cv::Size mNetOutputSize; - const cv::Size mOutputSize; + const Point mNetOutputSize; + const Point mOutputSize; const unsigned int mRWrist; const unsigned int mRElbow; const unsigned int mLWrist; @@ -65,4 +66,4 @@ namespace op } } -#endif // OPENPOSE__HAND__HAND_EXTRACTOR_HPP +#endif // OPENPOSE_HAND_HAND_EXTRACTOR_HPP diff --git a/include/openpose/experimental/hand/handParameters.hpp b/include/openpose/experimental/hand/handParameters.hpp index f73c804b..97ee9f51 100644 --- a/include/openpose/experimental/hand/handParameters.hpp +++ b/include/openpose/experimental/hand/handParameters.hpp @@ -1,22 +1,19 @@ -#ifndef OPENPOSE__HAND__HAND_PARAMETERS_HPP -#define OPENPOSE__HAND__HAND_PARAMETERS_HPP +#ifndef OPENPOSE_HAND_HAND_PARAMETERS_HPP +#define OPENPOSE_HAND_HAND_PARAMETERS_HPP #include "enumClasses.hpp" #include namespace op { - const unsigned char HAND_MAX_NUMBER_HANDS = 2; + const auto HAND_MAX_HANDS = 2*POSE_MAX_PEOPLE; - const unsigned char HAND_NUMBER_PARTS = 21; + const auto HAND_NUMBER_PARTS = 21u; #define HAND_PAIRS_TO_RENDER {0,1, 1,2, 2,3, 3,4, 0,5, 5,6, 6,7, 7,8, 0,9, 9,10, 10,11, 11,12, 0,13, 13,14, 14,15, 15,16, 0,17, 17,18, 18,19, 19,20} - // Constant Global Parameters - // const unsigned char HAND_MAX_PEOPLE = 1; - // Constant parameters const auto HAND_CCN_DECREASE_FACTOR = 8.f; - const unsigned int HAND_MAX_PEAKS = 64u; + const auto HAND_MAX_PEAKS = 64u; const std::string HAND_PROTOTXT{"hand/pose_deploy.prototxt"}; const std::string HAND_TRAINED_MODEL{"hand/pose_iter_120000.caffemodel"}; @@ -25,8 +22,8 @@ namespace op const auto HAND_DEFAULT_NMS_THRESHOLD = 0.1f; // Rendering default parameters - const auto HAND_DEFAULT_ALPHA_HANDS = POSE_DEFAULT_ALPHA_POSE; - // const auto HAND_DEFAULT_ALPHA_HEATMAP = POSE_DEFAULT_ALPHA_HEATMAP; + const auto HAND_DEFAULT_ALPHA_KEYPOINT = POSE_DEFAULT_ALPHA_KEYPOINT; + const auto HAND_DEFAULT_ALPHA_HEAT_MAP = POSE_DEFAULT_ALPHA_HEAT_MAP; } -#endif // OPENPOSE__HAND__HAND_PARAMETERS_HPP +#endif // OPENPOSE_HAND_HAND_PARAMETERS_HPP diff --git a/include/openpose/experimental/hand/handRenderGpu.hpp b/include/openpose/experimental/hand/handRenderGpu.hpp index 9be8412f..ba1dcd82 100644 --- a/include/openpose/experimental/hand/handRenderGpu.hpp +++ b/include/openpose/experimental/hand/handRenderGpu.hpp @@ -1,12 +1,12 @@ -#ifndef OPENPOSE__HAND__GPU_HAND_RENDER_HPP -#define OPENPOSE__HAND__GPU_HAND_RENDER_HPP +#ifndef OPENPOSE_HAND_GPU_HAND_RENDER_HPP +#define OPENPOSE_HAND_GPU_HAND_RENDER_HPP -#include +#include #include "handParameters.hpp" namespace op { - void renderHandsGpu(float* framePtr, const cv::Size& frameSize, const float* const handsPtr, const int numberHands, const float alphaColorToAdd = HAND_DEFAULT_ALPHA_HANDS); + void renderHandsGpu(float* framePtr, const Point& frameSize, const float* const handsPtr, const int numberHands, const float alphaColorToAdd = HAND_DEFAULT_ALPHA_KEYPOINT); } -#endif // OPENPOSE__HAND__GPU_HAND_RENDER_HPP +#endif // OPENPOSE_HAND_GPU_HAND_RENDER_HPP diff --git a/include/openpose/experimental/hand/handRenderer.hpp b/include/openpose/experimental/hand/handRenderer.hpp index fa689de2..d0d1cacd 100644 --- a/include/openpose/experimental/hand/handRenderer.hpp +++ b/include/openpose/experimental/hand/handRenderer.hpp @@ -1,8 +1,8 @@ -#ifndef OPENPOSE__HAND__HAND_RENDERER_HPP -#define OPENPOSE__HAND__HAND_RENDERER_HPP +#ifndef OPENPOSE_HAND_HAND_RENDERER_HPP +#define OPENPOSE_HAND_HAND_RENDERER_HPP -#include #include +#include #include #include @@ -13,16 +13,16 @@ namespace op class HandRenderer : public Renderer { public: - explicit HandRenderer(const cv::Size& frameSize); + explicit HandRenderer(const Point& frameSize); ~HandRenderer(); void initializationOnThread(); - void renderHands(Array& outputData, const Array& handKeyPoints); + void renderHands(Array& outputData, const Array& handKeypoints); private: - const cv::Size mFrameSize; + const Point mFrameSize; float* pGpuHands; // GPU aux memory DELETE_COPY(HandRenderer); @@ -30,4 +30,4 @@ namespace op } } -#endif // OPENPOSE__HAND__HAND_RENDERER_HPP +#endif // OPENPOSE_HAND_HAND_RENDERER_HPP diff --git a/include/openpose/experimental/hand/headers.hpp b/include/openpose/experimental/hand/headers.hpp index 74fe189e..9d8fd4c5 100644 --- a/include/openpose/experimental/hand/headers.hpp +++ b/include/openpose/experimental/hand/headers.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__HAND__HEADERS_HPP -#define OPENPOSE__HAND__HEADERS_HPP +#ifndef OPENPOSE_HAND_HEADERS_HPP +#define OPENPOSE_HAND_HEADERS_HPP // hand module #include "enumClasses.hpp" @@ -10,4 +10,4 @@ #include "wHandExtractor.hpp" #include "wHandRenderer.hpp" -#endif // OPENPOSE__HAND__HEADERS_HPP +#endif // OPENPOSE_HAND_HEADERS_HPP diff --git a/include/openpose/experimental/hand/wHandExtractor.hpp b/include/openpose/experimental/hand/wHandExtractor.hpp index 56fa5f0b..fe919d50 100644 --- a/include/openpose/experimental/hand/wHandExtractor.hpp +++ b/include/openpose/experimental/hand/wHandExtractor.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__HAND__W_HAND_EXTRACTOR_HPP -#define OPENPOSE__HAND__W_HAND_EXTRACTOR_HPP +#ifndef OPENPOSE_HAND_W_HAND_EXTRACTOR_HPP +#define OPENPOSE_HAND_W_HAND_EXTRACTOR_HPP #include // std::shared_ptr #include @@ -66,8 +66,8 @@ namespace op // Extract people hands for (auto& tDatum : *tDatums) { - spHandExtractor->forwardPass(tDatum.poseKeyPoints, tDatum.cvInputData); - tDatum.handKeyPoints = spHandExtractor->getHandKeyPoints(); + spHandExtractor->forwardPass(tDatum.poseKeypoints, tDatum.cvInputData); + tDatum.handKeypoints = spHandExtractor->getHandKeypoints(); } // Profiling speed Profiler::timerEnd(profilerKey); @@ -88,4 +88,4 @@ namespace op } } -#endif // OPENPOSE__HAND__W_HAND_EXTRACTOR_HPP +#endif // OPENPOSE_HAND_W_HAND_EXTRACTOR_HPP diff --git a/include/openpose/experimental/hand/wHandRenderer.hpp b/include/openpose/experimental/hand/wHandRenderer.hpp index f520bbe8..bb4d0031 100644 --- a/include/openpose/experimental/hand/wHandRenderer.hpp +++ b/include/openpose/experimental/hand/wHandRenderer.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__HAND__W_HAND_RENDERER_HPP -#define OPENPOSE__HAND__W_HAND_RENDERER_HPP +#ifndef OPENPOSE_HAND_W_HAND_RENDERER_HPP +#define OPENPOSE_HAND_W_HAND_RENDERER_HPP #include // std::shared_ptr #include @@ -65,7 +65,7 @@ namespace op const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); // Render people hands for (auto& tDatum : *tDatums) - spHandRenderer->renderHands(tDatum.outputData, tDatum.handKeyPoints); + spHandRenderer->renderHands(tDatum.outputData, tDatum.handKeypoints); // Profiling speed Profiler::timerEnd(profilerKey); Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); @@ -85,4 +85,4 @@ namespace op } } -#endif // OPENPOSE__HAND__W_HAND_RENDERER_HPP +#endif // OPENPOSE_HAND_W_HAND_RENDERER_HPP diff --git a/include/openpose/experimental/headers.hpp b/include/openpose/experimental/headers.hpp index 9cdbc5d8..a64975e6 100644 --- a/include/openpose/experimental/headers.hpp +++ b/include/openpose/experimental/headers.hpp @@ -1,8 +1,5 @@ -#ifndef OPENPOSE__EXPERIMENTAL__HEADERS_HPP -#define OPENPOSE__EXPERIMENTAL__HEADERS_HPP - -// face module -#include "face/headers.hpp" +#ifndef OPENPOSE_EXPERIMENTAL_HEADERS_HPP +#define OPENPOSE_EXPERIMENTAL_HEADERS_HPP // filestream module #include "filestream/headers.hpp" @@ -13,4 +10,4 @@ // producer module // #include "producer/headers.hpp" -#endif // OPENPOSE__EXPERIMENTAL__HEADERS_HPP +#endif // OPENPOSE_EXPERIMENTAL_HEADERS_HPP diff --git a/include/openpose/experimental/producer/headers.hpp b/include/openpose/experimental/producer/headers.hpp index c0f6c300..f7dd5750 100644 --- a/include/openpose/experimental/producer/headers.hpp +++ b/include/openpose/experimental/producer/headers.hpp @@ -1,7 +1,7 @@ -#ifndef OPENPOSE__EXPERIMENTAL__PRODUCER__HEADERS_HPP -#define OPENPOSE__EXPERIMENTAL__PRODUCER__HEADERS_HPP +#ifndef OPENPOSE_EXPERIMENTAL_PRODUCER_HEADERS_HPP +#define OPENPOSE_EXPERIMENTAL_PRODUCER_HEADERS_HPP // producer module // #include "wPoseLoader.hpp" -#endif // OPENPOSE__EXPERIMENTAL__PRODUCER__HEADERS_HPP +#endif // OPENPOSE_EXPERIMENTAL_PRODUCER_HEADERS_HPP diff --git a/include/openpose/experimental/producer/wPeoplePoseLoader.hpp b/include/openpose/experimental/producer/wPeoplePoseLoader.hpp index c7a1a4cc..f93e01b2 100644 --- a/include/openpose/experimental/producer/wPeoplePoseLoader.hpp +++ b/include/openpose/experimental/producer/wPeoplePoseLoader.hpp @@ -2,8 +2,8 @@ // 1. Pre-process whole video and save people pose // 2. Real-time showing it by loading this + original video -// #ifndef OPENPOSE__PRODUCER__W_POSE_LOADER_HPP -// #define OPENPOSE__PRODUCER__W_POSE_LOADER_HPP +// #ifndef OPENPOSE_PRODUCER_W_POSE_LOADER_HPP +// #define OPENPOSE_PRODUCER_W_POSE_LOADER_HPP // namespace op // { @@ -25,4 +25,4 @@ // COMPILE_TEMPLATE_DATUM(WPoseLoader); // } -// #endif // OPENPOSE__PRODUCER__W_POSE_LOADER_HPP +// #endif // OPENPOSE_PRODUCER_W_POSE_LOADER_HPP diff --git a/include/openpose/face/enumClasses.hpp b/include/openpose/face/enumClasses.hpp new file mode 100644 index 00000000..e5616ffb --- /dev/null +++ b/include/openpose/face/enumClasses.hpp @@ -0,0 +1,14 @@ +#ifndef OPENPOSE_FACE_ENUM_CLASSES_HPP +#define OPENPOSE_FACE_ENUM_CLASSES_HPP + +namespace op +{ + enum class FaceProperty : bool + { + NMSThreshold = 0, + Size, + }; +} + +#endif // OPENPOSE_FACE_ENUM_CLASSES_HPP + diff --git a/include/openpose/face/faceDetector.hpp b/include/openpose/face/faceDetector.hpp new file mode 100644 index 00000000..d4e91591 --- /dev/null +++ b/include/openpose/face/faceDetector.hpp @@ -0,0 +1,32 @@ +#ifndef OPENPOSE_FACE_FACE_DETECTOR_HPP +#define OPENPOSE_FACE_FACE_DETECTOR_HPP + +#include +#include +#include +#include +#include +#include "enumClasses.hpp" + +namespace op +{ + class FaceDetector + { + public: + explicit FaceDetector(const PoseModel poseModel); + + std::vector> detectFaces(const Array& poseKeypoints); + + private: + const unsigned int mNeck; + const unsigned int mNose; + const unsigned int mLEar; + const unsigned int mREar; + const unsigned int mLEye; + const unsigned int mREye; + + DELETE_COPY(FaceDetector); + }; +} + +#endif // OPENPOSE_FACE_FACE_DETECTOR_HPP diff --git a/include/openpose/face/faceExtractor.hpp b/include/openpose/face/faceExtractor.hpp new file mode 100644 index 00000000..8da9a683 --- /dev/null +++ b/include/openpose/face/faceExtractor.hpp @@ -0,0 +1,56 @@ +#ifndef OPENPOSE_FACE_FACE_EXTRACTOR_HPP +#define OPENPOSE_FACE_FACE_EXTRACTOR_HPP + +#include +#include +#include // std::shared_ptr +#include +#include // cv::Mat +#include +#include +#include +#include +#include +#include "enumClasses.hpp" + +namespace op +{ + class FaceExtractor + { + public: + explicit FaceExtractor(const Point& netInputSize, const Point& netOutputSize, const std::string& modelFolder, const int gpuId); + + void initializationOnThread(); + + void forwardPass(const std::vector>& faceRectangles, const cv::Mat& cvInputData); + + Array getFaceKeypoints() const; + + double get(const FaceProperty property) const; + + void set(const FaceProperty property, const double value); + + void increase(const FaceProperty property, const double value); + + private: + const Point mNetOutputSize; + const Point mOutputSize; + std::array, (int)FaceProperty::Size> mProperties; + std::shared_ptr spNet; + std::shared_ptr> spResizeAndMergeCaffe; + std::shared_ptr> spNmsCaffe; + Array mFaceImageCrop; + Array mFaceKeypoints; + // Init with thread + boost::shared_ptr> spCaffeNetOutputBlob; + std::shared_ptr> spHeatMapsBlob; + std::shared_ptr> spPeaksBlob; + std::thread::id mThreadId; + + void checkThread() const; + + DELETE_COPY(FaceExtractor); + }; +} + +#endif // OPENPOSE_FACE_FACE_EXTRACTOR_HPP diff --git a/include/openpose/experimental/face/faceParameters.hpp b/include/openpose/face/faceParameters.hpp similarity index 68% rename from include/openpose/experimental/face/faceParameters.hpp rename to include/openpose/face/faceParameters.hpp index 6f2ec346..54fe45e8 100644 --- a/include/openpose/experimental/face/faceParameters.hpp +++ b/include/openpose/face/faceParameters.hpp @@ -1,25 +1,22 @@ -#ifndef OPENPOSE__FACE__FACE_PARAMETERS_HPP -#define OPENPOSE__FACE__FACE_PARAMETERS_HPP +#ifndef OPENPOSE_FACE_FACE_PARAMETERS_HPP +#define OPENPOSE_FACE_FACE_PARAMETERS_HPP #include "enumClasses.hpp" #include namespace op { - const unsigned char FACE_MAX_NUMBER_FACE = 1; + const auto FACE_MAX_FACES = POSE_MAX_PEOPLE; - const unsigned char FACE_NUMBER_PARTS = 71; + const auto FACE_NUMBER_PARTS = 70u; #define FACE_PAIRS_TO_RENDER {0,1, 1,2, 2,3, 3,4, 4,5, 5,6, 6,7, 7,8, 8,9, 9,10, 10,11, 11,12, 12,13, 13,14, 14,15, 15,16, 17,18, 18,19, 19,20, \ 20,21, 22,23, 23,24, 24,25, 25,26, 27,28, 28,29, 29,30, 31,32, 32,33, 33,34, 34,35, 36,37, 37,38, 38,39, 39,40, 40,41, \ 41,36, 42,43, 43,44, 44,45, 45,46, 46,47, 47,42, 48,49, 49,50, 50,51, 51,52, 52,53, 53,54, 54,55, 55,56, 56,57, 57,58, \ 58,59, 59,48, 60,61, 61,62, 62,63, 63,64, 64,65, 65,66, 66,67, 67,60} - // Constant Global Parameters - // const unsigned char FACE_MAX_PEOPLE = 1; - // Constant parameters const auto FACE_CCN_DECREASE_FACTOR = 8.f; - const unsigned int FACE_MAX_PEAKS = 64u; + const auto FACE_MAX_PEAKS = 64u; const std::string FACE_PROTOTXT{"face/pose_deploy.prototxt"}; const std::string FACE_TRAINED_MODEL{"face/pose_iter_116000.caffemodel"}; @@ -28,8 +25,8 @@ namespace op const auto FACE_DEFAULT_NMS_THRESHOLD = 0.1f; // Rendering default parameters - const auto FACE_DEFAULT_ALPHA_FACE = POSE_DEFAULT_ALPHA_POSE; - // const auto FACE_DEFAULT_ALPHA_HEATMAP = POSE_DEFAULT_ALPHA_HEATMAP; + const auto FACE_DEFAULT_ALPHA_KEYPOINT = POSE_DEFAULT_ALPHA_KEYPOINT; + const auto FACE_DEFAULT_ALPHA_HEAT_MAP = POSE_DEFAULT_ALPHA_HEAT_MAP; } -#endif // OPENPOSE__FACE__FACE_PARAMETERS_HPP +#endif // OPENPOSE_FACE_FACE_PARAMETERS_HPP diff --git a/include/openpose/face/faceRenderGpu.hpp b/include/openpose/face/faceRenderGpu.hpp new file mode 100644 index 00000000..47f6c4c4 --- /dev/null +++ b/include/openpose/face/faceRenderGpu.hpp @@ -0,0 +1,12 @@ +#ifndef OPENPOSE_FACE_GPU_FACE_RENDER_HPP +#define OPENPOSE_FACE_GPU_FACE_RENDER_HPP + +#include +#include "faceParameters.hpp" + +namespace op +{ + void renderFaceGpu(float* framePtr, const Point& frameSize, const float* const facePtr, const int numberFace, const float alphaColorToAdd = FACE_DEFAULT_ALPHA_KEYPOINT); +} + +#endif // OPENPOSE_FACE_GPU_FACE_RENDER_HPP diff --git a/include/openpose/face/faceRenderer.hpp b/include/openpose/face/faceRenderer.hpp new file mode 100644 index 00000000..1ab61e01 --- /dev/null +++ b/include/openpose/face/faceRenderer.hpp @@ -0,0 +1,31 @@ +#ifndef OPENPOSE_FACE_FACE_RENDERER_HPP +#define OPENPOSE_FACE_FACE_RENDERER_HPP + +#include +#include +#include +#include + +namespace op +{ + class FaceRenderer : public Renderer + { + public: + explicit FaceRenderer(const Point& frameSize, const float alphaKeypoint = FACE_DEFAULT_ALPHA_KEYPOINT, + const float alphaHeatMap = FACE_DEFAULT_ALPHA_HEAT_MAP); + + ~FaceRenderer(); + + void initializationOnThread(); + + void renderFace(Array& outputData, const Array& faceKeypoints); + + private: + const Point mFrameSize; + float* pGpuFace; // GPU aux memory + + DELETE_COPY(FaceRenderer); + }; +} + +#endif // OPENPOSE_FACE_FACE_RENDERER_HPP diff --git a/include/openpose/experimental/face/headers.hpp b/include/openpose/face/headers.hpp similarity index 57% rename from include/openpose/experimental/face/headers.hpp rename to include/openpose/face/headers.hpp index 4829481b..b1b66629 100644 --- a/include/openpose/experimental/face/headers.hpp +++ b/include/openpose/face/headers.hpp @@ -1,13 +1,15 @@ -#ifndef OPENPOSE__FACE__HEADERS_HPP -#define OPENPOSE__FACE__HEADERS_HPP +#ifndef OPENPOSE_FACE_HEADERS_HPP +#define OPENPOSE_FACE_HEADERS_HPP // face module #include "enumClasses.hpp" +#include "faceDetector.hpp" #include "faceExtractor.hpp" #include "faceParameters.hpp" #include "faceRenderer.hpp" #include "faceRenderGpu.hpp" +#include "wFaceDetector.hpp" #include "wFaceExtractor.hpp" #include "wFaceRenderer.hpp" -#endif // OPENPOSE__FACE__HEADERS_HPP +#endif // OPENPOSE_FACE_HEADERS_HPP diff --git a/include/openpose/face/wFaceDetector.hpp b/include/openpose/face/wFaceDetector.hpp new file mode 100644 index 00000000..66483b4b --- /dev/null +++ b/include/openpose/face/wFaceDetector.hpp @@ -0,0 +1,81 @@ +#ifndef OPENPOSE_FACE_W_FACE_EXTRACTOR_HPP +#define OPENPOSE_FACE_W_FACE_EXTRACTOR_HPP + +#include // std::shared_ptr +#include +#include "faceRenderer.hpp" + +namespace op +{ + template + class WFaceDetector : public Worker + { + public: + explicit WFaceDetector(const std::shared_ptr& faceDetector); + + void initializationOnThread(); + + void work(TDatums& tDatums); + + private: + std::shared_ptr spFaceDetector; + + DELETE_COPY(WFaceDetector); + }; +} + + + + + +// Implementation +#include +#include +#include +#include +namespace op +{ + template + WFaceDetector::WFaceDetector(const std::shared_ptr& faceDetector) : + spFaceDetector{faceDetector} + { + } + + template + void WFaceDetector::initializationOnThread() + { + } + + template + void WFaceDetector::work(TDatums& tDatums) + { + try + { + if (checkNoNullNorEmpty(tDatums)) + { + // Debugging log + dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + // Profiling speed + const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); + // Detect people face + for (auto& tDatum : *tDatums) + tDatum.faceRectangles = spFaceDetector->detectFaces(tDatum.poseKeypoints); + // Profiling speed + Profiler::timerEnd(profilerKey); + Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); + // Debugging log + dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + } + } + catch (const std::exception& e) + { + this->stop(); + tDatums = nullptr; + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + COMPILE_TEMPLATE_DATUM(WFaceDetector); +} + +#endif // OPENPOSE_FACE_W_FACE_EXTRACTOR_HPP diff --git a/include/openpose/face/wFaceExtractor.hpp b/include/openpose/face/wFaceExtractor.hpp new file mode 100644 index 00000000..41e99819 --- /dev/null +++ b/include/openpose/face/wFaceExtractor.hpp @@ -0,0 +1,85 @@ +#ifndef OPENPOSE_FACE_W_FACE_DETECTOR_HPP +#define OPENPOSE_FACE_W_FACE_DETECTOR_HPP + +#include // std::shared_ptr +#include +#include "faceRenderer.hpp" + +namespace op +{ + template + class WFaceExtractor : public Worker + { + public: + explicit WFaceExtractor(const std::shared_ptr& faceExtractor); + + void initializationOnThread(); + + void work(TDatums& tDatums); + + private: + std::shared_ptr spFaceExtractor; + + DELETE_COPY(WFaceExtractor); + }; +} + + + + + +// Implementation +#include +#include +#include +#include +namespace op +{ + template + WFaceExtractor::WFaceExtractor(const std::shared_ptr& faceExtractor) : + spFaceExtractor{faceExtractor} + { + } + + template + void WFaceExtractor::initializationOnThread() + { + spFaceExtractor->initializationOnThread(); + } + + template + void WFaceExtractor::work(TDatums& tDatums) + { + try + { + if (checkNoNullNorEmpty(tDatums)) + { + // Debugging log + dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + // Profiling speed + const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); + // Extract people face + for (auto& tDatum : *tDatums) + { + spFaceExtractor->forwardPass(tDatum.faceRectangles, tDatum.cvInputData); + tDatum.faceKeypoints = spFaceExtractor->getFaceKeypoints(); + } + // Profiling speed + Profiler::timerEnd(profilerKey); + Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); + // Debugging log + dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + } + } + catch (const std::exception& e) + { + this->stop(); + tDatums = nullptr; + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + COMPILE_TEMPLATE_DATUM(WFaceExtractor); +} + +#endif // OPENPOSE_FACE_W_FACE_DETECTOR_HPP diff --git a/include/openpose/face/wFaceRenderer.hpp b/include/openpose/face/wFaceRenderer.hpp new file mode 100644 index 00000000..fac2b91c --- /dev/null +++ b/include/openpose/face/wFaceRenderer.hpp @@ -0,0 +1,82 @@ +#ifndef OPENPOSE_FACE_W_FACE_RENDERER_HPP +#define OPENPOSE_FACE_W_FACE_RENDERER_HPP + +#include // std::shared_ptr +#include +#include "faceRenderer.hpp" + +namespace op +{ + template + class WFaceRenderer : public Worker + { + public: + explicit WFaceRenderer(const std::shared_ptr& faceRenderer); + + void initializationOnThread(); + + void work(TDatums& tDatums); + + private: + std::shared_ptr spFaceRenderer; + + DELETE_COPY(WFaceRenderer); + }; +} + + + + + +// Implementation +#include +#include +#include +#include +namespace op +{ + template + WFaceRenderer::WFaceRenderer(const std::shared_ptr& faceRenderer) : + spFaceRenderer{faceRenderer} + { + } + + template + void WFaceRenderer::initializationOnThread() + { + spFaceRenderer->initializationOnThread(); + } + + template + void WFaceRenderer::work(TDatums& tDatums) + { + try + { + if (checkNoNullNorEmpty(tDatums)) + { + // Debugging log + dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + // Profiling speed + const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); + // Render people face + for (auto& tDatum : *tDatums) + spFaceRenderer->renderFace(tDatum.outputData, tDatum.faceKeypoints); + // Profiling speed + Profiler::timerEnd(profilerKey); + Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); + // Debugging log + dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + } + } + catch (const std::exception& e) + { + this->stop(); + tDatums = nullptr; + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + COMPILE_TEMPLATE_DATUM(WFaceRenderer); +} + +#endif // OPENPOSE_FACE_W_FACE_RENDERER_HPP diff --git a/include/openpose/filestream/cocoJsonSaver.hpp b/include/openpose/filestream/cocoJsonSaver.hpp new file mode 100644 index 00000000..b97d0d64 --- /dev/null +++ b/include/openpose/filestream/cocoJsonSaver.hpp @@ -0,0 +1,35 @@ +#ifndef OPENPOSE_FILESTREAM_POSE_JSON_COCO_SAVER_HPP +#define OPENPOSE_FILESTREAM_POSE_JSON_COCO_SAVER_HPP + +#include +#include +#include +#include "jsonOfstream.hpp" + +namespace op +{ + /** + * The CocoJsonSaver class creates a COCO validation json file with details about the processed images. It inherits from Recorder. + */ + class CocoJsonSaver + { + public: + /** + * This constructor of CocoJsonSaver extends the Recorder::Recorder(const std::string & filePathToSave) constructor. + * @param filePathToSave const std::string parameter with the final file path where the generated json file will be saved. + */ + explicit CocoJsonSaver(const std::string& filePathToSave, const bool humanReadable = true); + + ~CocoJsonSaver(); + + void record(const Array& poseKeypoints, const unsigned long long imageId); + + private: + JsonOfstream mJsonOfstream; + bool mFirstElementAdded; + + DELETE_COPY(CocoJsonSaver); + }; +} + +#endif // OPENPOSE_FILESTREAM_POSE_JSON_COCO_SAVER_HPP diff --git a/include/openpose/filestream/enumClasses.hpp b/include/openpose/filestream/enumClasses.hpp index f8f2989c..02dda3a6 100644 --- a/include/openpose/filestream/enumClasses.hpp +++ b/include/openpose/filestream/enumClasses.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__FILESTREAM__ENUM_CLASSES_HPP -#define OPENPOSE__FILESTREAM__ENUM_CLASSES_HPP +#ifndef OPENPOSE_FILESTREAM_ENUM_CLASSES_HPP +#define OPENPOSE_FILESTREAM_ENUM_CLASSES_HPP namespace op { @@ -12,4 +12,4 @@ namespace op }; } -#endif // OPENPOSE__FILESTREAM__ENUM_CLASSES_HPP +#endif // OPENPOSE_FILESTREAM_ENUM_CLASSES_HPP diff --git a/include/openpose/filestream/fileSaver.hpp b/include/openpose/filestream/fileSaver.hpp index 999d06ad..c6b093b9 100644 --- a/include/openpose/filestream/fileSaver.hpp +++ b/include/openpose/filestream/fileSaver.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__FILESTREAM__DATA_SAVER_HPP -#define OPENPOSE__FILESTREAM__DATA_SAVER_HPP +#ifndef OPENPOSE_FILESTREAM_DATA_SAVER_HPP +#define OPENPOSE_FILESTREAM_DATA_SAVER_HPP #include #include @@ -20,4 +20,4 @@ namespace op }; } -#endif // OPENPOSE__FILESTREAM__DATA_SAVER_HPP +#endif // OPENPOSE_FILESTREAM_DATA_SAVER_HPP diff --git a/include/openpose/filestream/fileStream.hpp b/include/openpose/filestream/fileStream.hpp index 9b3aba31..c16dfc79 100644 --- a/include/openpose/filestream/fileStream.hpp +++ b/include/openpose/filestream/fileStream.hpp @@ -1,9 +1,9 @@ -#ifndef OPENPOSE__FILESTREAM__FILE_STREAM_HPP -#define OPENPOSE__FILESTREAM__FILE_STREAM_HPP +#ifndef OPENPOSE_FILESTREAM_FILE_STREAM_HPP +#define OPENPOSE_FILESTREAM_FILE_STREAM_HPP #include #include -#include // cv::Mat, cv::Size +#include // cv::Mat #include // CV_LOAD_IMAGE_ANYDEPTH, CV_IMWRITE_PNG_COMPRESSION #include #include "enumClasses.hpp" @@ -30,4 +30,4 @@ namespace op cv::Mat loadImage(const std::string& fullFilePath, const int openCvFlags = CV_LOAD_IMAGE_ANYDEPTH); } -#endif // OPENPOSE__FILESTREAM__FILE_STREAM_HPP +#endif // OPENPOSE_FILESTREAM_FILE_STREAM_HPP diff --git a/include/openpose/filestream/headers.hpp b/include/openpose/filestream/headers.hpp index b8150e80..14c42ecb 100644 --- a/include/openpose/filestream/headers.hpp +++ b/include/openpose/filestream/headers.hpp @@ -1,21 +1,25 @@ -#ifndef OPENPOSE__FILESTREAM__HEADERS_HPP -#define OPENPOSE__FILESTREAM__HEADERS_HPP +#ifndef OPENPOSE_FILESTREAM_HEADERS_HPP +#define OPENPOSE_FILESTREAM_HEADERS_HPP // storage module +#include "cocoJsonSaver.hpp" #include "enumClasses.hpp" #include "fileSaver.hpp" #include "fileStream.hpp" #include "heatMapSaver.hpp" #include "imageSaver.hpp" #include "jsonOfstream.hpp" -#include "poseJsonCocoSaver.hpp" -#include "poseJsonSaver.hpp" -#include "poseSaver.hpp" +#include "keypointJsonSaver.hpp" +#include "keypointSaver.hpp" #include "videoSaver.hpp" +#include "wFaceJsonSaver.hpp" +#include "wFaceSaver.hpp" +#include "wHandJsonSaver.hpp" +#include "wHandSaver.hpp" #include "wImageSaver.hpp" #include "wHeatMapSaver.hpp" #include "wPoseJsonSaver.hpp" #include "wPoseSaver.hpp" #include "wVideoSaver.hpp" -#endif // OPENPOSE__FILESTREAM__HEADERS_HPP +#endif // OPENPOSE_FILESTREAM_HEADERS_HPP diff --git a/include/openpose/filestream/heatMapSaver.hpp b/include/openpose/filestream/heatMapSaver.hpp index fdbf810e..8a01a76c 100644 --- a/include/openpose/filestream/heatMapSaver.hpp +++ b/include/openpose/filestream/heatMapSaver.hpp @@ -1,9 +1,8 @@ -#ifndef OPENPOSE__FILESTREAM__HEAT_MAP_SAVER_HPP -#define OPENPOSE__FILESTREAM__HEAT_MAP_SAVER_HPP +#ifndef OPENPOSE_FILESTREAM_HEAT_MAP_SAVER_HPP +#define OPENPOSE_FILESTREAM_HEAT_MAP_SAVER_HPP #include #include -#include #include "fileSaver.hpp" namespace op @@ -20,4 +19,4 @@ namespace op }; } -#endif // OPENPOSE__FILESTREAM__HEAT_MAP_SAVER_HPP +#endif // OPENPOSE_FILESTREAM_HEAT_MAP_SAVER_HPP diff --git a/include/openpose/filestream/imageSaver.hpp b/include/openpose/filestream/imageSaver.hpp index 2c86952e..da979c72 100644 --- a/include/openpose/filestream/imageSaver.hpp +++ b/include/openpose/filestream/imageSaver.hpp @@ -1,9 +1,9 @@ -#ifndef OPENPOSE__FILESTREAM__IMAGE_SAVER_HPP -#define OPENPOSE__FILESTREAM__IMAGE_SAVER_HPP +#ifndef OPENPOSE_FILESTREAM_IMAGE_SAVER_HPP +#define OPENPOSE_FILESTREAM_IMAGE_SAVER_HPP #include #include -#include +#include // cv::Mat #include "fileSaver.hpp" namespace op @@ -20,4 +20,4 @@ namespace op }; } -#endif // OPENPOSE__FILESTREAM__IMAGE_SAVER_HPP +#endif // OPENPOSE_FILESTREAM_IMAGE_SAVER_HPP diff --git a/include/openpose/filestream/jsonOfstream.hpp b/include/openpose/filestream/jsonOfstream.hpp index 128485bd..e0ffdf33 100644 --- a/include/openpose/filestream/jsonOfstream.hpp +++ b/include/openpose/filestream/jsonOfstream.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__FILESTREAM__JSON_OFSTREAM_HPP -#define OPENPOSE__FILESTREAM__JSON_OFSTREAM_HPP +#ifndef OPENPOSE_FILESTREAM_JSON_OFSTREAM_HPP +#define OPENPOSE_FILESTREAM_JSON_OFSTREAM_HPP #include // std::ofstream #include @@ -47,4 +47,4 @@ namespace op }; } -#endif // OPENPOSE__FILESTREAM__JSON_OFSTREAM_HPP +#endif // OPENPOSE_FILESTREAM_JSON_OFSTREAM_HPP diff --git a/include/openpose/filestream/keypointJsonSaver.hpp b/include/openpose/filestream/keypointJsonSaver.hpp new file mode 100644 index 00000000..1aec1b4b --- /dev/null +++ b/include/openpose/filestream/keypointJsonSaver.hpp @@ -0,0 +1,20 @@ +#ifndef OPENPOSE_FILESTREAM_KEYPOINT_JSON_SAVER_HPP +#define OPENPOSE_FILESTREAM_KEYPOINT_JSON_SAVER_HPP + +#include +#include +#include +#include "fileSaver.hpp" + +namespace op +{ + class KeypointJsonSaver : public FileSaver + { + public: + KeypointJsonSaver(const std::string& directoryPath); + + void saveKeypoints(const std::vector>& keypointVector, const std::string& fileName, const std::string& keypointName) const; + }; +} + +#endif // OPENPOSE_FILESTREAM_KEYPOINT_JSON_SAVER_HPP diff --git a/include/openpose/filestream/keypointSaver.hpp b/include/openpose/filestream/keypointSaver.hpp new file mode 100644 index 00000000..2b9bf89d --- /dev/null +++ b/include/openpose/filestream/keypointSaver.hpp @@ -0,0 +1,22 @@ +#ifndef OPENPOSE_FILESTREAM_KEYPOINT_SAVER_HPP +#define OPENPOSE_FILESTREAM_KEYPOINT_SAVER_HPP + +#include +#include "enumClasses.hpp" +#include "fileSaver.hpp" + +namespace op +{ + class KeypointSaver : public FileSaver + { + public: + KeypointSaver(const std::string& directoryPath, const DataFormat format); + + void saveKeypoints(const std::vector>& keypointVector, const std::string& fileName, const std::string& keypointName) const; + + private: + const DataFormat mFormat; + }; +} + +#endif // OPENPOSE_FILESTREAM_KEYPOINT_SAVER_HPP diff --git a/include/openpose/filestream/poseJsonCocoSaver.hpp b/include/openpose/filestream/poseJsonCocoSaver.hpp deleted file mode 100644 index ed7a1ec6..00000000 --- a/include/openpose/filestream/poseJsonCocoSaver.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef OPENPOSE__FILESTREAM__POSE_JSON_COCO_SAVER_HPP -#define OPENPOSE__FILESTREAM__POSE_JSON_COCO_SAVER_HPP - -#include -#include -#include -#include "jsonOfstream.hpp" - -namespace op -{ - /** - * The PoseJsonCocoSaver class creates a COCO validation json file with details about the processed images. It inherits from Recorder. - */ - class PoseJsonCocoSaver - { - public: - /** - * This constructor of PoseJsonCocoSaver extends the Recorder::Recorder(const std::string & filePathToSave) constructor. - * @param filePathToSave const std::string parameter with the final file path where the generated json file will be saved. - */ - explicit PoseJsonCocoSaver(const std::string& filePathToSave, const bool humanReadable = true); - - ~PoseJsonCocoSaver(); - - void record(const Array& poseKeyPoints, const unsigned long long imageId); - - private: - JsonOfstream mJsonOfstream; - bool mFirstElementAdded; - - DELETE_COPY(PoseJsonCocoSaver); - }; -} - -#endif // OPENPOSE__FILESTREAM__POSE_JSON_COCO_SAVER_HPP diff --git a/include/openpose/filestream/poseJsonSaver.hpp b/include/openpose/filestream/poseJsonSaver.hpp deleted file mode 100644 index 802e18de..00000000 --- a/include/openpose/filestream/poseJsonSaver.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef OPENPOSE__FILESTREAM__POSE_JSON_SAVER_HPP -#define OPENPOSE__FILESTREAM__POSE_JSON_SAVER_HPP - -#include -#include -#include -#include "fileSaver.hpp" - -namespace op -{ - class PoseJsonSaver : public FileSaver - { - public: - explicit PoseJsonSaver(const std::string& directoryPath); - - void savePoseKeyPoints(const std::vector>& poseKeyPointsVector, const std::string& fileName) const; - }; -} - -#endif // OPENPOSE__FILESTREAM__POSE_JSON_SAVER_HPP diff --git a/include/openpose/filestream/poseSaver.hpp b/include/openpose/filestream/poseSaver.hpp deleted file mode 100644 index 73e8c5ba..00000000 --- a/include/openpose/filestream/poseSaver.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef OPENPOSE__FILESTREAM__POSE_SAVER_HPP -#define OPENPOSE__FILESTREAM__POSE_SAVER_HPP - -#include -#include "enumClasses.hpp" -#include "fileSaver.hpp" - -namespace op -{ - class PoseSaver : public FileSaver - { - public: - PoseSaver(const std::string& directoryPath, const DataFormat format); - - void savePoseKeyPoints(const std::vector>& poseKeyPointsVector, const std::string& fileName) const; - - private: - const DataFormat mFormat; - }; -} - -#endif // OPENPOSE__FILESTREAM__POSE_SAVER_HPP diff --git a/include/openpose/filestream/videoSaver.hpp b/include/openpose/filestream/videoSaver.hpp index 50fea451..4bb57cee 100644 --- a/include/openpose/filestream/videoSaver.hpp +++ b/include/openpose/filestream/videoSaver.hpp @@ -1,8 +1,8 @@ -#ifndef OPENPOSE__FILESTREAM__VIDEO_SAVER_HPP -#define OPENPOSE__FILESTREAM__VIDEO_SAVER_HPP +#ifndef OPENPOSE_FILESTREAM_VIDEO_SAVER_HPP +#define OPENPOSE_FILESTREAM_VIDEO_SAVER_HPP #include -#include +#include // cv::Mat #include // cv::VideoWriter #include @@ -11,9 +11,9 @@ namespace op class VideoSaver { public: - VideoSaver(const std::string& videoSaverPath, const int cvFourcc, const double fps, const cv::Size& cvSize); + VideoSaver(const std::string& videoSaverPath, const int cvFourcc, const double fps, const Point& cvSize); - VideoSaver(const std::vector& videoSaverPaths, const int cvFourcc, const double fps, const cv::Size& cvSize); + VideoSaver(const std::vector& videoSaverPaths, const int cvFourcc, const double fps, const Point& cvSize); bool isOpened(); @@ -28,4 +28,4 @@ namespace op }; } -#endif // OPENPOSE__FILESTREAM__VIDEO_SAVER_HPP +#endif // OPENPOSE_FILESTREAM_VIDEO_SAVER_HPP diff --git a/include/openpose/filestream/wFaceJsonSaver.hpp b/include/openpose/filestream/wFaceJsonSaver.hpp new file mode 100644 index 00000000..a5b278ef --- /dev/null +++ b/include/openpose/filestream/wFaceJsonSaver.hpp @@ -0,0 +1,86 @@ +#ifndef OPENPOSE_FILESTREAM_W_FACE_JSON_SAVER_HPP +#define OPENPOSE_FILESTREAM_W_FACE_JSON_SAVER_HPP + +#include // std::shared_ptr +#include +#include +#include "keypointJsonSaver.hpp" + +namespace op +{ + template + class WFaceJsonSaver : public WorkerConsumer + { + public: + explicit WFaceJsonSaver(const std::shared_ptr& keypointJsonSaver); + + void initializationOnThread(); + + void workConsumer(const TDatums& tDatums); + + private: + const std::shared_ptr spKeypointJsonSaver; + + DELETE_COPY(WFaceJsonSaver); + }; +} + + + + + +// Implementation +#include +#include +#include +#include +namespace op +{ + template + WFaceJsonSaver::WFaceJsonSaver(const std::shared_ptr& keypointJsonSaver) : + spKeypointJsonSaver{keypointJsonSaver} + { + } + + template + void WFaceJsonSaver::initializationOnThread() + { + } + + template + void WFaceJsonSaver::workConsumer(const TDatums& tDatums) + { + try + { + if (checkNoNullNorEmpty(tDatums)) + { + // Debugging log + dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + // Profiling speed + const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); + // T* to T + auto& tDatumsNoPtr = *tDatums; + // Record people face data in json format + std::vector> keypointVector(tDatumsNoPtr.size()); + for (auto i = 0; 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)); + spKeypointJsonSaver->saveKeypoints(keypointVector, fileName, "face"); + // Profiling speed + Profiler::timerEnd(profilerKey); + Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); + // Debugging log + dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + } + } + catch (const std::exception& e) + { + this->stop(); + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + COMPILE_TEMPLATE_DATUM(WFaceJsonSaver); +} + +#endif // OPENPOSE_FILESTREAM_W_FACE_JSON_SAVER_HPP diff --git a/include/openpose/filestream/wFaceSaver.hpp b/include/openpose/filestream/wFaceSaver.hpp new file mode 100644 index 00000000..681626b7 --- /dev/null +++ b/include/openpose/filestream/wFaceSaver.hpp @@ -0,0 +1,87 @@ +#ifndef OPENPOSE_FILESTREAM_W_FACE_SAVER_HPP +#define OPENPOSE_FILESTREAM_W_FACE_SAVER_HPP + +#include // std::shared_ptr +#include +#include +#include "enumClasses.hpp" +#include "keypointSaver.hpp" + +namespace op +{ + template + class WFaceSaver : public WorkerConsumer + { + public: + explicit WFaceSaver(const std::shared_ptr& keypointSaver); + + void initializationOnThread(); + + void workConsumer(const TDatums& tDatums); + + private: + const std::shared_ptr spKeypointSaver; + + DELETE_COPY(WFaceSaver); + }; +} + + + + + +// Implementation +#include +#include +#include +#include +namespace op +{ + template + WFaceSaver::WFaceSaver(const std::shared_ptr& keypointSaver) : + spKeypointSaver{keypointSaver} + { + } + + template + void WFaceSaver::initializationOnThread() + { + } + + template + void WFaceSaver::workConsumer(const TDatums& tDatums) + { + try + { + if (checkNoNullNorEmpty(tDatums)) + { + // Debugging log + dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + // Profiling speed + const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); + // T* to T + auto& tDatumsNoPtr = *tDatums; + // Record people face keypoint data + std::vector> keypointVector(tDatumsNoPtr.size()); + for (auto i = 0; 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)); + spKeypointSaver->saveKeypoints(keypointVector, fileName, "face"); + // Profiling speed + Profiler::timerEnd(profilerKey); + Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); + // Debugging log + dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + } + } + catch (const std::exception& e) + { + this->stop(); + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + COMPILE_TEMPLATE_DATUM(WFaceSaver); +} + +#endif // OPENPOSE_FILESTREAM_W_FACE_SAVER_HPP diff --git a/include/openpose/filestream/wHandJsonSaver.hpp b/include/openpose/filestream/wHandJsonSaver.hpp new file mode 100644 index 00000000..feaec096 --- /dev/null +++ b/include/openpose/filestream/wHandJsonSaver.hpp @@ -0,0 +1,86 @@ +#ifndef OPENPOSE_FILESTREAM_W_HAND_JSON_SAVER_HPP +#define OPENPOSE_FILESTREAM_W_HAND_JSON_SAVER_HPP + +#include // std::shared_ptr +#include +#include +#include "keypointJsonSaver.hpp" + +namespace op +{ + template + class WHandJsonSaver : public WorkerConsumer + { + public: + explicit WHandJsonSaver(const std::shared_ptr& keypointJsonSaver); + + void initializationOnThread(); + + void workConsumer(const TDatums& tDatums); + + private: + const std::shared_ptr spKeypointJsonSaver; + + DELETE_COPY(WHandJsonSaver); + }; +} + + + + + +// Implementation +#include +#include +#include +#include +namespace op +{ + template + WHandJsonSaver::WHandJsonSaver(const std::shared_ptr& keypointJsonSaver) : + spKeypointJsonSaver{keypointJsonSaver} + { + } + + template + void WHandJsonSaver::initializationOnThread() + { + } + + template + void WHandJsonSaver::workConsumer(const TDatums& tDatums) + { + try + { + if (checkNoNullNorEmpty(tDatums)) + { + // Debugging log + dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + // Profiling speed + const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); + // T* to T + auto& tDatumsNoPtr = *tDatums; + // Record people hand data in json format + std::vector> keypointVector(tDatumsNoPtr.size()); + for (auto i = 0; i < tDatumsNoPtr.size(); i++) + keypointVector[i] = tDatumsNoPtr[i].handKeypoints; + const auto fileName = (!tDatumsNoPtr[0].name.empty() ? tDatumsNoPtr[0].name : std::to_string(tDatumsNoPtr[0].id)); + spKeypointJsonSaver->saveKeypoints(keypointVector, fileName, "hand"); + // Profiling speed + Profiler::timerEnd(profilerKey); + Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); + // Debugging log + dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + } + } + catch (const std::exception& e) + { + this->stop(); + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + COMPILE_TEMPLATE_DATUM(WHandJsonSaver); +} + +#endif // OPENPOSE_FILESTREAM_W_HAND_JSON_SAVER_HPP diff --git a/include/openpose/filestream/wHandSaver.hpp b/include/openpose/filestream/wHandSaver.hpp new file mode 100644 index 00000000..92995717 --- /dev/null +++ b/include/openpose/filestream/wHandSaver.hpp @@ -0,0 +1,87 @@ +#ifndef OPENPOSE_FILESTREAM_W_HAND_SAVER_HPP +#define OPENPOSE_FILESTREAM_W_HAND_SAVER_HPP + +#include // std::shared_ptr +#include +#include +#include "enumClasses.hpp" +#include "keypointSaver.hpp" + +namespace op +{ + template + class WHandSaver : public WorkerConsumer + { + public: + explicit WHandSaver(const std::shared_ptr& keypointSaver); + + void initializationOnThread(); + + void workConsumer(const TDatums& tDatums); + + private: + const std::shared_ptr spKeypointSaver; + + DELETE_COPY(WHandSaver); + }; +} + + + + + +// Implementation +#include +#include +#include +#include +namespace op +{ + template + WHandSaver::WHandSaver(const std::shared_ptr& keypointSaver) : + spKeypointSaver{keypointSaver} + { + } + + template + void WHandSaver::initializationOnThread() + { + } + + template + void WHandSaver::workConsumer(const TDatums& tDatums) + { + try + { + if (checkNoNullNorEmpty(tDatums)) + { + // Debugging log + dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + // Profiling speed + const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); + // T* to T + auto& tDatumsNoPtr = *tDatums; + // Record people hand keypoint data + std::vector> keypointVector(tDatumsNoPtr.size()); + for (auto i = 0; i < tDatumsNoPtr.size(); i++) + keypointVector[i] = tDatumsNoPtr[i].handKeypoints; + const auto fileName = (!tDatumsNoPtr[0].name.empty() ? tDatumsNoPtr[0].name : std::to_string(tDatumsNoPtr[0].id)); + spKeypointSaver->saveKeypoints(keypointVector, fileName, "hand"); + // Profiling speed + Profiler::timerEnd(profilerKey); + Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); + // Debugging log + dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + } + } + catch (const std::exception& e) + { + this->stop(); + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + COMPILE_TEMPLATE_DATUM(WHandSaver); +} + +#endif // OPENPOSE_FILESTREAM_W_HAND_SAVER_HPP diff --git a/include/openpose/filestream/wHeatMapSaver.hpp b/include/openpose/filestream/wHeatMapSaver.hpp index a0fef902..f932dd30 100644 --- a/include/openpose/filestream/wHeatMapSaver.hpp +++ b/include/openpose/filestream/wHeatMapSaver.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__FILESTREAM__W_HEAT_MAP_SAVER_HPP -#define OPENPOSE__FILESTREAM__W_HEAT_MAP_SAVER_HPP +#ifndef OPENPOSE_FILESTREAM_W_HEAT_MAP_SAVER_HPP +#define OPENPOSE_FILESTREAM_W_HEAT_MAP_SAVER_HPP #include // std::shared_ptr #include @@ -31,7 +31,6 @@ namespace op // Implementation #include -#include #include #include #include @@ -85,4 +84,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WHeatMapSaver); } -#endif // OPENPOSE__FILESTREAM__W_HEAT_MAP_SAVER_HPP +#endif // OPENPOSE_FILESTREAM_W_HEAT_MAP_SAVER_HPP diff --git a/include/openpose/filestream/wImageSaver.hpp b/include/openpose/filestream/wImageSaver.hpp index ab183c1e..74fe792f 100644 --- a/include/openpose/filestream/wImageSaver.hpp +++ b/include/openpose/filestream/wImageSaver.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__FILESTREAM__W_IMAGE_SAVER_HPP -#define OPENPOSE__FILESTREAM__W_IMAGE_SAVER_HPP +#ifndef OPENPOSE_FILESTREAM_W_IMAGE_SAVER_HPP +#define OPENPOSE_FILESTREAM_W_IMAGE_SAVER_HPP #include // std::shared_ptr #include @@ -31,7 +31,6 @@ namespace op // Implementation #include -#include #include #include #include @@ -85,4 +84,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WImageSaver); } -#endif // OPENPOSE__FILESTREAM__W_IMAGE_SAVER_HPP +#endif // OPENPOSE_FILESTREAM_W_IMAGE_SAVER_HPP diff --git a/include/openpose/filestream/wPoseJsonSaver.hpp b/include/openpose/filestream/wPoseJsonSaver.hpp index 9a1b65eb..b172c97d 100644 --- a/include/openpose/filestream/wPoseJsonSaver.hpp +++ b/include/openpose/filestream/wPoseJsonSaver.hpp @@ -1,10 +1,10 @@ -#ifndef OPENPOSE__FILESTREAM__W_POSE_JSON_SAVER_HPP -#define OPENPOSE__FILESTREAM__W_POSE_JSON_SAVER_HPP +#ifndef OPENPOSE_FILESTREAM_W_POSE_JSON_SAVER_HPP +#define OPENPOSE_FILESTREAM_W_POSE_JSON_SAVER_HPP #include // std::shared_ptr #include #include -#include "poseJsonSaver.hpp" +#include "keypointJsonSaver.hpp" namespace op { @@ -12,14 +12,14 @@ namespace op class WPoseJsonSaver : public WorkerConsumer { public: - explicit WPoseJsonSaver(const std::shared_ptr& poseJsonSaver); + explicit WPoseJsonSaver(const std::shared_ptr& keypointJsonSaver); void initializationOnThread(); void workConsumer(const TDatums& tDatums); private: - const std::shared_ptr spPoseJsonSaver; + const std::shared_ptr spKeypointJsonSaver; DELETE_COPY(WPoseJsonSaver); }; @@ -37,8 +37,8 @@ namespace op namespace op { template - WPoseJsonSaver::WPoseJsonSaver(const std::shared_ptr& poseJsonSaver) : - spPoseJsonSaver{poseJsonSaver} + WPoseJsonSaver::WPoseJsonSaver(const std::shared_ptr& keypointJsonSaver) : + spKeypointJsonSaver{keypointJsonSaver} { } @@ -61,11 +61,11 @@ namespace op // T* to T auto& tDatumsNoPtr = *tDatums; // Record people pose data in json format - std::vector> poseKeyPointsVector(tDatumsNoPtr.size()); + std::vector> keypointVector(tDatumsNoPtr.size()); for (auto i = 0; i < tDatumsNoPtr.size(); i++) - poseKeyPointsVector[i] = tDatumsNoPtr[i].poseKeyPoints; + keypointVector[i] = tDatumsNoPtr[i].poseKeypoints; const auto fileName = (!tDatumsNoPtr[0].name.empty() ? tDatumsNoPtr[0].name : std::to_string(tDatumsNoPtr[0].id)); - spPoseJsonSaver->savePoseKeyPoints(poseKeyPointsVector, fileName); + spKeypointJsonSaver->saveKeypoints(keypointVector, fileName, "pose"); // Profiling speed Profiler::timerEnd(profilerKey); Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); @@ -83,4 +83,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WPoseJsonSaver); } -#endif // OPENPOSE__FILESTREAM__W_POSE_JSON_SAVER_HPP +#endif // OPENPOSE_FILESTREAM_W_POSE_JSON_SAVER_HPP diff --git a/include/openpose/filestream/wPoseSaver.hpp b/include/openpose/filestream/wPoseSaver.hpp index 78352e17..e7d318ee 100644 --- a/include/openpose/filestream/wPoseSaver.hpp +++ b/include/openpose/filestream/wPoseSaver.hpp @@ -1,11 +1,11 @@ -#ifndef OPENPOSE__FILESTREAM__W_POSE_SAVER_HPP -#define OPENPOSE__FILESTREAM__W_POSE_SAVER_HPP +#ifndef OPENPOSE_FILESTREAM_W_POSE_SAVER_HPP +#define OPENPOSE_FILESTREAM_W_POSE_SAVER_HPP #include // std::shared_ptr #include #include #include "enumClasses.hpp" -#include "poseSaver.hpp" +#include "keypointSaver.hpp" namespace op { @@ -13,14 +13,14 @@ namespace op class WPoseSaver : public WorkerConsumer { public: - explicit WPoseSaver(const std::shared_ptr& poseSaver); + explicit WPoseSaver(const std::shared_ptr& keypointSaver); void initializationOnThread(); void workConsumer(const TDatums& tDatums); private: - const std::shared_ptr spPoseSaver; + const std::shared_ptr spKeypointSaver; DELETE_COPY(WPoseSaver); }; @@ -38,8 +38,8 @@ namespace op namespace op { template - WPoseSaver::WPoseSaver(const std::shared_ptr& poseSaver) : - spPoseSaver{poseSaver} + WPoseSaver::WPoseSaver(const std::shared_ptr& keypointSaver) : + spKeypointSaver{keypointSaver} { } @@ -61,12 +61,12 @@ namespace op const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); // T* to T auto& tDatumsNoPtr = *tDatums; - // Record people pose data - std::vector> poseKeyPointsVector(tDatumsNoPtr.size()); + // Record people pose keypoint data + std::vector> keypointVector(tDatumsNoPtr.size()); for (auto i = 0; i < tDatumsNoPtr.size(); i++) - poseKeyPointsVector[i] = tDatumsNoPtr[i].poseKeyPoints; + keypointVector[i] = tDatumsNoPtr[i].poseKeypoints; const auto fileName = (!tDatumsNoPtr[0].name.empty() ? tDatumsNoPtr[0].name : std::to_string(tDatumsNoPtr[0].id)); - spPoseSaver->savePoseKeyPoints(poseKeyPointsVector, fileName); + spKeypointSaver->saveKeypoints(keypointVector, fileName, "pose"); // Profiling speed Profiler::timerEnd(profilerKey); Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); @@ -84,4 +84,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WPoseSaver); } -#endif // OPENPOSE__FILESTREAM__W_POSE_SAVER_HPP +#endif // OPENPOSE_FILESTREAM_W_POSE_SAVER_HPP diff --git a/include/openpose/filestream/wVideoSaver.hpp b/include/openpose/filestream/wVideoSaver.hpp index a330fbec..d8abfa59 100644 --- a/include/openpose/filestream/wVideoSaver.hpp +++ b/include/openpose/filestream/wVideoSaver.hpp @@ -1,10 +1,9 @@ -#ifndef OPENPOSE__FILESTREAM__W_VIDEO_SAVER_HPP -#define OPENPOSE__FILESTREAM__W_VIDEO_SAVER_HPP +#ifndef OPENPOSE_FILESTREAM_W_VIDEO_SAVER_HPP +#define OPENPOSE_FILESTREAM_W_VIDEO_SAVER_HPP #include // std::shared_ptr #include #include -#include #include #include "videoSaver.hpp" @@ -84,4 +83,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WVideoSaver); } -#endif // OPENPOSE__FILESTREAM__W_VIDEO_SAVER_HPP +#endif // OPENPOSE_FILESTREAM_W_VIDEO_SAVER_HPP diff --git a/include/openpose/gui/enumClasses.hpp b/include/openpose/gui/enumClasses.hpp index fa72d84f..e5740767 100644 --- a/include/openpose/gui/enumClasses.hpp +++ b/include/openpose/gui/enumClasses.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__GUI__ENUM_CLASSES_HPP -#define OPENPOSE__GUI__ENUM_CLASSES_HPP +#ifndef OPENPOSE_GUI_ENUM_CLASSES_HPP +#define OPENPOSE_GUI_ENUM_CLASSES_HPP namespace op { @@ -15,4 +15,4 @@ namespace op }; } -#endif // OPENPOSE__GUI__ENUM_CLASSES_HPP +#endif // OPENPOSE_GUI_ENUM_CLASSES_HPP diff --git a/include/openpose/gui/frameDisplayer.hpp b/include/openpose/gui/frameDisplayer.hpp index 3ba49189..a3e6a9b9 100644 --- a/include/openpose/gui/frameDisplayer.hpp +++ b/include/openpose/gui/frameDisplayer.hpp @@ -1,8 +1,9 @@ -#ifndef OPENPOSE__GUI__FRAMES_DISPLAY_HPP -#define OPENPOSE__GUI__FRAMES_DISPLAY_HPP +#ifndef OPENPOSE_GUI_FRAMES_DISPLAY_HPP +#define OPENPOSE_GUI_FRAMES_DISPLAY_HPP #include -#include +#include // cv::Mat +#include #include "enumClasses.hpp" namespace op @@ -16,10 +17,10 @@ namespace op /** * Constructor of the FrameDisplayer class. * @param fullScreen bool from which the FrameDisplayer::GuiDisplayMode property mGuiDisplayMode will be set, i.e. specifying the type of initial display (it can be changed later). - * @param windowedSize const cv::Size with the windored output resolution (width and height). + * @param windowedSize const Point with the windored output resolution (width and height). * @param windowedName const std::string value with the opencv resulting display name. Showed at the top-left part of the window. */ - FrameDisplayer(const cv::Size& windowedSize, const std::string& windowedName = "OpenPose Display", const bool fullScreen = false); + FrameDisplayer(const Point& windowedSize, const std::string& windowedName = "OpenPose Display", const bool fullScreen = false); // Due to OpenCV visualization issues (all visualization functions must be in the same thread) void initializationOnThread(); @@ -44,10 +45,10 @@ namespace op void displayFrame(const cv::Mat& frame, const int waitKeyValue = -1); private: - const cv::Size mWindowedSize; + const Point mWindowedSize; const std::string mWindowName; GuiDisplayMode mGuiDisplayMode; }; } -#endif // OPENPOSE__GUI__FRAMES_DISPLAY_HPP +#endif // OPENPOSE_GUI_FRAMES_DISPLAY_HPP diff --git a/include/openpose/gui/gui.hpp b/include/openpose/gui/gui.hpp index 98e5de5f..e550cda9 100644 --- a/include/openpose/gui/gui.hpp +++ b/include/openpose/gui/gui.hpp @@ -1,9 +1,10 @@ -#ifndef OPENPOSE__GUI__GUI_HPP -#define OPENPOSE__GUI__GUI_HPP +#ifndef OPENPOSE_GUI_GUI_HPP +#define OPENPOSE_GUI_GUI_HPP #include #include // std::shared_ptr -#include +#include // cv::Mat +#include #include #include #include "enumClasses.hpp" @@ -14,7 +15,7 @@ namespace op class Gui { public: - Gui(const bool fullScreen, const cv::Size& outputSize, const std::shared_ptr>& isRunningSharedPtr, + Gui(const bool fullScreen, const Point& outputSize, const std::shared_ptr>& isRunningSharedPtr, const std::shared_ptr, std::atomic>>& videoSeekSharedPtr = nullptr, const std::vector>& poseExtractors = {}, const std::vector>& poseRenderers = {}); @@ -33,4 +34,4 @@ namespace op }; } -#endif // OPENPOSE__GUI__GUI_HPP +#endif // OPENPOSE_GUI_GUI_HPP diff --git a/include/openpose/gui/guiInfoAdder.hpp b/include/openpose/gui/guiInfoAdder.hpp index f6179ae8..71429c0f 100644 --- a/include/openpose/gui/guiInfoAdder.hpp +++ b/include/openpose/gui/guiInfoAdder.hpp @@ -1,22 +1,23 @@ -#ifndef OPENPOSE__GUI__ADD_GUI_INFO_HPP -#define OPENPOSE__GUI__ADD_GUI_INFO_HPP +#ifndef OPENPOSE_GUI_ADD_GUI_INFO_HPP +#define OPENPOSE_GUI_ADD_GUI_INFO_HPP #include -#include +#include // cv::Mat #include +#include namespace op { class GuiInfoAdder { public: - GuiInfoAdder(const cv::Size& outputSize, const int numberGpus, const bool guiEnabled = false); + GuiInfoAdder(const Point& outputSize, const int numberGpus, const bool guiEnabled = false); - void addInfo(cv::Mat& cvOutputData, const Array& poseKeyPoints, const unsigned long long id, const std::string& elementRenderedName); + void addInfo(cv::Mat& cvOutputData, const Array& poseKeypoints, const unsigned long long id, const std::string& elementRenderedName); private: // Const variables - const cv::Size mOutputSize; + const Point mOutputSize; const int mBorderMargin; const int mNumberGpus; const bool mGuiEnabled; @@ -30,4 +31,4 @@ namespace op }; } -#endif // OPENPOSE__GUI__ADD_GUI_INFO_HPP +#endif // OPENPOSE_GUI_ADD_GUI_INFO_HPP diff --git a/include/openpose/gui/headers.hpp b/include/openpose/gui/headers.hpp index 4bb7ca76..b057dd81 100644 --- a/include/openpose/gui/headers.hpp +++ b/include/openpose/gui/headers.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__GUI__HEADERS_HPP -#define OPENPOSE__GUI__HEADERS_HPP +#ifndef OPENPOSE_GUI_HEADERS_HPP +#define OPENPOSE_GUI_HEADERS_HPP // gui module #include "enumClasses.hpp" @@ -9,4 +9,4 @@ #include "wGui.hpp" #include "wGuiInfoAdder.hpp" -#endif // OPENPOSE__GUI__HEADERS_HPP +#endif // OPENPOSE_GUI_HEADERS_HPP diff --git a/include/openpose/gui/wGui.hpp b/include/openpose/gui/wGui.hpp index e57c2949..cb4af65b 100644 --- a/include/openpose/gui/wGui.hpp +++ b/include/openpose/gui/wGui.hpp @@ -1,8 +1,7 @@ -#ifndef OPENPOSE__GUI__W_GUI_HPP -#define OPENPOSE__GUI__W_GUI_HPP +#ifndef OPENPOSE_GUI_W_GUI_HPP +#define OPENPOSE_GUI_W_GUI_HPP #include // std::shared_ptr -#include #include #include "enumClasses.hpp" #include "gui.hpp" @@ -95,4 +94,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WGui); } -#endif // OPENPOSE__GUI__W_GUI_HPP +#endif // OPENPOSE_GUI_W_GUI_HPP diff --git a/include/openpose/gui/wGuiInfoAdder.hpp b/include/openpose/gui/wGuiInfoAdder.hpp index 05eee471..7d5721d4 100644 --- a/include/openpose/gui/wGuiInfoAdder.hpp +++ b/include/openpose/gui/wGuiInfoAdder.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__GUI__W_ADD_GUI_INFO_HPP -#define OPENPOSE__GUI__W_ADD_GUI_INFO_HPP +#ifndef OPENPOSE_GUI_W_ADD_GUI_INFO_HPP +#define OPENPOSE_GUI_W_ADD_GUI_INFO_HPP #include "guiInfoAdder.hpp" #include @@ -58,7 +58,7 @@ namespace op const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); // Add GUI components to frame for (auto& tDatum : *tDatums) - spGuiInfoAdder->addInfo(tDatum.cvOutputData, tDatum.poseKeyPoints, tDatum.id, tDatum.elementRendered.second); + spGuiInfoAdder->addInfo(tDatum.cvOutputData, tDatum.poseKeypoints, tDatum.id, tDatum.elementRendered.second); // Profiling speed Profiler::timerEnd(profilerKey); Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); @@ -77,4 +77,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WGuiInfoAdder); } -#endif // OPENPOSE__GUI__W_ADD_GUI_INFO_HPP +#endif // OPENPOSE_GUI_W_ADD_GUI_INFO_HPP diff --git a/include/openpose/headers.hpp b/include/openpose/headers.hpp index 03349fc5..30072d7d 100644 --- a/include/openpose/headers.hpp +++ b/include/openpose/headers.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__HEADERS_HPP -#define OPENPOSE__HEADERS_HPP +#ifndef OPENPOSE_HEADERS_HPP +#define OPENPOSE_HEADERS_HPP // core module #include "core/headers.hpp" @@ -7,6 +7,9 @@ // experimental module #include "experimental/headers.hpp" +// face module +#include "face/headers.hpp" + // filestream module #include "filestream/headers.hpp" @@ -28,4 +31,4 @@ // wrapper module #include "wrapper/headers.hpp" -#endif // OPENPOSE__HEADERS_HPP +#endif // OPENPOSE_HEADERS_HPP diff --git a/include/openpose/pose/bodyPartConnectorBase.hpp b/include/openpose/pose/bodyPartConnectorBase.hpp index 347ed677..a816a6e0 100644 --- a/include/openpose/pose/bodyPartConnectorBase.hpp +++ b/include/openpose/pose/bodyPartConnectorBase.hpp @@ -1,18 +1,19 @@ -#ifndef OPENPOSE__POSE__BODY_PARTS_CONNECTOR_HPP -#define OPENPOSE__POSE__BODY_PARTS_CONNECTOR_HPP +#ifndef OPENPOSE_POSE_BODY_PARTS_CONNECTOR_HPP +#define OPENPOSE_POSE_BODY_PARTS_CONNECTOR_HPP #include +#include #include "enumClasses.hpp" namespace op { template - void connectBodyPartsCpu(Array& poseKeyPoints, const T* const heatMapPtr, const T* const peaksPtr, const PoseModel poseModel, const cv::Size& heatMapSize, const int maxPeaks, + void connectBodyPartsCpu(Array& poseKeypoints, const T* const heatMapPtr, const T* const peaksPtr, const PoseModel poseModel, const Point& heatMapSize, const int maxPeaks, const int interMinAboveThreshold, const T interThreshold, const int minSubsetCnt, const T minSubsetScore, const T scaleFactor = 1.f); template - void connectBodyPartsGpu(Array& poseKeyPoints, T* posePtr, const T* const heatMapPtr, const T* const peaksPtr, const PoseModel poseModel, const cv::Size& heatMapSize, + void connectBodyPartsGpu(Array& poseKeypoints, T* posePtr, const T* const heatMapPtr, const T* const peaksPtr, const PoseModel poseModel, const Point& heatMapSize, const int maxPeaks, const int interMinAboveThreshold, const T interThreshold, const int minSubsetCnt, const T minSubsetScore, const T scaleFactor = 1.f); } -#endif // OPENPOSE__POSE__BODY_PARTS_CONNECTOR_HPP +#endif // OPENPOSE_POSE_BODY_PARTS_CONNECTOR_HPP diff --git a/include/openpose/pose/bodyPartConnectorCaffe.hpp b/include/openpose/pose/bodyPartConnectorCaffe.hpp index 5f483969..31d515a1 100644 --- a/include/openpose/pose/bodyPartConnectorCaffe.hpp +++ b/include/openpose/pose/bodyPartConnectorCaffe.hpp @@ -1,10 +1,11 @@ #ifdef USE_CAFFE -#ifndef OPENPOSE__POSE__BODY_PART_CONNECTOR_CAFFE_HPP -#define OPENPOSE__POSE__BODY_PART_CONNECTOR_CAFFE_HPP +#ifndef OPENPOSE_POSE_BODY_PART_CONNECTOR_CAFFE_HPP +#define OPENPOSE_POSE_BODY_PART_CONNECTOR_CAFFE_HPP #include #include #include +#include #include #include "enumClasses.hpp" @@ -36,9 +37,9 @@ namespace op void setScaleNetToOutput(const T scaleNetToOutput); - virtual void Forward_cpu(const std::vector*>& bottom, Array& poseKeyPoints); + virtual void Forward_cpu(const std::vector*>& bottom, Array& poseKeypoints); - virtual void Forward_gpu(const std::vector*>& bottom, const std::vector*>& top, Array& poseKeyPoints); + virtual void Forward_gpu(const std::vector*>& bottom, const std::vector*>& top, Array& poseKeypoints); virtual void Backward_cpu(const std::vector*>& top, const std::vector& propagate_down, const std::vector*>& bottom); @@ -59,5 +60,5 @@ namespace op }; } -#endif // OPENPOSE__POSE__BODY_PART_CONNECTOR_CAFFE_HPP +#endif // OPENPOSE_POSE_BODY_PART_CONNECTOR_CAFFE_HPP #endif diff --git a/include/openpose/pose/enumClasses.hpp b/include/openpose/pose/enumClasses.hpp index 6c270545..6436d435 100644 --- a/include/openpose/pose/enumClasses.hpp +++ b/include/openpose/pose/enumClasses.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__POSE__ENUM_CLASSES_HPP -#define OPENPOSE__POSE__ENUM_CLASSES_HPP +#ifndef OPENPOSE_POSE_ENUM_CLASSES_HPP +#define OPENPOSE_POSE_ENUM_CLASSES_HPP namespace op { @@ -25,4 +25,4 @@ namespace op }; } -#endif // OPENPOSE__POSE__ENUM_CLASSES_HPP +#endif // OPENPOSE_POSE_ENUM_CLASSES_HPP diff --git a/include/openpose/pose/headers.hpp b/include/openpose/pose/headers.hpp index b1273ec7..879defe8 100644 --- a/include/openpose/pose/headers.hpp +++ b/include/openpose/pose/headers.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__POSE__HEADERS_HPP -#define OPENPOSE__POSE__HEADERS_HPP +#ifndef OPENPOSE_POSE_HEADERS_HPP +#define OPENPOSE_POSE_HEADERS_HPP // pose module #include "bodyPartConnectorBase.hpp" @@ -13,4 +13,4 @@ #include "wPoseExtractor.hpp" #include "wPoseRenderer.hpp" -#endif // OPENPOSE__POSE__HEADERS_HPP +#endif // OPENPOSE_POSE_HEADERS_HPP diff --git a/include/openpose/pose/poseExtractor.hpp b/include/openpose/pose/poseExtractor.hpp index 7965dd7b..306699ca 100644 --- a/include/openpose/pose/poseExtractor.hpp +++ b/include/openpose/pose/poseExtractor.hpp @@ -1,11 +1,11 @@ -#ifndef OPENPOSE__POSE__POSE_EXTRACTOR_HPP -#define OPENPOSE__POSE__POSE_EXTRACTOR_HPP +#ifndef OPENPOSE_POSE_POSE_EXTRACTOR_HPP +#define OPENPOSE_POSE_POSE_EXTRACTOR_HPP #include #include #include -#include #include +#include #include #include #include "poseParameters.hpp" @@ -15,14 +15,14 @@ namespace op class PoseExtractor { public: - PoseExtractor(const cv::Size& netOutputSize, const cv::Size& outputSize, const PoseModel poseModel, const std::vector& heatMapTypes = {}, - const ScaleMode heatMapScaleMode = ScaleMode::ZeroToOne); + PoseExtractor(const Point& netOutputSize, const Point& outputSize, const PoseModel poseModel, const std::vector& heatMapTypes = {}, + const ScaleMode heatMapScale = ScaleMode::ZeroToOne); virtual ~PoseExtractor(); void initializationOnThread(); - virtual void forwardPass(const Array& inputNetData, const cv::Size& inputDataSize) = 0; + virtual void forwardPass(const Array& inputNetData, const Point& inputDataSize) = 0; virtual const float* getHeatMapCpuConstPtr() const = 0; @@ -32,7 +32,7 @@ namespace op virtual const float* getPoseGpuConstPtr() const = 0; - Array getPoseKeyPoints() const; + Array getPoseKeypoints() const; double getScaleNetToOutput() const; @@ -44,9 +44,9 @@ namespace op protected: const PoseModel mPoseModel; - const cv::Size mNetOutputSize; - const cv::Size mOutputSize; - Array mPoseKeyPoints; + const Point mNetOutputSize; + const Point mOutputSize; + Array mPoseKeypoints; float mScaleNetToOutput; void checkThread() const; @@ -63,4 +63,4 @@ namespace op }; } -#endif // OPENPOSE__POSE__POSE_EXTRACTOR_HPP +#endif // OPENPOSE_POSE_POSE_EXTRACTOR_HPP diff --git a/include/openpose/pose/poseExtractorCaffe.hpp b/include/openpose/pose/poseExtractorCaffe.hpp index 34ba8bb9..9dc465db 100644 --- a/include/openpose/pose/poseExtractorCaffe.hpp +++ b/include/openpose/pose/poseExtractorCaffe.hpp @@ -1,11 +1,11 @@ #ifdef USE_CAFFE -#ifndef OPENPOSE__POSE__POSE_EXTRACTOR_CAFFE_HPP -#define OPENPOSE__POSE__POSE_EXTRACTOR_CAFFE_HPP +#ifndef OPENPOSE_POSE_POSE_EXTRACTOR_CAFFE_HPP +#define OPENPOSE_POSE_POSE_EXTRACTOR_CAFFE_HPP #include // std::shared_ptr -#include #include #include +#include #include #include #include @@ -19,15 +19,15 @@ namespace op class PoseExtractorCaffe : public PoseExtractor { public: - PoseExtractorCaffe(const cv::Size& netInputSize, const cv::Size& netOutputSize, const cv::Size& outputSize, const int scaleNumber, + PoseExtractorCaffe(const Point& netInputSize, const Point& netOutputSize, const Point& outputSize, const int scaleNumber, const float scaleGap, const PoseModel poseModel, const std::string& modelFolder, const int gpuId, const std::vector& heatMapTypes = {}, - const ScaleMode heatMapScaleMode = ScaleMode::ZeroToOne); + const ScaleMode heatMapScale = ScaleMode::ZeroToOne); virtual ~PoseExtractorCaffe(); void netInitializationOnThread(); - void forwardPass(const Array& inputNetData, const cv::Size& inputDataSize); + void forwardPass(const Array& inputNetData, const Point& inputDataSize); const float* getHeatMapCpuConstPtr() const; @@ -50,5 +50,5 @@ namespace op }; } -#endif // OPENPOSE__POSE__POSE_EXTRACTOR_CAFFE_HPP +#endif // OPENPOSE_POSE_POSE_EXTRACTOR_CAFFE_HPP #endif diff --git a/include/openpose/pose/poseParameters.hpp b/include/openpose/pose/poseParameters.hpp index 271ef3d5..4e5b8e6a 100644 --- a/include/openpose/pose/poseParameters.hpp +++ b/include/openpose/pose/poseParameters.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__POSE__POSE_PARAMETERS_HPP -#define OPENPOSE__POSE__POSE_PARAMETERS_HPP +#ifndef OPENPOSE_POSE_POSE_PARAMETERS_HPP +#define OPENPOSE_POSE_POSE_PARAMETERS_HPP #include #include @@ -88,12 +88,12 @@ namespace op const std::array POSE_DEFAULT_CONNECT_MIN_SUBSET_SCORE{ 0.4f, 0.4f, 0.4f}; // Rendering default parameters - const auto POSE_DEFAULT_ALPHA_POSE = 0.6f; - const auto POSE_DEFAULT_ALPHA_HEATMAP = 0.7f; + const auto POSE_DEFAULT_ALPHA_KEYPOINT = 0.6f; + const auto POSE_DEFAULT_ALPHA_HEAT_MAP = 0.7f; // Auxiliary functions unsigned int poseBodyPartMapStringToKey(const PoseModel poseModel, const std::string& string); unsigned int poseBodyPartMapStringToKey(const PoseModel poseModel, const std::vector& strings); } -#endif // OPENPOSE__POSE__POSE_PARAMETERS_HPP +#endif // OPENPOSE_POSE_POSE_PARAMETERS_HPP diff --git a/include/openpose/pose/poseRenderGpu.hpp b/include/openpose/pose/poseRenderGpu.hpp index 34d776be..d42743cc 100644 --- a/include/openpose/pose/poseRenderGpu.hpp +++ b/include/openpose/pose/poseRenderGpu.hpp @@ -1,22 +1,22 @@ -#ifndef OPENPOSE__POSE__GPU_POSE_RENDER_HPP -#define OPENPOSE__POSE__GPU_POSE_RENDER_HPP +#ifndef OPENPOSE_POSE_GPU_POSE_RENDER_HPP +#define OPENPOSE_POSE_GPU_POSE_RENDER_HPP -#include +#include #include "enumClasses.hpp" #include "poseParameters.hpp" namespace op { - void renderPoseGpu(float* framePtr, const PoseModel poseModel, const int numberPeople, const cv::Size& frameSize, const float* const posePtr, - const bool googlyEyes = false, const bool blendOriginalFrame = true, const float alphaBlending = POSE_DEFAULT_ALPHA_POSE); - void renderBodyPartGpu(float* frame, const PoseModel poseModel, const cv::Size& frameSize, const float* const heatmap, const cv::Size& heatmapSize, - const float scaleToKeepRatio, const int part, const float alphaBlending = POSE_DEFAULT_ALPHA_HEATMAP); - void renderBodyPartsGpu(float* frame, const PoseModel poseModel, const cv::Size& frameSize, const float* const heatmap, const cv::Size& heatmapSize, - const float scaleToKeepRatio, const float alphaBlending = POSE_DEFAULT_ALPHA_HEATMAP); - void renderPartAffinityFieldGpu(float* framePtr, const PoseModel poseModel, const cv::Size& frameSize, const float* const heatmapPtr, - const cv::Size& heatmapSize, const float scaleToKeepRatio, const int part, const float alphaBlending = POSE_DEFAULT_ALPHA_HEATMAP); - void renderPartAffinityFieldsGpu(float* framePtr, const PoseModel poseModel, const cv::Size& frameSize, const float* const heatmapPtr, - const cv::Size& heatmapSize, const float scaleToKeepRatio, const float alphaBlending = POSE_DEFAULT_ALPHA_HEATMAP); + void renderPoseGpu(float* framePtr, const PoseModel poseModel, const int numberPeople, const Point& frameSize, const float* const posePtr, + const bool googlyEyes = false, const bool blendOriginalFrame = true, const float alphaBlending = POSE_DEFAULT_ALPHA_KEYPOINT); + void renderBodyPartGpu(float* frame, const PoseModel poseModel, const Point& frameSize, const float* const heatmap, const Point& heatmapSize, + const float scaleToKeepRatio, const int part, const float alphaBlending = POSE_DEFAULT_ALPHA_HEAT_MAP); + void renderBodyPartsGpu(float* frame, const PoseModel poseModel, const Point& frameSize, const float* const heatmap, const Point& heatmapSize, + const float scaleToKeepRatio, const float alphaBlending = POSE_DEFAULT_ALPHA_HEAT_MAP); + void renderPartAffinityFieldGpu(float* framePtr, const PoseModel poseModel, const Point& frameSize, const float* const heatmapPtr, + const Point& heatmapSize, const float scaleToKeepRatio, const int part, const float alphaBlending = POSE_DEFAULT_ALPHA_HEAT_MAP); + void renderPartAffinityFieldsGpu(float* framePtr, const PoseModel poseModel, const Point& frameSize, const float* const heatmapPtr, + const Point& heatmapSize, const float scaleToKeepRatio, const float alphaBlending = POSE_DEFAULT_ALPHA_HEAT_MAP); } -#endif // OPENPOSE__POSE__GPU_POSE_RENDER_HPP +#endif // OPENPOSE_POSE_GPU_POSE_RENDER_HPP diff --git a/include/openpose/pose/poseRenderer.hpp b/include/openpose/pose/poseRenderer.hpp index 2f1955df..4ad50bf5 100644 --- a/include/openpose/pose/poseRenderer.hpp +++ b/include/openpose/pose/poseRenderer.hpp @@ -1,9 +1,9 @@ -#ifndef OPENPOSE__POSE__POSE_RENDERER_HPP -#define OPENPOSE__POSE__POSE_RENDERER_HPP +#ifndef OPENPOSE_POSE_POSE_RENDERER_HPP +#define OPENPOSE_POSE_POSE_RENDERER_HPP #include // std::shared_ptr -#include #include +#include #include #include #include "poseExtractor.hpp" @@ -14,26 +14,14 @@ namespace op class PoseRenderer : public Renderer { public: - explicit PoseRenderer(const cv::Size& heatMapsSize, const cv::Size& outputSize, const PoseModel poseModel, const std::shared_ptr& poseExtractor, - const bool blendOriginalFrame = true, const float alphaPose = POSE_DEFAULT_ALPHA_POSE, - const float alphaHeatMap = POSE_DEFAULT_ALPHA_HEATMAP, const unsigned int elementToRender = 0u); + explicit PoseRenderer(const Point& heatMapsSize, const Point& outputSize, const PoseModel poseModel, const std::shared_ptr& poseExtractor, + const bool blendOriginalFrame = true, const float alphaKeypoint = POSE_DEFAULT_ALPHA_KEYPOINT, + const float alphaHeatMap = POSE_DEFAULT_ALPHA_HEAT_MAP, const unsigned int elementToRender = 0u); ~PoseRenderer(); void initializationOnThread(); - void increaseElementToRender(const int increment); - - void setElementToRender(const int elementToRender); - - float getAlphaPose() const; - - void setAlphaPose(const float alphaPose); - - float getAlphaHeatMap() const; - - void setAlphaHeatMap(const float alphaHeatMap); - bool getBlendOriginalFrame() const; bool getShowGooglyEyes() const; @@ -42,20 +30,16 @@ namespace op void setShowGooglyEyes(const bool showGooglyEyes); - std::pair renderPose(Array& outputData, const Array& poseKeyPoints, const float scaleNetToOutput = -1.f); + std::pair renderPose(Array& outputData, const Array& poseKeypoints, const float scaleNetToOutput = -1.f); private: - const cv::Size mHeatMapsSize; - const cv::Size mOutputSize; + const Point mHeatMapsSize; + const Point mOutputSize; const PoseModel mPoseModel; const std::map mPartIndexToName; - const int mNumberElementsToRender; const std::shared_ptr spPoseExtractor; - float mAlphaPose; - float mAlphaHeatMap; std::atomic mBlendOriginalFrame; std::atomic mShowGooglyEyes; - std::atomic mElementToRender; // Init with thread float* pGpuPose; // GPU aux memory @@ -63,4 +47,4 @@ namespace op }; } -#endif // OPENPOSE__POSE__POSE_RENDERER_HPP +#endif // OPENPOSE_POSE_POSE_RENDERER_HPP diff --git a/include/openpose/pose/wPoseExtractor.hpp b/include/openpose/pose/wPoseExtractor.hpp index d173dd9e..d2c54569 100644 --- a/include/openpose/pose/wPoseExtractor.hpp +++ b/include/openpose/pose/wPoseExtractor.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__POSE__W_POSE_EXTRACTOR_HPP -#define OPENPOSE__POSE__W_POSE_EXTRACTOR_HPP +#ifndef OPENPOSE_POSE_W_POSE_EXTRACTOR_HPP +#define OPENPOSE_POSE_W_POSE_EXTRACTOR_HPP #include // std::shared_ptr #include @@ -61,9 +61,9 @@ namespace op // Extract people pose for (auto& tDatum : *tDatums) { - spPoseExtractor->forwardPass(tDatum.inputNetData, tDatum.cvInputData.size()); + spPoseExtractor->forwardPass(tDatum.inputNetData, Point{tDatum.cvInputData.cols, tDatum.cvInputData.rows}); tDatum.poseHeatMaps = spPoseExtractor->getHeatMaps(); - tDatum.poseKeyPoints = spPoseExtractor->getPoseKeyPoints(); + tDatum.poseKeypoints = spPoseExtractor->getPoseKeypoints(); tDatum.scaleNetToOutput = spPoseExtractor->getScaleNetToOutput(); } // Profiling speed @@ -84,4 +84,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WPoseExtractor); } -#endif // OPENPOSE__POSE__W_POSE_EXTRACTOR_HPP +#endif // OPENPOSE_POSE_W_POSE_EXTRACTOR_HPP diff --git a/include/openpose/pose/wPoseRenderer.hpp b/include/openpose/pose/wPoseRenderer.hpp index b02f5a2c..1c245718 100644 --- a/include/openpose/pose/wPoseRenderer.hpp +++ b/include/openpose/pose/wPoseRenderer.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__POSE__W_POSE_RENDERER_HPP -#define OPENPOSE__POSE__W_POSE_RENDERER_HPP +#ifndef OPENPOSE_POSE_W_POSE_RENDERER_HPP +#define OPENPOSE_POSE_W_POSE_RENDERER_HPP #include // std::shared_ptr #include @@ -60,7 +60,7 @@ namespace op 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.scaleNetToOutput); + tDatum.elementRendered = spPoseRenderer->renderPose(tDatum.outputData, tDatum.poseKeypoints, (float)tDatum.scaleNetToOutput); // Profiling speed Profiler::timerEnd(profilerKey); Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X); @@ -79,4 +79,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WPoseRenderer); } -#endif // OPENPOSE__POSE__W_POSE_RENDERER_HPP +#endif // OPENPOSE_POSE_W_POSE_RENDERER_HPP diff --git a/include/openpose/producer/datumProducer.hpp b/include/openpose/producer/datumProducer.hpp index b2ec95c4..0cb0530a 100644 --- a/include/openpose/producer/datumProducer.hpp +++ b/include/openpose/producer/datumProducer.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__PRODUCER__DATUM_PRODUCER_HPP -#define OPENPOSE__PRODUCER__DATUM_PRODUCER_HPP +#ifndef OPENPOSE_PRODUCER_DATUM_PRODUCER_HPP +#define OPENPOSE_PRODUCER_DATUM_PRODUCER_HPP #include #include // std::numeric_limits @@ -126,4 +126,4 @@ namespace op } -#endif // OPENPOSE__PRODUCER__DATUM_PRODUCER_HPP +#endif // OPENPOSE_PRODUCER_DATUM_PRODUCER_HPP diff --git a/include/openpose/producer/enumClasses.hpp b/include/openpose/producer/enumClasses.hpp index b1469e99..9627cf06 100644 --- a/include/openpose/producer/enumClasses.hpp +++ b/include/openpose/producer/enumClasses.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__PRODUCER__ENUM_CLASSES_HPP -#define OPENPOSE__PRODUCER__ENUM_CLASSES_HPP +#ifndef OPENPOSE_PRODUCER_ENUM_CLASSES_HPP +#define OPENPOSE_PRODUCER_ENUM_CLASSES_HPP namespace op { @@ -31,4 +31,4 @@ namespace op }; } -#endif // OPENPOSE__PRODUCER__ENUM_CLASSES_HPP +#endif // OPENPOSE_PRODUCER_ENUM_CLASSES_HPP diff --git a/include/openpose/producer/headers.hpp b/include/openpose/producer/headers.hpp index c563dc04..65a7d71e 100644 --- a/include/openpose/producer/headers.hpp +++ b/include/openpose/producer/headers.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__PRODUCER__HEADERS_HPP -#define OPENPOSE__PRODUCER__HEADERS_HPP +#ifndef OPENPOSE_PRODUCER_HEADERS_HPP +#define OPENPOSE_PRODUCER_HEADERS_HPP // producer module #include "datumProducer.hpp" @@ -11,4 +11,4 @@ #include "webcamReader.hpp" #include "wDatumProducer.hpp" -#endif // OPENPOSE__PRODUCER__HEADERS_HPP +#endif // OPENPOSE_PRODUCER_HEADERS_HPP diff --git a/include/openpose/producer/imageDirectoryReader.hpp b/include/openpose/producer/imageDirectoryReader.hpp index 3feef3b8..457bf18c 100644 --- a/include/openpose/producer/imageDirectoryReader.hpp +++ b/include/openpose/producer/imageDirectoryReader.hpp @@ -1,8 +1,9 @@ -#ifndef OPENPOSE__PRODUCER__IMAGE_DIRECTORY_READER_HPP -#define OPENPOSE__PRODUCER__IMAGE_DIRECTORY_READER_HPP +#ifndef OPENPOSE_PRODUCER_IMAGE_DIRECTORY_READER_HPP +#define OPENPOSE_PRODUCER_IMAGE_DIRECTORY_READER_HPP #include #include +#include #include "producer.hpp" namespace op @@ -51,7 +52,7 @@ namespace op private: const std::string mImageDirectoryPath; const std::vector mFilePaths; - cv::Size mResolution; + Point mResolution; long long mFrameNameCounter; cv::Mat getRawFrame(); @@ -60,4 +61,4 @@ namespace op }; } -#endif // OPENPOSE__PRODUCER__IMAGE_DIRECTORY_READER_HPP +#endif // OPENPOSE_PRODUCER_IMAGE_DIRECTORY_READER_HPP diff --git a/include/openpose/producer/producer.hpp b/include/openpose/producer/producer.hpp index bf9367a3..dad2e46f 100644 --- a/include/openpose/producer/producer.hpp +++ b/include/openpose/producer/producer.hpp @@ -1,10 +1,10 @@ -#ifndef OPENPOSE__PRODUCER__PRODUCER_HPP -#define OPENPOSE__PRODUCER__PRODUCER_HPP +#ifndef OPENPOSE_PRODUCER_PRODUCER_HPP +#define OPENPOSE_PRODUCER_PRODUCER_HPP #include #include -#include -#include // capProperties of OpenCV +#include // cv::Mat +#include // capProperties of OpenCV #include #include "enumClasses.hpp" @@ -142,4 +142,4 @@ namespace op }; } -#endif // OPENPOSE__PRODUCER__PRODUCER_HPP +#endif // OPENPOSE_PRODUCER_PRODUCER_HPP diff --git a/include/openpose/producer/videoCaptureReader.hpp b/include/openpose/producer/videoCaptureReader.hpp index 3ead44c4..cbf20c42 100644 --- a/include/openpose/producer/videoCaptureReader.hpp +++ b/include/openpose/producer/videoCaptureReader.hpp @@ -1,9 +1,9 @@ -#ifndef OPENPOSE__PRODUCER__VIDEO_CAPTURE_READER_HPP -#define OPENPOSE__PRODUCER__VIDEO_CAPTURE_READER_HPP +#ifndef OPENPOSE_PRODUCER_VIDEO_CAPTURE_READER_HPP +#define OPENPOSE_PRODUCER_VIDEO_CAPTURE_READER_HPP #include -#include // cv::Mat -#include // cv::VideoCapture +#include // cv::Mat +#include // cv::VideoCapture #include "producer.hpp" namespace op @@ -69,4 +69,4 @@ namespace op }; } -#endif // OPENPOSE__PRODUCER__VIDEO_CAPTURE_READER_HPP +#endif // OPENPOSE_PRODUCER_VIDEO_CAPTURE_READER_HPP diff --git a/include/openpose/producer/videoReader.hpp b/include/openpose/producer/videoReader.hpp index 02b2a7fc..5669e29e 100644 --- a/include/openpose/producer/videoReader.hpp +++ b/include/openpose/producer/videoReader.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__PRODUCER__VIDEO_READER_HPP -#define OPENPOSE__PRODUCER__VIDEO_READER_HPP +#ifndef OPENPOSE_PRODUCER_VIDEO_READER_HPP +#define OPENPOSE_PRODUCER_VIDEO_READER_HPP #include "videoCaptureReader.hpp" @@ -35,4 +35,4 @@ namespace op }; } -#endif // OPENPOSE__PRODUCER__VIDEO_READER_HPP +#endif // OPENPOSE_PRODUCER_VIDEO_READER_HPP diff --git a/include/openpose/producer/wDatumProducer.hpp b/include/openpose/producer/wDatumProducer.hpp index f54a19d6..2b0e3490 100644 --- a/include/openpose/producer/wDatumProducer.hpp +++ b/include/openpose/producer/wDatumProducer.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__PRODUCER__W_DATUM_PRODUCER_HPP -#define OPENPOSE__PRODUCER__W_DATUM_PRODUCER_HPP +#ifndef OPENPOSE_PRODUCER_W_DATUM_PRODUCER_HPP +#define OPENPOSE_PRODUCER_W_DATUM_PRODUCER_HPP #include // std::numeric_limits #include // std::shared_ptr @@ -81,4 +81,4 @@ namespace op extern template class WDatumProducer; } -#endif // OPENPOSE__PRODUCER__W_DATUM_PRODUCER_HPP +#endif // OPENPOSE_PRODUCER_W_DATUM_PRODUCER_HPP diff --git a/include/openpose/producer/webcamReader.hpp b/include/openpose/producer/webcamReader.hpp index 079c3a50..a9248b22 100644 --- a/include/openpose/producer/webcamReader.hpp +++ b/include/openpose/producer/webcamReader.hpp @@ -1,8 +1,9 @@ -#ifndef OPENPOSE__PRODUCER__WEBCAM_READER_HPP -#define OPENPOSE__PRODUCER__WEBCAM_READER_HPP +#ifndef OPENPOSE_PRODUCER_WEBCAM_READER_HPP +#define OPENPOSE_PRODUCER_WEBCAM_READER_HPP #include #include +#include #include "videoCaptureReader.hpp" namespace op @@ -19,9 +20,9 @@ namespace op * to indicate the desired resolution. * @param webcamIndex const int indicating the camera source (see the OpenCV documentation about * cv::VideoCapture for more details), in the range [0, 9]. - * @param webcamResolution const cv::Size parameter which specifies the desired camera resolution. + * @param webcamResolution const Point parameter which specifies the desired camera resolution. */ - explicit WebcamReader(const int webcamIndex = 0, const cv::Size webcamResolution = cv::Size{}); + explicit WebcamReader(const int webcamIndex = 0, const Point webcamResolution = Point{}); ~WebcamReader(); @@ -44,4 +45,4 @@ namespace op }; } -#endif // OPENPOSE__PRODUCER__WEBCAM_READER_HPP +#endif // OPENPOSE_PRODUCER_WEBCAM_READER_HPP diff --git a/include/openpose/thread/enumClasses.hpp b/include/openpose/thread/enumClasses.hpp index b3e43cd0..3d648b5c 100644 --- a/include/openpose/thread/enumClasses.hpp +++ b/include/openpose/thread/enumClasses.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__THREAD__ENUM_CLASSES_HPP -#define OPENPOSE__THREAD__ENUM_CLASSES_HPP +#ifndef OPENPOSE_THREAD_ENUM_CLASSES_HPP +#define OPENPOSE_THREAD_ENUM_CLASSES_HPP namespace op { @@ -24,4 +24,4 @@ namespace op }; } -#endif // OPENPOSE__THREAD__ENUM_CLASSES_HPP +#endif // OPENPOSE_THREAD_ENUM_CLASSES_HPP diff --git a/include/openpose/thread/headers.hpp b/include/openpose/thread/headers.hpp index 7faabaa4..3a8585d8 100644 --- a/include/openpose/thread/headers.hpp +++ b/include/openpose/thread/headers.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__THREAD__HEADERS_HPP -#define OPENPOSE__THREAD__HEADERS_HPP +#ifndef OPENPOSE_THREAD_HEADERS_HPP +#define OPENPOSE_THREAD_HEADERS_HPP // thread module #include "enumClasses.hpp" @@ -19,4 +19,4 @@ #include "wIdGenerator.hpp" #include "wQueueOrderer.hpp" -#endif // OPENPOSE__THREAD__HEADERS_HPP +#endif // OPENPOSE_THREAD_HEADERS_HPP diff --git a/include/openpose/thread/priorityQueue.hpp b/include/openpose/thread/priorityQueue.hpp index a2b25380..e526ccd3 100644 --- a/include/openpose/thread/priorityQueue.hpp +++ b/include/openpose/thread/priorityQueue.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__THREAD__PRIORITY_QUEUE_HPP -#define OPENPOSE__THREAD__PRIORITY_QUEUE_HPP +#ifndef OPENPOSE_THREAD_PRIORITY_QUEUE_HPP +#define OPENPOSE_THREAD_PRIORITY_QUEUE_HPP #include // std::priority_queue #include @@ -79,4 +79,4 @@ namespace op COMPILE_TEMPLATE_DATUM(PriorityQueue); } -#endif // OPENPOSE__THREAD__PRIORITY_QUEUE_HPP +#endif // OPENPOSE_THREAD_PRIORITY_QUEUE_HPP diff --git a/include/openpose/thread/queue.hpp b/include/openpose/thread/queue.hpp index 08a00d9f..8d3ff913 100644 --- a/include/openpose/thread/queue.hpp +++ b/include/openpose/thread/queue.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__THREAD__QUEUE_HPP -#define OPENPOSE__THREAD__QUEUE_HPP +#ifndef OPENPOSE_THREAD_QUEUE_HPP +#define OPENPOSE_THREAD_QUEUE_HPP #include // std::queue #include @@ -81,4 +81,4 @@ namespace op COMPILE_TEMPLATE_DATUM(Queue); } -#endif // OPENPOSE__THREAD__QUEUE_HPP +#endif // OPENPOSE_THREAD_QUEUE_HPP diff --git a/include/openpose/thread/queueBase.hpp b/include/openpose/thread/queueBase.hpp index 2d7a47a8..bf156d90 100644 --- a/include/openpose/thread/queueBase.hpp +++ b/include/openpose/thread/queueBase.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__THREAD__QUEUE_BASE_HPP -#define OPENPOSE__THREAD__QUEUE_BASE_HPP +#ifndef OPENPOSE_THREAD_QUEUE_BASE_HPP +#define OPENPOSE_THREAD_QUEUE_BASE_HPP #include // std::queue & std::priority_queue #include @@ -505,4 +505,4 @@ namespace op extern template class QueueBase, std::greater>>; } -#endif // OPENPOSE__THREAD__QUEUE_BASE_HPP +#endif // OPENPOSE_THREAD_QUEUE_BASE_HPP diff --git a/include/openpose/thread/subThread.hpp b/include/openpose/thread/subThread.hpp index 3e215672..80341424 100644 --- a/include/openpose/thread/subThread.hpp +++ b/include/openpose/thread/subThread.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__THREAD__SUB_THREAD_HPP -#define OPENPOSE__THREAD__SUB_THREAD_HPP +#ifndef OPENPOSE_THREAD_SUB_THREAD_HPP +#define OPENPOSE_THREAD_SUB_THREAD_HPP #include #include @@ -157,4 +157,4 @@ namespace op COMPILE_TEMPLATE_DATUM(SubThread); } -#endif // OPENPOSE__THREAD__SUB_THREAD_HPP +#endif // OPENPOSE_THREAD_SUB_THREAD_HPP diff --git a/include/openpose/thread/subThreadNoQueue.hpp b/include/openpose/thread/subThreadNoQueue.hpp index 7a4e2251..d2f5cddf 100644 --- a/include/openpose/thread/subThreadNoQueue.hpp +++ b/include/openpose/thread/subThreadNoQueue.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__SUB_THREAD__THREAD_NO_QUEUE_HPP -#define OPENPOSE__SUB_THREAD__THREAD_NO_QUEUE_HPP +#ifndef OPENPOSE_THREAD_THREAD_NO_QUEUE_HPP +#define OPENPOSE_THREAD_THREAD_NO_QUEUE_HPP #include #include "thread.hpp" @@ -51,4 +51,4 @@ namespace op COMPILE_TEMPLATE_DATUM(SubThreadNoQueue); } -#endif // OPENPOSE__SUB_THREAD__THREAD_NO_QUEUE_HPP +#endif // OPENPOSE_THREAD_THREAD_NO_QUEUE_HPP diff --git a/include/openpose/thread/subThreadQueueIn.hpp b/include/openpose/thread/subThreadQueueIn.hpp index dbdafaf1..d65f6751 100644 --- a/include/openpose/thread/subThreadQueueIn.hpp +++ b/include/openpose/thread/subThreadQueueIn.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__SUB_THREAD__THREAD_QUEUE_IN_HPP -#define OPENPOSE__SUB_THREAD__THREAD_QUEUE_IN_HPP +#ifndef OPENPOSE_THREAD_THREAD_QUEUE_IN_HPP +#define OPENPOSE_THREAD_THREAD_QUEUE_IN_HPP #include // std::shared_ptr #include @@ -70,4 +70,4 @@ namespace op COMPILE_TEMPLATE_DATUM(SubThreadQueueIn); } -#endif // OPENPOSE__SUB_THREAD__THREAD_QUEUE_IN_HPP +#endif // OPENPOSE_THREAD_THREAD_QUEUE_IN_HPP diff --git a/include/openpose/thread/subThreadQueueInOut.hpp b/include/openpose/thread/subThreadQueueInOut.hpp index 0f5bc5bd..a05d7ebb 100644 --- a/include/openpose/thread/subThreadQueueInOut.hpp +++ b/include/openpose/thread/subThreadQueueInOut.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__SUB_THREAD__THREAD_QUEUE_IN_OUT_HPP -#define OPENPOSE__SUB_THREAD__THREAD_QUEUE_IN_OUT_HPP +#ifndef OPENPOSE_THREAD_THREAD_QUEUE_IN_OUT_HPP +#define OPENPOSE_THREAD_THREAD_QUEUE_IN_OUT_HPP #include // std::shared_ptr #include @@ -94,4 +94,4 @@ namespace op COMPILE_TEMPLATE_DATUM(SubThreadQueueInOut); } -#endif // OPENPOSE__SUB_THREAD__THREAD_QUEUE_IN_OUT_HPP +#endif // OPENPOSE_THREAD_THREAD_QUEUE_IN_OUT_HPP diff --git a/include/openpose/thread/subThreadQueueOut.hpp b/include/openpose/thread/subThreadQueueOut.hpp index 8066c03f..fe5414b6 100644 --- a/include/openpose/thread/subThreadQueueOut.hpp +++ b/include/openpose/thread/subThreadQueueOut.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__SUB_THREAD__THREAD_QUEUE_OUT_HPP -#define OPENPOSE__SUB_THREAD__THREAD_QUEUE_OUT_HPP +#ifndef OPENPOSE_THREAD_THREAD_QUEUE_OUT_HPP +#define OPENPOSE_THREAD_THREAD_QUEUE_OUT_HPP #include // std::shared_ptr #include @@ -78,4 +78,4 @@ namespace op COMPILE_TEMPLATE_DATUM(SubThreadQueueOut); } -#endif // OPENPOSE__SUB_THREAD__THREAD_QUEUE_OUT_HPP +#endif // OPENPOSE_THREAD_THREAD_QUEUE_OUT_HPP diff --git a/include/openpose/thread/thread.hpp b/include/openpose/thread/thread.hpp index 2f2096de..4cb9259a 100644 --- a/include/openpose/thread/thread.hpp +++ b/include/openpose/thread/thread.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__THREAD__THREAD_HPP -#define OPENPOSE__THREAD__THREAD_HPP +#ifndef OPENPOSE_THREAD_THREAD_HPP +#define OPENPOSE_THREAD_THREAD_HPP #include #include // std::shared_ptr @@ -237,4 +237,4 @@ namespace op COMPILE_TEMPLATE_DATUM(Thread); } -#endif // OPENPOSE__THREAD__THREAD_HPP +#endif // OPENPOSE_THREAD_THREAD_HPP diff --git a/include/openpose/thread/threadManager.hpp b/include/openpose/thread/threadManager.hpp index ac3b845d..d894aef1 100644 --- a/include/openpose/thread/threadManager.hpp +++ b/include/openpose/thread/threadManager.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__THREAD__THREAD_MANAGER_HPP -#define OPENPOSE__THREAD__THREAD_MANAGER_HPP +#ifndef OPENPOSE_THREAD_THREAD_MANAGER_HPP +#define OPENPOSE_THREAD_THREAD_MANAGER_HPP #include #include // std::unique_ptr<> & std::shared_ptr<> @@ -505,4 +505,4 @@ namespace op COMPILE_TEMPLATE_DATUM(ThreadManager); } -#endif // OPENPOSE__THREAD__THREAD_MANAGER_HPP +#endif // OPENPOSE_THREAD_THREAD_MANAGER_HPP diff --git a/include/openpose/thread/wIdGenerator.hpp b/include/openpose/thread/wIdGenerator.hpp index 9a26d5b0..d5cf2817 100644 --- a/include/openpose/thread/wIdGenerator.hpp +++ b/include/openpose/thread/wIdGenerator.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__THREAD__W_ID_GENERATOR_HPP -#define OPENPOSE__THREAD__W_ID_GENERATOR_HPP +#ifndef OPENPOSE_THREAD_W_ID_GENERATOR_HPP +#define OPENPOSE_THREAD_W_ID_GENERATOR_HPP #include // std::priority_queue #include "worker.hpp" @@ -69,4 +69,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WIdGenerator); } -#endif // OPENPOSE__THREAD__W_ID_GENERATOR_HPP +#endif // OPENPOSE_THREAD_W_ID_GENERATOR_HPP diff --git a/include/openpose/thread/wQueueOrderer.hpp b/include/openpose/thread/wQueueOrderer.hpp index 84c0b761..a3c55951 100644 --- a/include/openpose/thread/wQueueOrderer.hpp +++ b/include/openpose/thread/wQueueOrderer.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__THREAD__W_QUEUE_ORDERER_HPP -#define OPENPOSE__THREAD__W_QUEUE_ORDERER_HPP +#ifndef OPENPOSE_THREAD_W_QUEUE_ORDERER_HPP +#define OPENPOSE_THREAD_W_QUEUE_ORDERER_HPP #include // std::priority_queue #include @@ -141,4 +141,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WQueueOrderer); } -#endif // OPENPOSE__THREAD__W_QUEUE_ORDERER_HPP +#endif // OPENPOSE_THREAD_W_QUEUE_ORDERER_HPP diff --git a/include/openpose/thread/worker.hpp b/include/openpose/thread/worker.hpp index 460eb53e..e681db38 100644 --- a/include/openpose/thread/worker.hpp +++ b/include/openpose/thread/worker.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__THREAD__WORKER_HPP -#define OPENPOSE__THREAD__WORKER_HPP +#ifndef OPENPOSE_THREAD_WORKER_HPP +#define OPENPOSE_THREAD_WORKER_HPP #include @@ -73,4 +73,4 @@ namespace op COMPILE_TEMPLATE_DATUM(Worker); } -#endif // OPENPOSE__THREAD__WORKER_HPP +#endif // OPENPOSE_THREAD_WORKER_HPP diff --git a/include/openpose/thread/workerConsumer.hpp b/include/openpose/thread/workerConsumer.hpp index 3f3aa783..66b146b1 100644 --- a/include/openpose/thread/workerConsumer.hpp +++ b/include/openpose/thread/workerConsumer.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__THREAD__WORKER_CONSUMER_HPP -#define OPENPOSE__THREAD__WORKER_CONSUMER_HPP +#ifndef OPENPOSE_THREAD_WORKER_CONSUMER_HPP +#define OPENPOSE_THREAD_WORKER_CONSUMER_HPP #include "worker.hpp" @@ -37,4 +37,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WorkerConsumer); } -#endif // OPENPOSE__THREAD__WORKER_CONSUMER_HPP +#endif // OPENPOSE_THREAD_WORKER_CONSUMER_HPP diff --git a/include/openpose/thread/workerProducer.hpp b/include/openpose/thread/workerProducer.hpp index 36118307..da64acf2 100644 --- a/include/openpose/thread/workerProducer.hpp +++ b/include/openpose/thread/workerProducer.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__THREAD__WORKER_PRODUCER_HPP -#define OPENPOSE__THREAD__WORKER_PRODUCER_HPP +#ifndef OPENPOSE_THREAD_WORKER_PRODUCER_HPP +#define OPENPOSE_THREAD_WORKER_PRODUCER_HPP #include "worker.hpp" @@ -37,4 +37,4 @@ namespace op COMPILE_TEMPLATE_DATUM(WorkerProducer); } -#endif // OPENPOSE__THREAD__WORKER_PRODUCER_HPP +#endif // OPENPOSE_THREAD_WORKER_PRODUCER_HPP diff --git a/include/openpose/utilities/check.hpp b/include/openpose/utilities/check.hpp index b75ed00a..fef6ba62 100644 --- a/include/openpose/utilities/check.hpp +++ b/include/openpose/utilities/check.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__UTILITIES__CHECK_HPP -#define OPENPOSE__UTILITIES__CHECK_HPP +#ifndef OPENPOSE_UTILITIES_CHECK_HPP +#define OPENPOSE_UTILITIES_CHECK_HPP #include #include "errorAndLog.hpp" @@ -57,4 +57,4 @@ namespace op } } -#endif // OPENPOSE__UTILITIES__CHECK_HPP +#endif // OPENPOSE_UTILITIES_CHECK_HPP diff --git a/include/openpose/utilities/cuda.hpp b/include/openpose/utilities/cuda.hpp index 6cdf79ce..6c2d880a 100644 --- a/include/openpose/utilities/cuda.hpp +++ b/include/openpose/utilities/cuda.hpp @@ -1,11 +1,11 @@ -#ifndef OPENPOSE__UTILITIES_CUDA_HPP -#define OPENPOSE__UTILITIES_CUDA_HPP +#ifndef OPENPOSE_UTILITIES_CUDA_HPP +#define OPENPOSE_UTILITIES_CUDA_HPP #include #include // std::pair #include #include -#include +#include namespace op { @@ -13,14 +13,16 @@ namespace op void cudaCheck(const int line = -1, const std::string& function = "", const std::string& file = ""); + int getGpuNumber(); + inline unsigned int getNumberCudaBlocks(const unsigned int totalRequired, const unsigned int numberCudaThreads = CUDA_NUM_THREADS) { return (totalRequired + numberCudaThreads - 1) / numberCudaThreads; } - dim3 getNumberCudaBlocks(const cv::Size& frameSize, const dim3 numberCudaThreads = dim3{ CUDA_NUM_THREADS, CUDA_NUM_THREADS, 1 }); + dim3 getNumberCudaBlocks(const Point& frameSize, const dim3 numberCudaThreads = dim3{ CUDA_NUM_THREADS, CUDA_NUM_THREADS, 1 }); - std::pair getNumberCudaThreadsAndBlocks(const cv::Size& frameSize); + std::pair getNumberCudaThreadsAndBlocks(const Point& frameSize); } -#endif // OPENPOSE__UTILITIES_CUDA_HPP +#endif // OPENPOSE_UTILITIES_CUDA_HPP diff --git a/include/openpose/utilities/cuda.hu b/include/openpose/utilities/cuda.hu index 146e5fdc..ae1630cc 100644 --- a/include/openpose/utilities/cuda.hu +++ b/include/openpose/utilities/cuda.hu @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__UTILITIES_CUDA_HU -#define OPENPOSE__UTILITIES_CUDA_HU +#ifndef OPENPOSE_UTILITIES_CUDA_HU +#define OPENPOSE_UTILITIES_CUDA_HU namespace op { @@ -143,4 +143,4 @@ namespace op } } -#endif // OPENPOSE__UTILITIES_CUDA_HU +#endif // OPENPOSE_UTILITIES_CUDA_HU diff --git a/include/openpose/utilities/enumClasses.hpp b/include/openpose/utilities/enumClasses.hpp index d2c93d0d..15a5c823 100644 --- a/include/openpose/utilities/enumClasses.hpp +++ b/include/openpose/utilities/enumClasses.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__UTILITIES__ENUM_CLASSES_HPP -#define OPENPOSE__UTILITIES__ENUM_CLASSES_HPP +#ifndef OPENPOSE_UTILITIES_ENUM_CLASSES_HPP +#define OPENPOSE_UTILITIES_ENUM_CLASSES_HPP namespace op { @@ -29,4 +29,4 @@ namespace op }; } -#endif // OPENPOSE__UTILITIES__ENUM_CLASSES_HPP +#endif // OPENPOSE_UTILITIES_ENUM_CLASSES_HPP diff --git a/include/openpose/utilities/errorAndLog.hpp b/include/openpose/utilities/errorAndLog.hpp index 8e1e9434..d8a7dd5f 100644 --- a/include/openpose/utilities/errorAndLog.hpp +++ b/include/openpose/utilities/errorAndLog.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__UTILITIES__ERROR_AND_LOG_HPP -#define OPENPOSE__UTILITIES__ERROR_AND_LOG_HPP +#ifndef OPENPOSE_UTILITIES_ERROR_AND_LOG_HPP +#define OPENPOSE_UTILITIES_ERROR_AND_LOG_HPP #include #include @@ -80,4 +80,4 @@ namespace op }; } -#endif // OPENPOSE__UTILITIES__ERROR_AND_LOG_HPP +#endif // OPENPOSE_UTILITIES_ERROR_AND_LOG_HPP diff --git a/include/openpose/utilities/fastMath.hpp b/include/openpose/utilities/fastMath.hpp index b12611cf..b479f81e 100644 --- a/include/openpose/utilities/fastMath.hpp +++ b/include/openpose/utilities/fastMath.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__UTILITIES__MATH_HPP -#define OPENPOSE__UTILITIES__MATH_HPP +#ifndef OPENPOSE_UTILITIES_MATH_HPP +#define OPENPOSE_UTILITIES_MATH_HPP namespace op { @@ -83,4 +83,4 @@ namespace op } } -#endif // OPENPOSE__UTILITIES__MATH_HPP +#endif // OPENPOSE_UTILITIES_MATH_HPP diff --git a/include/openpose/utilities/fileSystem.hpp b/include/openpose/utilities/fileSystem.hpp index e445cf52..de5a0b04 100644 --- a/include/openpose/utilities/fileSystem.hpp +++ b/include/openpose/utilities/fileSystem.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__UTILITIES__FILE_SYSTEM_HPP -#define OPENPOSE__UTILITIES__FILE_SYSTEM_HPP +#ifndef OPENPOSE_UTILITIES_FILE_SYSTEM_HPP +#define OPENPOSE_UTILITIES_FILE_SYSTEM_HPP #include @@ -59,4 +59,4 @@ namespace op std::vector getFilesOnDirectory(const std::string& directoryPath, const std::string& extension); } -#endif // OPENPOSE__UTILITIES__FILE_SYSTEM_HPP +#endif // OPENPOSE_UTILITIES_FILE_SYSTEM_HPP diff --git a/include/openpose/utilities/headers.hpp b/include/openpose/utilities/headers.hpp index 486e7885..c0acf06a 100644 --- a/include/openpose/utilities/headers.hpp +++ b/include/openpose/utilities/headers.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__UTILITIES__HEADERS_HPP -#define OPENPOSE__UTILITIES__HEADERS_HPP +#ifndef OPENPOSE_UTILITIES_HEADERS_HPP +#define OPENPOSE_UTILITIES_HEADERS_HPP // utilities module #include "check.hpp" @@ -14,4 +14,4 @@ #include "profiler.hpp" #include "string.hpp" -#endif // OPENPOSE__UTILITIES__HEADERS_HPP +#endif // OPENPOSE_UTILITIES_HEADERS_HPP diff --git a/include/openpose/utilities/macros.hpp b/include/openpose/utilities/macros.hpp index f6ebf4ca..59d147b0 100644 --- a/include/openpose/utilities/macros.hpp +++ b/include/openpose/utilities/macros.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__UTILITIES__MACROS_HPP -#define OPENPOSE__UTILITIES__MACROS_HPP +#ifndef OPENPOSE_UTILITIES_MACROS_HPP +#define OPENPOSE_UTILITIES_MACROS_HPP #include // std::shared_ptr #include @@ -32,4 +32,4 @@ template class className; \ template class className -#endif // OPENPOSE__UTILITIES__MACROS_HPP +#endif // OPENPOSE_UTILITIES_MACROS_HPP diff --git a/include/openpose/utilities/openCv.hpp b/include/openpose/utilities/openCv.hpp index 71c22ed3..b9c87927 100644 --- a/include/openpose/utilities/openCv.hpp +++ b/include/openpose/utilities/openCv.hpp @@ -1,23 +1,24 @@ -#ifndef OPENPOSE__UTILITIES__OPEN_CV_HPP -#define OPENPOSE__UTILITIES__OPEN_CV_HPP +#ifndef OPENPOSE_UTILITIES_OPEN_CV_HPP +#define OPENPOSE_UTILITIES_OPEN_CV_HPP -#include // cv::Mat, cv::Point +#include // cv::Mat #include // cv::warpAffine, cv::BORDER_CONSTANT +#include // Point namespace op { - void putTextOnCvMat(cv::Mat& cvMat, const std::string& textToDisplay, const cv::Point& position, const cv::Scalar& color, const bool normalizeWidth); + void putTextOnCvMat(cv::Mat& cvMat, const std::string& textToDisplay, const Point& position, const cv::Scalar& color, const bool normalizeWidth); - void floatPtrToUCharCvMat(cv::Mat& cvMat, const float* const floatImage, const cv::Size& resolutionSize, const int resolutionChannels); + void floatPtrToUCharCvMat(cv::Mat& cvMat, const float* const floatImage, const Point& resolutionSize, const int resolutionChannels); void unrollArrayToUCharCvMat(cv::Mat& cvMatResult, const Array& array); void uCharCvMatToFloatPtr(float* floatImage, const cv::Mat& cvImage, const bool normalize); - double resizeGetScaleFactor(const cv::Size& initialSize, const cv::Size& targetSize); + double resizeGetScaleFactor(const Point& initialSize, const Point& targetSize); - cv::Mat resizeFixedAspectRatio(const cv::Mat& cvMat, const double scaleFactor, const cv::Size& targetSize, const int borderMode = cv::BORDER_CONSTANT, + cv::Mat resizeFixedAspectRatio(const cv::Mat& cvMat, const double scaleFactor, const Point& targetSize, const int borderMode = cv::BORDER_CONSTANT, const cv::Scalar& borderValue = cv::Scalar{0,0,0}); } -#endif // OPENPOSE__UTILITIES__OPEN_CV_HPP +#endif // OPENPOSE_UTILITIES_OPEN_CV_HPP diff --git a/include/openpose/utilities/pointerContainer.hpp b/include/openpose/utilities/pointerContainer.hpp index 6f39e965..0505f5fa 100644 --- a/include/openpose/utilities/pointerContainer.hpp +++ b/include/openpose/utilities/pointerContainer.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__UTILITIES__POINTER_CONTAINER_HPP -#define OPENPOSE__UTILITIES__POINTER_CONTAINER_HPP +#ifndef OPENPOSE_UTILITIES_POINTER_CONTAINER_HPP +#define OPENPOSE_UTILITIES_POINTER_CONTAINER_HPP namespace op { @@ -40,4 +40,4 @@ namespace op }; } -#endif // OPENPOSE__UTILITIES__POINTER_CONTAINER_HPP +#endif // OPENPOSE_UTILITIES_POINTER_CONTAINER_HPP diff --git a/include/openpose/utilities/profiler.hpp b/include/openpose/utilities/profiler.hpp index 0d44a941..e00da75e 100644 --- a/include/openpose/utilities/profiler.hpp +++ b/include/openpose/utilities/profiler.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__UTILITIES__PROFILER_HPP -#define OPENPOSE__UTILITIES__PROFILER_HPP +#ifndef OPENPOSE_UTILITIES_PROFILER_HPP +#define OPENPOSE_UTILITIES_PROFILER_HPP #include @@ -34,4 +34,4 @@ namespace op }; } -#endif // OPENPOSE__UTILITIES__PROFILER_HPP +#endif // OPENPOSE_UTILITIES_PROFILER_HPP diff --git a/include/openpose/utilities/render.hu b/include/openpose/utilities/render.hu index caec6eba..1d9af8a1 100644 --- a/include/openpose/utilities/render.hu +++ b/include/openpose/utilities/render.hu @@ -1,11 +1,11 @@ -#ifndef OPENPOSE__UTILITIES_RENDER_HU -#define OPENPOSE__UTILITIES_RENDER_HU +#ifndef OPENPOSE_UTILITIES_RENDER_HU +#define OPENPOSE_UTILITIES_RENDER_HU namespace op { - inline __device__ void renderKeyPoints(float* targetPtr, float2* sharedMaxs, float2* sharedMins, float* sharedScaleF, + inline __device__ void renderKeypoints(float* targetPtr, float2* sharedMaxs, float2* sharedMins, float* sharedScaleF, const int globalIdx, const int x, const int y, const int targetWidth, const int targetHeight, - const float* const keypointsPtr, const unsigned char* const partPairsPtr, + const float* const keypointsPtr, const unsigned int* const partPairsPtr, const int numberPeople, const int numberParts, const int numberPartPairs, const float* const rgbColorsPtr, const int numberColors, const float radius, const float stickwidth, const float threshold, const float alphaColorToAdd, @@ -36,14 +36,17 @@ namespace op sharedMaxs[globalIdx].y = y; } } - const auto averageX = sharedMaxs[globalIdx].x - sharedMins[globalIdx].x; - const auto averageY = sharedMaxs[globalIdx].y - sharedMins[globalIdx].y; - sharedScaleF[globalIdx] = fastTruncate((averageX + averageY) / 400.f, 0.33f, 1.f); // (averageX + averageY) / 2.f / 400.f - const auto constantToAdd = 50.f; - sharedMaxs[globalIdx].x += constantToAdd; - sharedMaxs[globalIdx].y += constantToAdd; - sharedMins[globalIdx].x -= constantToAdd; - sharedMins[globalIdx].y -= constantToAdd; + if (sharedMaxs[globalIdx].x != 0.f && sharedMaxs[globalIdx].y != 0.f) + { + const auto averageX = sharedMaxs[globalIdx].x - sharedMins[globalIdx].x; + const auto averageY = sharedMaxs[globalIdx].y - sharedMins[globalIdx].y; + sharedScaleF[globalIdx] = fastTruncate((averageX + averageY) / 400.f, 0.33f, 1.f); // (averageX + averageY) / 2.f / 400.f + const auto constantToAdd = 50.f; + sharedMaxs[globalIdx].x += constantToAdd; + sharedMaxs[globalIdx].y += constantToAdd; + sharedMins[globalIdx].x -= constantToAdd; + sharedMins[globalIdx].y -= constantToAdd; + } } __syncthreads(); @@ -64,9 +67,12 @@ namespace op for (auto person = 0; person < numberPeople; person++) { + // Make sure person x,y in the limits + // Make sure person is not empty. Assume all joints are below threshold. Then + // maxs = 0 and mins = width/height. So if statement would be false if (x <= sharedMaxs[person].x && x >= sharedMins[person].x && y <= sharedMaxs[person].y && y >= sharedMins[person].y) { - // Hand part connections + // Part pair connections for (auto partPair = 0; partPair < numberPartPairs; partPair++) { const auto bSqrt = sharedScaleF[person] * sharedScaleF[person] * stickwidth * stickwidth; @@ -101,8 +107,8 @@ namespace op } } - // Hand part circles - for (unsigned char i = 0; i < numberParts; i++) + // Part circles + for (auto i = 0u; i < numberParts; i++) { const auto index = 3 * (person*numberParts + i); const auto localX = keypointsPtr[index]; @@ -116,8 +122,8 @@ namespace op if (googlyEye1 == i || googlyEye2 == i) { const auto ratio = 2.5f * radius; - const auto minr2 = sharedScaleF[person]*sharedScaleF[person] * (ratio - 2) * (ratio - 2); - const auto maxr2 = sharedScaleF[person]*sharedScaleF[person] * ratio * ratio; + const auto minr2 = sharedScaleF[person] * sharedScaleF[person] * (ratio - 2) * (ratio - 2); + const auto maxr2 = sharedScaleF[person] * sharedScaleF[person] * ratio * ratio; if (dist2 <= maxr2) { float colorToAdd [3] = {0., 0., 0.}; @@ -135,11 +141,11 @@ namespace op addColorWeighted(r, g, b, colorToAdd, alphaColorToAdd); } } - // Other limbs + // Other parts else { const auto minr2 = 0.f; - const auto maxr2 = sharedScaleF[person]*sharedScaleF[person]*radius * radius; + const auto maxr2 = sharedScaleF[person] * sharedScaleF[person] * radius * radius; if (minr2 <= dist2 && dist2 <= maxr2) addColorWeighted(r, g, b, &rgbColorsPtr[(i%numberColors)*3], alphaColorToAdd); } @@ -151,4 +157,4 @@ namespace op } } -#endif // OPENPOSE__UTILITIES_RENDER_HU +#endif // OPENPOSE_UTILITIES_RENDER_HU diff --git a/include/openpose/utilities/string.hpp b/include/openpose/utilities/string.hpp index aa3881d5..2fb29e0a 100644 --- a/include/openpose/utilities/string.hpp +++ b/include/openpose/utilities/string.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__UTILITIES__STRING_HPP -#define OPENPOSE__UTILITIES__STRING_HPP +#ifndef OPENPOSE_UTILITIES_STRING_HPP +#define OPENPOSE_UTILITIES_STRING_HPP #include @@ -16,4 +16,4 @@ namespace op std::string toFixedLengthString(const T number, const unsigned long long stringLength = 0); } -#endif // OPENPOSE__UTILITIES__STRING_HPP +#endif // OPENPOSE_UTILITIES_STRING_HPP diff --git a/include/openpose/wrapper/headers.hpp b/include/openpose/wrapper/headers.hpp index 80ff7a56..3de60b43 100644 --- a/include/openpose/wrapper/headers.hpp +++ b/include/openpose/wrapper/headers.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__WRAPPER__HEADERS_HPP -#define OPENPOSE__WRAPPER__HEADERS_HPP +#ifndef OPENPOSE_WRAPPER_HEADERS_HPP +#define OPENPOSE_WRAPPER_HEADERS_HPP // wrapper module #include "wrapper.hpp" @@ -9,4 +9,4 @@ #include "wrapperStructOutput.hpp" #include "wrapperStructPose.hpp" -#endif // OPENPOSE__WRAPPER__HEADERS_HPP +#endif // OPENPOSE_WRAPPER_HEADERS_HPP diff --git a/include/openpose/wrapper/wrapper.hpp b/include/openpose/wrapper/wrapper.hpp index 6ce512d9..18af1cff 100644 --- a/include/openpose/wrapper/wrapper.hpp +++ b/include/openpose/wrapper/wrapper.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__WRAPPER__WRAPPER_HPP -#define OPENPOSE__WRAPPER__WRAPPER_HPP +#ifndef OPENPOSE_WRAPPER_WRAPPER_HPP +#define OPENPOSE_WRAPPER_WRAPPER_HPP #include #include "wrapperStructFace.hpp" @@ -94,7 +94,7 @@ namespace op // Similar to the previos configure, but it includes hand extraction and rendering void configure(const WrapperStructPose& wrapperStructPose, // Face (use the default WrapperStructFace{} to disable any face detector) - const experimental::WrapperStructFace& wrapperStructFace, + const WrapperStructFace& wrapperStructFace, // Producer (set producerSharedPtr = nullptr or use the default WrapperStructInput{} to disable any input) const WrapperStructInput& wrapperStructInput, // Consumer (keep default values to disable any output) @@ -104,7 +104,7 @@ namespace op // Similar to the previos configure, but it includes hand extraction and rendering void configure(const WrapperStructPose& wrapperStructPose = WrapperStructPose{}, // Face (use the default WrapperStructFace{} to disable any face detector) - const experimental::WrapperStructFace& wrapperStructFace = experimental::WrapperStructFace{}, + const WrapperStructFace& wrapperStructFace = WrapperStructFace{}, // Hand (use the default WrapperStructHand{} to disable any hand detector) const experimental::WrapperStructHand& wrapperHandStruct = experimental::WrapperStructHand{}, // Producer (set producerSharedPtr = nullptr or use the default WrapperStructInput{} to disable any input) @@ -201,7 +201,6 @@ namespace op const ThreadManagerMode mThreadManagerMode; const std::shared_ptr, std::atomic>> spVideoSeek; ThreadManager> mThreadManager; - int mGpuNumber; bool mUserInputWsOnNewThread; bool mUserPostProcessingWsOnNewThread; bool mUserOutputWsOnNewThread; @@ -265,10 +264,12 @@ namespace op // Implementation #include #include +#include #include #include #include #include +#include #include #include namespace op @@ -376,7 +377,7 @@ namespace op { try { - configure(wrapperStructPose, experimental::WrapperStructFace{}, experimental::WrapperStructHand{}, wrapperStructInput, wrapperStructOutput); + configure(wrapperStructPose, WrapperStructFace{}, experimental::WrapperStructHand{}, wrapperStructInput, wrapperStructOutput); } catch (const std::exception& e) { @@ -385,7 +386,7 @@ namespace op } template - void Wrapper::configure(const WrapperStructPose& wrapperStructPose, const experimental::WrapperStructFace& wrapperStructFace, + void Wrapper::configure(const WrapperStructPose& wrapperStructPose, const WrapperStructFace& wrapperStructFace, const WrapperStructInput& wrapperStructInput, const WrapperStructOutput& wrapperStructOutput) { try @@ -404,7 +405,7 @@ namespace op { try { - configure(wrapperStructPose, experimental::WrapperStructFace{}, wrapperHandStruct, wrapperStructInput, wrapperStructOutput); + configure(wrapperStructPose, WrapperStructFace{}, wrapperHandStruct, wrapperStructInput, wrapperStructOutput); } catch (const std::exception& e) { @@ -413,7 +414,7 @@ namespace op } template - void Wrapper::configure(const WrapperStructPose& wrapperStructPose, const experimental::WrapperStructFace& wrapperStructFace, + void Wrapper::configure(const WrapperStructPose& wrapperStructPose, const WrapperStructFace& wrapperStructFace, const experimental::WrapperStructHand& wrapperHandStruct, const WrapperStructInput& wrapperStructInput, const WrapperStructOutput& wrapperStructOutput) { @@ -424,13 +425,17 @@ namespace op // Shortcut typedef std::shared_ptr TDatumsPtr; - // Check no contradictory flags enabled - if (wrapperStructPose.alphaPose < 0. || wrapperStructPose.alphaPose > 1. || wrapperStructPose.alphaHeatMap < 0. - || wrapperStructPose.alphaHeatMap > 1.) + // Required parameters + const auto renderOutput = wrapperStructPose.renderOutput || wrapperStructFace.renderOutput; + const auto renderFace = wrapperStructFace.enable && wrapperStructFace.renderOutput; + + // Check no wrong/contradictory flags enabled + if (wrapperStructPose.alphaKeypoint < 0. || wrapperStructPose.alphaKeypoint > 1. + || wrapperStructFace.alphaHeatMap < 0. || wrapperStructFace.alphaHeatMap > 1.) error("Alpha value for blending must be in the range [0,1].", __LINE__, __FUNCTION__, __FILE__); if (wrapperStructPose.scaleGap <= 0.f && wrapperStructPose.scalesNumber > 1) error("The scale gap must be greater than 0 (it has no effect if the number of scales is 1).", __LINE__, __FUNCTION__, __FILE__); - if (!wrapperStructPose.renderOutput && (!wrapperStructOutput.writeImages.empty() || !wrapperStructOutput.writeVideo.empty())) + if (!renderOutput && (!wrapperStructOutput.writeImages.empty() || !wrapperStructOutput.writeVideo.empty())) { const auto message = "In order to save the rendered frames (`write_images` or `write_video`), you must set `render_output` to true."; error(message, __LINE__, __FUNCTION__, __FILE__); @@ -441,9 +446,9 @@ namespace op " flags or fill the wrapperStructPose.heatMapTypes."; error(message, __LINE__, __FUNCTION__, __FILE__); } - if (!wrapperStructOutput.writeHeatMaps.empty() && wrapperStructPose.heatMapScaleMode != ScaleMode::UnsignedChar) + if (!wrapperStructOutput.writeHeatMaps.empty() && wrapperStructPose.heatMapScale != ScaleMode::UnsignedChar) { - const auto message = "In order to save the heatmaps, you must set wrapperStructPose.heatMapScaleMode to ScaleMode::UnsignedChar," + const auto message = "In order to save the heatmaps, you must set wrapperStructPose.heatMapScale to ScaleMode::UnsignedChar," " i.e. range [0, 255]."; error(message, __LINE__, __FUNCTION__, __FILE__); } @@ -452,7 +457,7 @@ namespace op const std::string additionalMessage = " You could also set mThreadManagerMode = mThreadManagerMode::Asynchronous(Out) and/or add your own" " output worker class before calling this function."; const auto savingSomething = (!wrapperStructOutput.writeImages.empty() || !wrapperStructOutput.writeVideo.empty() - || !wrapperStructOutput.writePose.empty() || !wrapperStructOutput.writePoseJson.empty() + || !wrapperStructOutput.writeKeypoint.empty() || !wrapperStructOutput.writeKeypointJson.empty() || !wrapperStructOutput.writeCocoJson.empty() || !wrapperStructOutput.writeHeatMaps.empty()); if (!wrapperStructOutput.displayGui && !savingSomething) { @@ -461,9 +466,9 @@ namespace op error(message, __LINE__, __FUNCTION__, __FILE__); } - if ((wrapperStructOutput.displayGui && wrapperStructOutput.guiVerbose) && !wrapperStructPose.renderOutput) + if ((wrapperStructOutput.displayGui && wrapperStructOutput.guiVerbose) && !renderOutput) { - const auto message = "No render is enabled (`no_render_output`), so you should also remove the display (set `no_display`" + const auto message = "No render is enabled (e.g. `no_render_pose`), so you should also remove the display (set `no_display`" " or `no_gui_verbose`)." + additionalMessage; error(message, __LINE__, __FUNCTION__, __FILE__); } @@ -481,17 +486,32 @@ namespace op } } if (!wrapperStructOutput.writeVideo.empty() && wrapperStructInput.producerSharedPtr == nullptr) - error("Writting video is only available if the OpenPose producer is used (i.e. wrapperStructInput.producerSharedPtr cannot be a nullptr)."); + error("Writting video is only available if the OpenPose producer is used (i.e. wrapperStructInput.producerSharedPtr cannot be a nullptr).", + __LINE__, __FUNCTION__, __FILE__); + + // Get number GPUs + auto gpuNumber = wrapperStructPose.gpuNumber; + auto gpuNumberStart = wrapperStructPose.gpuNumberStart; + // If number GPU < 0 --> set it to all the available GPUs + if (gpuNumber < 0) + { + // Get total number GPUs + gpuNumber = getGpuNumber(); + // Reset initial GPU to 0 (we want them all) + gpuNumberStart = 0; + // Logging message + log("Auto-detecting GPUs... Detected " + std::to_string(gpuNumber) + " GPU(s), using them all.", Priority::Max); + } // Proper format const auto writeImagesCleaned = formatAsDirectory(wrapperStructOutput.writeImages); - const auto writePoseCleaned = formatAsDirectory(wrapperStructOutput.writePose); - const auto writePoseJsonCleaned = formatAsDirectory(wrapperStructOutput.writePoseJson); + const auto writeKeypointCleaned = formatAsDirectory(wrapperStructOutput.writeKeypoint); + const auto writeKeypointJsonCleaned = formatAsDirectory(wrapperStructOutput.writeKeypointJson); const auto writeHeatMapsCleaned = formatAsDirectory(wrapperStructOutput.writeHeatMaps); // Common parameters auto finalOutputSize = wrapperStructPose.outputSize; - cv::Size producerSize{-1,-1}; + Point producerSize{-1,-1}; if (wrapperStructInput.producerSharedPtr != nullptr) { // 1. Set producer properties @@ -501,9 +521,9 @@ namespace op wrapperStructInput.producerSharedPtr->set(ProducerProperty::Rotation, wrapperStructInput.frameRotate); wrapperStructInput.producerSharedPtr->set(ProducerProperty::AutoRepeat, wrapperStructInput.framesRepeat); // 2. Set finalOutputSize - producerSize = cv::Size{(int)wrapperStructInput.producerSharedPtr->get(CV_CAP_PROP_FRAME_WIDTH), + producerSize = Point{(int)wrapperStructInput.producerSharedPtr->get(CV_CAP_PROP_FRAME_WIDTH), (int)wrapperStructInput.producerSharedPtr->get(CV_CAP_PROP_FRAME_HEIGHT)}; - if (wrapperStructPose.outputSize.width == -1 || wrapperStructPose.outputSize.height == -1) + if (wrapperStructPose.outputSize.x == -1 || wrapperStructPose.outputSize.y == -1) { if (producerSize.area() > 0) finalOutputSize = producerSize; @@ -514,15 +534,12 @@ namespace op } } } - else if (finalOutputSize.width == -1 || finalOutputSize.height == -1) + else if (finalOutputSize.x == -1 || finalOutputSize.y == -1) { const auto message = "Output resolution cannot be (-1 x -1) unless wrapperStructInput.producerSharedPtr is also set."; error(message, __LINE__, __FUNCTION__, __FILE__); } - // Update global parameter - mGpuNumber = wrapperStructPose.gpuNumber; - // Producer if (wrapperStructInput.producerSharedPtr != nullptr) { @@ -535,24 +552,29 @@ namespace op wDatumProducer = nullptr; // Pose estimators - const cv::Size& netOutputSize = wrapperStructPose.netInputSize; + const Point& netOutputSize = wrapperStructPose.netInputSize; std::vector> poseExtractors; - for (auto gpuId = 0; gpuId < wrapperStructPose.gpuNumber; gpuId++) + for (auto gpuId = 0; gpuId < gpuNumber; gpuId++) poseExtractors.emplace_back(std::make_shared( wrapperStructPose.netInputSize, netOutputSize, finalOutputSize, wrapperStructPose.scalesNumber, wrapperStructPose.scaleGap, wrapperStructPose.poseModel, wrapperStructPose.modelFolder, - gpuId + wrapperStructPose.gpuNumberStart, wrapperStructPose.heatMapTypes, wrapperStructPose.heatMapScaleMode + gpuId + gpuNumberStart, wrapperStructPose.heatMapTypes, wrapperStructPose.heatMapScale )); + // Pose renderers std::vector> poseRenderers; - if (wrapperStructPose.renderOutput) + if (wrapperStructPose.renderOutput || renderOutput) { + // If !wrapperStructPose.renderOutput but renderOutput, then we create an alpha = 0 pose renderer + // in order to keep the removing background option + const auto alphaKeypoint = (wrapperStructPose.renderOutput ? wrapperStructPose.alphaKeypoint : 0.f); + const auto alphaHeatMap = (wrapperStructPose.renderOutput ? wrapperStructPose.alphaHeatMap : 0.f); for (auto gpuId = 0; gpuId < poseExtractors.size(); gpuId++) { poseRenderers.emplace_back(std::make_shared( netOutputSize, finalOutputSize, wrapperStructPose.poseModel, poseExtractors[gpuId], - wrapperStructPose.blendOriginalFrame, wrapperStructPose.alphaPose, - wrapperStructPose.alphaHeatMap, wrapperStructPose.defaultPartToRender + wrapperStructPose.blendOriginalFrame, alphaKeypoint, + alphaHeatMap, wrapperStructPose.defaultPartToRender )); } } @@ -563,7 +585,7 @@ namespace op wrapperStructPose.netInputSize, wrapperStructPose.scalesNumber, wrapperStructPose.scaleGap ); spWCvMatToOpInput = std::make_shared>(cvMatToOpInput); - const auto cvMatToOpOutput = std::make_shared(finalOutputSize, wrapperStructPose.renderOutput); + const auto cvMatToOpOutput = std::make_shared(finalOutputSize, renderOutput); spWCvMatToOpOutput = std::make_shared>(cvMatToOpOutput); // Pose extractor(s) @@ -573,14 +595,19 @@ namespace op spWPoses.at(i) = {std::make_shared>(poseExtractors.at(i))}; // Face extractor(s) - if (wrapperStructFace.extractAndRenderFace) + if (wrapperStructFace.enable) { for (auto gpuId = 0; gpuId < spWPoses.size(); gpuId++) { - const auto faceExtractor = std::make_shared( - wrapperStructPose.modelFolder, gpuId + wrapperStructPose.gpuNumberStart, wrapperStructPose.poseModel + // Face detector + const auto faceDetector = std::make_shared(wrapperStructPose.poseModel); + spWPoses.at(gpuId).emplace_back(std::make_shared>(faceDetector)); + // Face keypoint extractor + const auto netOutputSize = wrapperStructFace.netInputSize; + const auto faceExtractor = std::make_shared( + wrapperStructFace.netInputSize, netOutputSize, wrapperStructPose.modelFolder, gpuId + gpuNumberStart ); - spWPoses.at(gpuId).emplace_back(std::make_shared>(faceExtractor)); + spWPoses.at(gpuId).emplace_back(std::make_shared>(faceExtractor)); } } @@ -590,7 +617,7 @@ namespace op for (auto gpuId = 0; gpuId < spWPoses.size(); gpuId++) { const auto handExtractor = std::make_shared( - wrapperStructPose.modelFolder, gpuId + wrapperStructPose.gpuNumberStart, wrapperStructPose.poseModel + wrapperStructPose.modelFolder, gpuId + gpuNumberStart, wrapperStructPose.poseModel ); spWPoses.at(gpuId).emplace_back(std::make_shared>(handExtractor)); } @@ -611,8 +638,8 @@ namespace op // Performance boost -> share spGpuMemoryPtr for all renderers if (!poseRenderers.empty()) { - const bool isLastRenderer = (!wrapperStructFace.extractAndRenderFace); - handRenderer->setGpuMemoryAndSetIfLast(poseRenderers.at(i)->getGpuMemoryAndSetAsFirst(), isLastRenderer); + const bool isLastRenderer = (!renderFace); + handRenderer->setSharedParametersAndIfLast(poseRenderers.at(i)->getSharedParameters(), isLastRenderer); } // Add worker spWPoses.at(i).emplace_back(std::make_shared>(handRenderer)); @@ -620,20 +647,20 @@ namespace op } // Face renderer(s) - if (wrapperStructFace.extractAndRenderFace) + if (renderFace) { for (auto i = 0; i < spWPoses.size(); i++) { // Construct face renderer - const auto faceRenderer = std::make_shared(finalOutputSize); + const auto faceRenderer = std::make_shared(finalOutputSize, wrapperStructFace.alphaKeypoint, wrapperStructFace.alphaHeatMap); // Performance boost -> share spGpuMemoryPtr for all renderers if (!poseRenderers.empty()) { const bool isLastRenderer = true; - faceRenderer->setGpuMemoryAndSetIfLast(poseRenderers.at(i)->getGpuMemoryAndSetAsFirst(), isLastRenderer); + faceRenderer->setSharedParametersAndIfLast(poseRenderers.at(i)->getSharedParameters(), isLastRenderer); } // Add worker - spWPoses.at(i).emplace_back(std::make_shared>(faceRenderer)); + spWPoses.at(i).emplace_back(std::make_shared>(faceRenderer)); } } @@ -643,39 +670,47 @@ namespace op if (spWPoses.size() > 1) mPostProcessingWs.emplace_back(std::make_shared>()); // Frames processor (OpenPose format -> cv::Mat format) - if (wrapperStructPose.renderOutput) + if (renderOutput) { const auto opOutputToCvMat = std::make_shared(finalOutputSize); mPostProcessingWs.emplace_back(std::make_shared>(opOutputToCvMat)); } // Re-scale pose if desired - if (wrapperStructPose.poseScaleMode != ScaleMode::OutputResolution - && (wrapperStructPose.poseScaleMode != ScaleMode::InputResolution || (finalOutputSize != producerSize)) - && (wrapperStructPose.poseScaleMode != ScaleMode::NetOutputResolution || (finalOutputSize != netOutputSize))) + if (wrapperStructPose.keypointScale != ScaleMode::OutputResolution + && (wrapperStructPose.keypointScale != ScaleMode::InputResolution || (finalOutputSize != producerSize)) + && (wrapperStructPose.keypointScale != ScaleMode::NetOutputResolution || (finalOutputSize != netOutputSize))) { - auto keyPointScaler = std::make_shared(wrapperStructPose.poseScaleMode); - mPostProcessingWs.emplace_back(std::make_shared>(keyPointScaler)); + auto keypointScaler = std::make_shared(wrapperStructPose.keypointScale); + mPostProcessingWs.emplace_back(std::make_shared>(keypointScaler)); } mOutputWs.clear(); // Write people pose data on disk (json for OpenCV >= 3, xml, yml...) - if (!writePoseCleaned.empty()) + if (!writeKeypointCleaned.empty()) { - const auto poseSaver = std::make_shared(writePoseCleaned, wrapperStructOutput.writePoseDataFormat); - mOutputWs.emplace_back(std::make_shared>(poseSaver)); + const auto keypointSaver = std::make_shared(writeKeypointCleaned, wrapperStructOutput.writeKeypointFormat); + mOutputWs.emplace_back(std::make_shared>(keypointSaver)); + if (wrapperStructFace.enable) + mOutputWs.emplace_back(std::make_shared>(keypointSaver)); + if (wrapperHandStruct.extractAndRenderHands) + mOutputWs.emplace_back(std::make_shared>(keypointSaver)); } // Write people pose data on disk (json format) - if (!writePoseJsonCleaned.empty()) + if (!writeKeypointJsonCleaned.empty()) { - const auto poseJsonSaver = std::make_shared(writePoseJsonCleaned); - mOutputWs.emplace_back(std::make_shared>(poseJsonSaver)); + const auto keypointJsonSaver = std::make_shared(writeKeypointJsonCleaned); + mOutputWs.emplace_back(std::make_shared>(keypointJsonSaver)); + if (wrapperStructFace.enable) + mOutputWs.emplace_back(std::make_shared>(keypointJsonSaver)); + if (wrapperHandStruct.extractAndRenderHands) + mOutputWs.emplace_back(std::make_shared>(keypointJsonSaver)); } // Write people pose data on disk (COCO validation json format) if (!wrapperStructOutput.writeCocoJson.empty()) { const auto humanFormat = true; // If true, bigger size (and potentially slower to process), but easier for a human to read it - const auto poseJsonCocoSaver = std::make_shared(wrapperStructOutput.writeCocoJson, humanFormat); - mOutputWs.emplace_back(std::make_shared>(poseJsonCocoSaver)); + const auto cocoJsonSaver = std::make_shared(wrapperStructOutput.writeCocoJson, humanFormat); + mOutputWs.emplace_back(std::make_shared>(cocoJsonSaver)); } // Write frames as desired image format on hard disk if (!writeImagesCleaned.empty()) @@ -707,7 +742,7 @@ namespace op || mThreadManagerMode == ThreadManagerMode::Asynchronous || mThreadManagerMode == ThreadManagerMode::AsynchronousOut)) { - const auto guiInfoAdder = std::make_shared(finalOutputSize, wrapperStructPose.gpuNumber, wrapperStructOutput.displayGui); + const auto guiInfoAdder = std::make_shared(finalOutputSize, gpuNumber, wrapperStructOutput.displayGui); mOutputWs.emplace_back(std::make_shared>(guiInfoAdder)); } // Minimal graphical user interface (GUI) @@ -1070,4 +1105,4 @@ namespace op extern template class Wrapper; } -#endif // OPENPOSE__WRAPPER__WRAPPER_HPP +#endif // OPENPOSE_WRAPPER_WRAPPER_HPP diff --git a/include/openpose/wrapper/wrapperStructFace.hpp b/include/openpose/wrapper/wrapperStructFace.hpp index f2c84712..29f79dd0 100644 --- a/include/openpose/wrapper/wrapperStructFace.hpp +++ b/include/openpose/wrapper/wrapperStructFace.hpp @@ -1,32 +1,57 @@ -#ifndef OPENPOSE__WRAPPER__WRAPPER_STRUCT_FACE_HPP -#define OPENPOSE__WRAPPER__WRAPPER_STRUCT_FACE_HPP +#ifndef OPENPOSE_WRAPPER_WRAPPER_STRUCT_FACE_HPP +#define OPENPOSE_WRAPPER_WRAPPER_STRUCT_FACE_HPP + +#include +#include namespace op { - namespace experimental + /** + * WrapperStructFace: Face estimation and rendering configuration struct. + * WrapperStructFace allows the user to set up the face estimation and rendering parameters that will be used for the OpenPose Wrapper + * class. + */ + struct WrapperStructFace { /** - * WrapperStructFace: Face estimation and rendering configuration struct. - * DO NOT USE. CODE TO BE FINISHED. - * WrapperStructFace allows the user to set up the face estimation and rendering parameters that will be used for the OpenPose Wrapper - * class. + * PROVISIONAL PARAMETER. IT WILL BE CHANGED. + * Whether to extract and render face. */ - struct WrapperStructFace - { - /** - * PROVISIONAL PARAMETER. IT WILL BE CHANGED. - * Whether to extract and render face. - */ - bool extractAndRenderFace; + bool enable; - /** - * Constructor of the struct. - * It has the recommended and default values we recommend for each element of the struct. - * Since all the elements of the struct are public, they can also be manually filled. - */ - WrapperStructFace(const bool extractAndRenderFace = false); - }; - } + /** + * CCN (Conv Net) input size. + * The greater, the slower and more memory it will be needed, but it will potentially increase accuracy. + * Both width and height must be divisible by 16. + */ + Point netInputSize; + + /** + * Whether to render the output (pose locations, face, background or PAF heat maps). + */ + bool renderOutput; + + /** + * Rendering blending alpha value of the pose point locations with respect to the background image. + * Value in the range [0, 1]. 0 will only render the background, 1 will fully render the pose. + */ + float alphaKeypoint; + + /** + * Rendering blending alpha value of the heat maps (face part, background or PAF) with respect to the background image. + * Value in the range [0, 1]. 0 will only render the background, 1 will only render the heat map. + */ + float alphaHeatMap; + + /** + * Constructor of the struct. + * It has the recommended and default values we recommend for each element of the struct. + * Since all the elements of the struct are public, they can also be manually filled. + */ + WrapperStructFace(const bool enable = false, const Point& netInputSize = Point{368, 368}, + const bool renderOutput = false, const float alphaKeypoint = FACE_DEFAULT_ALPHA_KEYPOINT, + const float alphaHeatMap = FACE_DEFAULT_ALPHA_HEAT_MAP); + }; } -#endif // OPENPOSE__WRAPPER__WRAPPER_STRUCT_FACE_HPP +#endif // OPENPOSE_WRAPPER_WRAPPER_STRUCT_FACE_HPP diff --git a/include/openpose/wrapper/wrapperStructHand.hpp b/include/openpose/wrapper/wrapperStructHand.hpp index 998e86e4..fdd3eff1 100644 --- a/include/openpose/wrapper/wrapperStructHand.hpp +++ b/include/openpose/wrapper/wrapperStructHand.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__WRAPPER__WRAPPER_STRUCT_HAND_HPP -#define OPENPOSE__WRAPPER__WRAPPER_STRUCT_HAND_HPP +#ifndef OPENPOSE_WRAPPER_WRAPPER_STRUCT_HAND_HPP +#define OPENPOSE_WRAPPER_WRAPPER_STRUCT_HAND_HPP namespace op { @@ -29,4 +29,4 @@ namespace op } } -#endif // OPENPOSE__WRAPPER__WRAPPER_STRUCT_HAND_HPP +#endif // OPENPOSE_WRAPPER_WRAPPER_STRUCT_HAND_HPP diff --git a/include/openpose/wrapper/wrapperStructInput.hpp b/include/openpose/wrapper/wrapperStructInput.hpp index 8587a751..1673807a 100644 --- a/include/openpose/wrapper/wrapperStructInput.hpp +++ b/include/openpose/wrapper/wrapperStructInput.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__WRAPPER__WRAPPER_STRUCT_INPUT_HPP -#define OPENPOSE__WRAPPER__WRAPPER_STRUCT_INPUT_HPP +#ifndef OPENPOSE_WRAPPER_WRAPPER_STRUCT_INPUT_HPP +#define OPENPOSE_WRAPPER_WRAPPER_STRUCT_INPUT_HPP #include #include @@ -62,4 +62,4 @@ namespace op }; } -#endif // OPENPOSE__WRAPPER__WRAPPER_STRUCT_INPUT_HPP +#endif // OPENPOSE_WRAPPER_WRAPPER_STRUCT_INPUT_HPP diff --git a/include/openpose/wrapper/wrapperStructOutput.hpp b/include/openpose/wrapper/wrapperStructOutput.hpp index 10f88de6..452c3db5 100644 --- a/include/openpose/wrapper/wrapperStructOutput.hpp +++ b/include/openpose/wrapper/wrapperStructOutput.hpp @@ -1,5 +1,5 @@ -#ifndef OPENPOSE__WRAPPER__WRAPPER_STRUCT_OUTPUT_HPP -#define OPENPOSE__WRAPPER__WRAPPER_STRUCT_OUTPUT_HPP +#ifndef OPENPOSE_WRAPPER_WRAPPER_STRUCT_OUTPUT_HPP +#define OPENPOSE_WRAPPER_WRAPPER_STRUCT_OUTPUT_HPP #include #include @@ -31,22 +31,22 @@ namespace op /** * Pose (x, y, score) locations saving folder location. * If it is empty (default), it is disabled. - * Select format with writePoseDataFormat. + * Select format with writeKeypointFormat. */ - std::string writePose; + std::string writeKeypoint; /** * Data format to save Pose (x, y, score) locations. * Options: DataFormat::Json (default), DataFormat::Xml and DataFormat::Yml (equivalent to DataFormat::Yaml) * JSON option only available for OpenCV >= 3.0. */ - DataFormat writePoseDataFormat; + DataFormat writeKeypointFormat; /** * Pose (x, y, score) locations saving folder location in JSON format (e.g. useful when needed JSON but using OpenCV < 3.0). * If it is empty (default), it is disabled. */ - std::string writePoseJson; + std::string writeKeypointJson; /** * Pose (x, y, score) locations saving folder location in JSON COCO validation format. @@ -93,11 +93,11 @@ namespace op * It has the recommended and default values we recommend for each element of the struct. * Since all the elements of the struct are public, they can also be manually filled. */ - WrapperStructOutput(const bool displayGui = false, const bool guiVerbose = false, const bool fullScreen = false, const std::string& writePose = "", - const DataFormat writePoseDataFormat = DataFormat::Xml, const std::string& writePoseJson = "", const std::string& writeCocoJson = "", + WrapperStructOutput(const bool displayGui = false, const bool guiVerbose = false, const bool fullScreen = false, const std::string& writeKeypoint = "", + const DataFormat writeKeypointFormat = DataFormat::Xml, const std::string& writeKeypointJson = "", const std::string& writeCocoJson = "", const std::string& writeImages = "", const std::string& writeImagesFormat = "", const std::string& writeVideo = "", const std::string& writeHeatMaps = "", const std::string& writeHeatMapsFormat = ""); }; } -#endif // OPENPOSE__WRAPPER__WRAPPER_STRUCT_OUTPUT_HPP +#endif // OPENPOSE_WRAPPER_WRAPPER_STRUCT_OUTPUT_HPP diff --git a/include/openpose/wrapper/wrapperStructPose.hpp b/include/openpose/wrapper/wrapperStructPose.hpp index a3889668..2c3bb3fe 100644 --- a/include/openpose/wrapper/wrapperStructPose.hpp +++ b/include/openpose/wrapper/wrapperStructPose.hpp @@ -1,8 +1,8 @@ -#ifndef OPENPOSE__WRAPPER__WRAPPER_STRUCT_POSE_HPP -#define OPENPOSE__WRAPPER__WRAPPER_STRUCT_POSE_HPP +#ifndef OPENPOSE_WRAPPER_WRAPPER_STRUCT_POSE_HPP +#define OPENPOSE_WRAPPER_WRAPPER_STRUCT_POSE_HPP -#include #include +#include #include #include @@ -20,22 +20,22 @@ namespace op * The greater, the slower and more memory it will be needed, but it will potentially increase accuracy. * Both width and height must be divisible by 16. */ - cv::Size netInputSize; + Point netInputSize; /** * Output size of the final rendered image. * It barely affects performance compared to netInputSize. - * The final Datum.poseKeyPoints can be scaled with respect to outputSize if `poseScaleMode` is set to ScaleMode::OutputResolution, even if the + * The final Datum.poseKeypoints can be scaled with respect to outputSize if `keypointScale` is set to ScaleMode::OutputResolution, even if the * rendering is disabled. */ - cv::Size outputSize; + Point outputSize; /** - * Final scale of the Array Datum.poseKeyPoints and the writen pose data. - * The final Datum.poseKeyPoints can be scaled with respect to input size (ScaleMode::InputResolution), net output size (ScaleMode::NetOutputResolution), + * Final scale of the Array Datum.poseKeypoints and the writen pose data. + * The final Datum.poseKeypoints can be scaled with respect to input size (ScaleMode::InputResolution), net output size (ScaleMode::NetOutputResolution), * output rendering size (ScaleMode::OutputResolution), from 0 to 1 (ScaleMode::ZeroToOne), and -1 to 1 (ScaleMode::PlusMinusOne). */ - ScaleMode poseScaleMode; + ScaleMode keypointScale; /** * Number of GPUs processing in parallel. @@ -83,7 +83,7 @@ namespace op * Rendering blending alpha value of the pose point locations with respect to the background image. * Value in the range [0, 1]. 0 will only render the background, 1 will fully render the pose. */ - float alphaPose; + float alphaKeypoint; /** * Rendering blending alpha value of the heat maps (body part, background or PAF) with respect to the background image. @@ -115,21 +115,21 @@ namespace op * Select ScaleMode::ZeroToOne for range [0,1], ScaleMode::PlusMinusOne for [-1,1] and ScaleMode::UnsignedChar for [0, 255] * If heatMapTypes.empty(), then this parameters makes no effect. */ - ScaleMode heatMapScaleMode; + ScaleMode heatMapScale; /** * Constructor of the struct. * It has the recommended and default values we recommend for each element of the struct. * Since all the elements of the struct are public, they can also be manually filled. */ - WrapperStructPose(const cv::Size& netInputSize = cv::Size{656, 368}, const cv::Size& outputSize = cv::Size{1280, 720}, - const ScaleMode poseScaleMode = ScaleMode::InputResolution, const int gpuNumber = 1, const int gpuNumberStart = 0, + WrapperStructPose(const Point& netInputSize = Point{656, 368}, const Point& outputSize = Point{1280, 720}, + const ScaleMode keypointScale = ScaleMode::InputResolution, const int gpuNumber = 1, const int gpuNumberStart = 0, const int scalesNumber = 1, const float scaleGap = 0.15f, const bool renderOutput = false, const PoseModel poseModel = PoseModel::COCO_18, const bool blendOriginalFrame = true, - const float alphaPose = POSE_DEFAULT_ALPHA_POSE, const float alphaHeatMap = POSE_DEFAULT_ALPHA_HEATMAP, + const float alphaKeypoint = POSE_DEFAULT_ALPHA_KEYPOINT, const float alphaHeatMap = POSE_DEFAULT_ALPHA_HEAT_MAP, const int defaultPartToRender = 0, const std::string& modelFolder = "models/", - const std::vector& heatMapTypes = {}, const ScaleMode heatMapScaleMode = ScaleMode::ZeroToOne); + const std::vector& heatMapTypes = {}, const ScaleMode heatMapScale = ScaleMode::ZeroToOne); }; } -#endif // OPENPOSE__WRAPPER__WRAPPER_STRUCT_POSE_HPP +#endif // OPENPOSE_WRAPPER_WRAPPER_STRUCT_POSE_HPP diff --git a/models/face/pose_deploy.prototxt b/models/face/pose_deploy.prototxt new file mode 100644 index 00000000..d347748c --- /dev/null +++ b/models/face/pose_deploy.prototxt @@ -0,0 +1,1728 @@ +input: "image" +input_dim: 1 +input_dim: 3 +input_dim: 1 # Original: 368 +input_dim: 1 # Original: 368 +# input: "weights" +# input_dim: 1 +# input_dim: 71 +# input_dim: 184 +# input_dim: 184 +# input: "labels" +# input_dim: 1 +# input_dim: 71 +# input_dim: 184 +# input_dim: 184 + +layer { + name: "conv1_1" + type: "Convolution" + bottom: "image" + top: "conv1_1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv1_1_re" + type: "ReLU" + bottom: "conv1_1" + top: "conv1_1" +} +layer { + name: "conv1_2" + type: "Convolution" + bottom: "conv1_1" + top: "conv1_2" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 64 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv1_2_re" + type: "ReLU" + bottom: "conv1_2" + top: "conv1_2" +} +layer { + name: "pool1" + type: "Pooling" + bottom: "conv1_2" + top: "pool1" + pooling_param { + pool: MAX + kernel_size: 2 + stride: 2 + } +} +layer { + name: "conv2_1" + type: "Convolution" + bottom: "pool1" + top: "conv2_1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv2_1_re" + type: "ReLU" + bottom: "conv2_1" + top: "conv2_1" +} +layer { + name: "conv2_2" + type: "Convolution" + bottom: "conv2_1" + top: "conv2_2" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv2_2_re" + type: "ReLU" + bottom: "conv2_2" + top: "conv2_2" +} +layer { + name: "pool2" + type: "Pooling" + bottom: "conv2_2" + top: "pool2" + pooling_param { + pool: MAX + kernel_size: 2 + stride: 2 + } +} +layer { + name: "conv3_1" + type: "Convolution" + bottom: "pool2" + top: "conv3_1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 256 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv3_1_re" + type: "ReLU" + bottom: "conv3_1" + top: "conv3_1" +} +layer { + name: "conv3_2" + type: "Convolution" + bottom: "conv3_1" + top: "conv3_2" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 256 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv3_2_re" + type: "ReLU" + bottom: "conv3_2" + top: "conv3_2" +} +layer { + name: "conv3_3" + type: "Convolution" + bottom: "conv3_2" + top: "conv3_3" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 256 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv3_3_re" + type: "ReLU" + bottom: "conv3_3" + top: "conv3_3" +} +layer { + name: "conv3_4" + type: "Convolution" + bottom: "conv3_3" + top: "conv3_4" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 256 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv3_4_re" + type: "ReLU" + bottom: "conv3_4" + top: "conv3_4" +} +layer { + name: "pool3" + type: "Pooling" + bottom: "conv3_4" + top: "pool3" + pooling_param { + pool: MAX + kernel_size: 2 + stride: 2 + } +} +layer { + name: "conv4_1" + type: "Convolution" + bottom: "pool3" + top: "conv4_1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 512 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv4_1_re" + type: "ReLU" + bottom: "conv4_1" + top: "conv4_1" +} +layer { + name: "conv4_2" + type: "Convolution" + bottom: "conv4_1" + top: "conv4_2" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 512 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv4_2_re" + type: "ReLU" + bottom: "conv4_2" + top: "conv4_2" +} +layer { + name: "conv4_3" + type: "Convolution" + bottom: "conv4_2" + top: "conv4_3" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 512 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv4_3_re" + type: "ReLU" + bottom: "conv4_3" + top: "conv4_3" +} +layer { + name: "conv4_4" + type: "Convolution" + bottom: "conv4_3" + top: "conv4_4" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 512 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv4_4_re" + type: "ReLU" + bottom: "conv4_4" + top: "conv4_4" +} +layer { + name: "conv5_1" + type: "Convolution" + bottom: "conv4_4" + top: "conv5_1" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 512 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv5_1_re" + type: "ReLU" + bottom: "conv5_1" + top: "conv5_1" +} +layer { + name: "conv5_2" + type: "Convolution" + bottom: "conv5_1" + top: "conv5_2" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 512 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv5_2_re" + type: "ReLU" + bottom: "conv5_2" + top: "conv5_2" +} +layer { + name: "conv5_3_CPM" + type: "Convolution" + bottom: "conv5_2" + top: "conv5_3_CPM" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 1 + kernel_size: 3 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv5_3_CPM_re" + type: "ReLU" + bottom: "conv5_3_CPM" + top: "conv5_3_CPM" +} +layer { + name: "conv6_1_CPM" + type: "Convolution" + bottom: "conv5_3_CPM" + top: "conv6_1_CPM" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 512 + pad: 0 + kernel_size: 1 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "conv6_1_CPM_re" + type: "ReLU" + bottom: "conv6_1_CPM" + top: "conv6_1_CPM" +} +layer { + name: "conv6_2_CPM" + type: "Convolution" + bottom: "conv6_1_CPM" + top: "conv6_2_CPM" + param { + lr_mult: 1 + decay_mult: 1 + } + param { + lr_mult: 2 + decay_mult: 0 + } + convolution_param { + num_output: 71 + pad: 0 + kernel_size: 1 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "features_in_stage_2" + type: "Concat" + bottom: "conv6_2_CPM" + bottom: "conv5_3_CPM" + top: "features_in_stage_2" + concat_param { + axis: 1 + } +} +layer { + name: "Mconv1_stage2" + type: "Convolution" + bottom: "features_in_stage_2" + top: "Mconv1_stage2" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv1_stage2_re" + type: "ReLU" + bottom: "Mconv1_stage2" + top: "Mconv1_stage2" +} +layer { + name: "Mconv2_stage2" + type: "Convolution" + bottom: "Mconv1_stage2" + top: "Mconv2_stage2" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv2_stage2_re" + type: "ReLU" + bottom: "Mconv2_stage2" + top: "Mconv2_stage2" +} +layer { + name: "Mconv3_stage2" + type: "Convolution" + bottom: "Mconv2_stage2" + top: "Mconv3_stage2" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv3_stage2_re" + type: "ReLU" + bottom: "Mconv3_stage2" + top: "Mconv3_stage2" +} +layer { + name: "Mconv4_stage2" + type: "Convolution" + bottom: "Mconv3_stage2" + top: "Mconv4_stage2" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv4_stage2_re" + type: "ReLU" + bottom: "Mconv4_stage2" + top: "Mconv4_stage2" +} +layer { + name: "Mconv5_stage2" + type: "Convolution" + bottom: "Mconv4_stage2" + top: "Mconv5_stage2" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv5_stage2_re" + type: "ReLU" + bottom: "Mconv5_stage2" + top: "Mconv5_stage2" +} +layer { + name: "Mconv6_stage2" + type: "Convolution" + bottom: "Mconv5_stage2" + top: "Mconv6_stage2" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 0 + kernel_size: 1 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv6_stage2_re" + type: "ReLU" + bottom: "Mconv6_stage2" + top: "Mconv6_stage2" +} +layer { + name: "Mconv7_stage2" + type: "Convolution" + bottom: "Mconv6_stage2" + top: "Mconv7_stage2" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 71 + pad: 0 + kernel_size: 1 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "features_in_stage_3" + type: "Concat" + bottom: "Mconv7_stage2" + bottom: "conv5_3_CPM" + top: "features_in_stage_3" + concat_param { + axis: 1 + } +} +layer { + name: "Mconv1_stage3" + type: "Convolution" + bottom: "features_in_stage_3" + top: "Mconv1_stage3" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv1_stage3_re" + type: "ReLU" + bottom: "Mconv1_stage3" + top: "Mconv1_stage3" +} +layer { + name: "Mconv2_stage3" + type: "Convolution" + bottom: "Mconv1_stage3" + top: "Mconv2_stage3" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv2_stage3_re" + type: "ReLU" + bottom: "Mconv2_stage3" + top: "Mconv2_stage3" +} +layer { + name: "Mconv3_stage3" + type: "Convolution" + bottom: "Mconv2_stage3" + top: "Mconv3_stage3" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv3_stage3_re" + type: "ReLU" + bottom: "Mconv3_stage3" + top: "Mconv3_stage3" +} +layer { + name: "Mconv4_stage3" + type: "Convolution" + bottom: "Mconv3_stage3" + top: "Mconv4_stage3" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv4_stage3_re" + type: "ReLU" + bottom: "Mconv4_stage3" + top: "Mconv4_stage3" +} +layer { + name: "Mconv5_stage3" + type: "Convolution" + bottom: "Mconv4_stage3" + top: "Mconv5_stage3" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv5_stage3_re" + type: "ReLU" + bottom: "Mconv5_stage3" + top: "Mconv5_stage3" +} +layer { + name: "Mconv6_stage3" + type: "Convolution" + bottom: "Mconv5_stage3" + top: "Mconv6_stage3" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 0 + kernel_size: 1 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv6_stage3_re" + type: "ReLU" + bottom: "Mconv6_stage3" + top: "Mconv6_stage3" +} +layer { + name: "Mconv7_stage3" + type: "Convolution" + bottom: "Mconv6_stage3" + top: "Mconv7_stage3" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 71 + pad: 0 + kernel_size: 1 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "features_in_stage_4" + type: "Concat" + bottom: "Mconv7_stage3" + bottom: "conv5_3_CPM" + top: "features_in_stage_4" + concat_param { + axis: 1 + } +} +layer { + name: "Mconv1_stage4" + type: "Convolution" + bottom: "features_in_stage_4" + top: "Mconv1_stage4" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv1_stage4_re" + type: "ReLU" + bottom: "Mconv1_stage4" + top: "Mconv1_stage4" +} +layer { + name: "Mconv2_stage4" + type: "Convolution" + bottom: "Mconv1_stage4" + top: "Mconv2_stage4" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv2_stage4_re" + type: "ReLU" + bottom: "Mconv2_stage4" + top: "Mconv2_stage4" +} +layer { + name: "Mconv3_stage4" + type: "Convolution" + bottom: "Mconv2_stage4" + top: "Mconv3_stage4" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv3_stage4_re" + type: "ReLU" + bottom: "Mconv3_stage4" + top: "Mconv3_stage4" +} +layer { + name: "Mconv4_stage4" + type: "Convolution" + bottom: "Mconv3_stage4" + top: "Mconv4_stage4" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv4_stage4_re" + type: "ReLU" + bottom: "Mconv4_stage4" + top: "Mconv4_stage4" +} +layer { + name: "Mconv5_stage4" + type: "Convolution" + bottom: "Mconv4_stage4" + top: "Mconv5_stage4" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv5_stage4_re" + type: "ReLU" + bottom: "Mconv5_stage4" + top: "Mconv5_stage4" +} +layer { + name: "Mconv6_stage4" + type: "Convolution" + bottom: "Mconv5_stage4" + top: "Mconv6_stage4" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 0 + kernel_size: 1 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv6_stage4_re" + type: "ReLU" + bottom: "Mconv6_stage4" + top: "Mconv6_stage4" +} +layer { + name: "Mconv7_stage4" + type: "Convolution" + bottom: "Mconv6_stage4" + top: "Mconv7_stage4" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 71 + pad: 0 + kernel_size: 1 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "features_in_stage_5" + type: "Concat" + bottom: "Mconv7_stage4" + bottom: "conv5_3_CPM" + top: "features_in_stage_5" + concat_param { + axis: 1 + } +} +layer { + name: "Mconv1_stage5" + type: "Convolution" + bottom: "features_in_stage_5" + top: "Mconv1_stage5" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv1_stage5_re" + type: "ReLU" + bottom: "Mconv1_stage5" + top: "Mconv1_stage5" +} +layer { + name: "Mconv2_stage5" + type: "Convolution" + bottom: "Mconv1_stage5" + top: "Mconv2_stage5" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv2_stage5_re" + type: "ReLU" + bottom: "Mconv2_stage5" + top: "Mconv2_stage5" +} +layer { + name: "Mconv3_stage5" + type: "Convolution" + bottom: "Mconv2_stage5" + top: "Mconv3_stage5" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv3_stage5_re" + type: "ReLU" + bottom: "Mconv3_stage5" + top: "Mconv3_stage5" +} +layer { + name: "Mconv4_stage5" + type: "Convolution" + bottom: "Mconv3_stage5" + top: "Mconv4_stage5" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv4_stage5_re" + type: "ReLU" + bottom: "Mconv4_stage5" + top: "Mconv4_stage5" +} +layer { + name: "Mconv5_stage5" + type: "Convolution" + bottom: "Mconv4_stage5" + top: "Mconv5_stage5" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv5_stage5_re" + type: "ReLU" + bottom: "Mconv5_stage5" + top: "Mconv5_stage5" +} +layer { + name: "Mconv6_stage5" + type: "Convolution" + bottom: "Mconv5_stage5" + top: "Mconv6_stage5" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 0 + kernel_size: 1 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv6_stage5_re" + type: "ReLU" + bottom: "Mconv6_stage5" + top: "Mconv6_stage5" +} +layer { + name: "Mconv7_stage5" + type: "Convolution" + bottom: "Mconv6_stage5" + top: "Mconv7_stage5" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 71 + pad: 0 + kernel_size: 1 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "features_in_stage_6" + type: "Concat" + bottom: "Mconv7_stage5" + bottom: "conv5_3_CPM" + top: "features_in_stage_6" + concat_param { + axis: 1 + } +} +layer { + name: "Mconv1_stage6" + type: "Convolution" + bottom: "features_in_stage_6" + top: "Mconv1_stage6" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv1_stage6_re" + type: "ReLU" + bottom: "Mconv1_stage6" + top: "Mconv1_stage6" +} +layer { + name: "Mconv2_stage6" + type: "Convolution" + bottom: "Mconv1_stage6" + top: "Mconv2_stage6" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv2_stage6_re" + type: "ReLU" + bottom: "Mconv2_stage6" + top: "Mconv2_stage6" +} +layer { + name: "Mconv3_stage6" + type: "Convolution" + bottom: "Mconv2_stage6" + top: "Mconv3_stage6" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv3_stage6_re" + type: "ReLU" + bottom: "Mconv3_stage6" + top: "Mconv3_stage6" +} +layer { + name: "Mconv4_stage6" + type: "Convolution" + bottom: "Mconv3_stage6" + top: "Mconv4_stage6" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv4_stage6_re" + type: "ReLU" + bottom: "Mconv4_stage6" + top: "Mconv4_stage6" +} +layer { + name: "Mconv5_stage6" + type: "Convolution" + bottom: "Mconv4_stage6" + top: "Mconv5_stage6" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 3 + kernel_size: 7 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv5_stage6_re" + type: "ReLU" + bottom: "Mconv5_stage6" + top: "Mconv5_stage6" +} +layer { + name: "Mconv6_stage6" + type: "Convolution" + bottom: "Mconv5_stage6" + top: "Mconv6_stage6" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 128 + pad: 0 + kernel_size: 1 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} +layer { + name: "Mconv6_stage6_re" + type: "ReLU" + bottom: "Mconv6_stage6" + top: "Mconv6_stage6" +} +layer { + name: "Mconv7_stage6" + type: "Convolution" + bottom: "Mconv6_stage6" +# top: "Mconv7_stage6" + top: "net_output" + param { + lr_mult: 4.0 + decay_mult: 1 + } + param { + lr_mult: 8.0 + decay_mult: 0 + } + convolution_param { + num_output: 71 + pad: 0 + kernel_size: 1 + weight_filler { + type: "gaussian" + std: 0.01 + } + bias_filler { + type: "constant" + } + } +} diff --git a/models/getModels.sh b/models/getModels.sh index 8cda1ea0..644a9d41 100755 --- a/models/getModels.sh +++ b/models/getModels.sh @@ -1,23 +1,24 @@ # "------------------------- POSE MODELS -------------------------" -# Downloading COCO and MPI models -models_folder="pose/" +# Downloading body pose (COCO and MPI) as well as face models +pose_folder="pose/" +face_folder="face/" -# COCO -coco_folder="$models_folder"coco/"" +# Body (COCO) +coco_folder="$pose_folder"coco/"" coco_model="$coco_folder"pose_iter_440000.caffemodel"" if [ ! -f $coco_model ]; then - wget http://posefs1.perception.cs.cmu.edu/Users/tsimon/Projects/coco/data/models/coco/pose_iter_440000.caffemodel -P $coco_folder + wget http://posefs1.perception.cs.cmu.edu/OpenPose/models/$coco_model -P $coco_folder fi -# MPI -mpi_folder="$models_folder"mpi/"" +# Body (MPI) +mpi_folder="$pose_folder"mpi/"" mpi_model="$mpi_folder"pose_iter_160000.caffemodel"" if [ ! -f $mpi_model ]; then - wget http://posefs1.perception.cs.cmu.edu/Users/tsimon/Projects/coco/data/models/mpi/pose_iter_160000.caffemodel -P $mpi_folder + wget http://posefs1.perception.cs.cmu.edu/OpenPose/models/$mpi_model -P $mpi_folder fi - - -# EXTRA - Other paths -# /media/posenas1b/Users/zhe/arch/MPI_exp_caffe/pose43/exp04/model/pose_iter_264000.caffemodel -# cubeserver1:/home/zhe/Real-time-CPM-for-multiple-people/model/pose_iter_166000.caffemodel +# Face +face_model="$face_folder"pose_iter_116000.caffemodel"" +if [ ! -f $face_model ]; then + wget http://posefs1.perception.cs.cmu.edu/OpenPose/models/$face_model -P $face_folder +fi diff --git a/src/openpose/core/array.cpp b/src/openpose/core/array.cpp index 6d79bf6f..0776d289 100644 --- a/src/openpose/core/array.cpp +++ b/src/openpose/core/array.cpp @@ -336,6 +336,37 @@ namespace op } } + template + const std::string Array::toString() const + { + try + { + // Initial value + std::string string{"Array::toString():\n"}; + // Add each element + for (auto i = 0 ; i < mVolume ; i++) + { + // Adding element sepearted by an space + string += std::to_string(spData[i]) + " "; + // Introduce an enter for each dimension change + // If comented, all values will be printed in the same line + auto multiplier = 1u; + for (auto dimension = mSize.size() - 1u ; dimension > 0 && ((i/multiplier) % getSize(dimension) == getSize(dimension)-1) ; dimension--) + { + string += "\n"; + multiplier *= getSize(dimension); + } + } + // Return string + return string; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return ""; + } + } + template int Array::getIndex(const std::vector& indexes) const { diff --git a/src/openpose/core/cvMatToOpInput.cpp b/src/openpose/core/cvMatToOpInput.cpp index 440be2e2..225864c7 100644 --- a/src/openpose/core/cvMatToOpInput.cpp +++ b/src/openpose/core/cvMatToOpInput.cpp @@ -5,10 +5,10 @@ namespace op { - CvMatToOpInput::CvMatToOpInput(const cv::Size& netInputResolution, const int scaleNumber, const float scaleGap) : + CvMatToOpInput::CvMatToOpInput(const Point& netInputResolution, const int scaleNumber, const float scaleGap) : mScaleNumber{scaleNumber}, mScaleGap{scaleGap}, - mInputNetSize4D{{mScaleNumber, 3, netInputResolution.height, netInputResolution.width}} + mInputNetSize4D{{mScaleNumber, 3, netInputResolution.y, netInputResolution.x}} { } @@ -33,9 +33,9 @@ namespace op const auto targetWidth = fastTruncate(16 * intRound(netInputWidth * requestedScale / 16.), 1, netInputWidth/16*16); const auto netInputHeight = inputNetData.getSize(2); const auto targetHeight = fastTruncate(16 * intRound(netInputHeight * requestedScale / 16.), 1, netInputHeight/16*16); - const cv::Size targetSize{targetWidth, targetHeight}; - const auto scale = resizeGetScaleFactor(cvInputData.size(), targetSize); - const cv::Mat frameWithNetSize = resizeFixedAspectRatio(cvInputData, scale, cv::Size{netInputWidth, netInputHeight}); + const Point targetSize{targetWidth, targetHeight}; + const auto scale = resizeGetScaleFactor(Point{cvInputData.cols, cvInputData.rows}, targetSize); + const cv::Mat frameWithNetSize = resizeFixedAspectRatio(cvInputData, scale, Point{netInputWidth, netInputHeight}); uCharCvMatToFloatPtr(inputNetData.getPtr() + i * inputNetDataOffset, frameWithNetSize, true); } diff --git a/src/openpose/core/cvMatToOpOutput.cpp b/src/openpose/core/cvMatToOpOutput.cpp index 97412364..e88bc036 100644 --- a/src/openpose/core/cvMatToOpOutput.cpp +++ b/src/openpose/core/cvMatToOpOutput.cpp @@ -4,9 +4,9 @@ namespace op { - CvMatToOpOutput::CvMatToOpOutput(const cv::Size& outputResolution, const bool generateOutput) : + CvMatToOpOutput::CvMatToOpOutput(const Point& outputResolution, const bool generateOutput) : mGenerateOutput{generateOutput}, - mOutputSize3D{{3, outputResolution.height, outputResolution.width}} + mOutputSize3D{{3, outputResolution.y, outputResolution.x}} { } @@ -19,8 +19,8 @@ namespace op error("Wrong input element (empty cvInputData).", __LINE__, __FUNCTION__, __FILE__); // outputData - Reescale keeping aspect ratio and transform to float the output image - const cv::Size outputResolution{mOutputSize3D[2], mOutputSize3D[1]}; - const double scaleInputToOutput = resizeGetScaleFactor(cvInputData.size(), outputResolution); + const Point outputResolution{mOutputSize3D[2], mOutputSize3D[1]}; + const double scaleInputToOutput = resizeGetScaleFactor(Point{cvInputData.cols, cvInputData.rows}, outputResolution); const cv::Mat frameWithOutputSize = resizeFixedAspectRatio(cvInputData, scaleInputToOutput, outputResolution); Array outputData; if (mGenerateOutput) diff --git a/src/openpose/core/datum.cpp b/src/openpose/core/datum.cpp index 349730f1..950cdc6b 100644 --- a/src/openpose/core/datum.cpp +++ b/src/openpose/core/datum.cpp @@ -18,10 +18,11 @@ namespace op outputData{datum.outputData}, cvOutputData{datum.cvOutputData}, // Resulting Array data - poseKeyPoints{datum.poseKeyPoints}, + poseKeypoints{datum.poseKeypoints}, poseHeatMaps{datum.poseHeatMaps}, - faceKeyPoints{datum.faceKeyPoints}, - handKeyPoints{datum.handKeyPoints}, + faceRectangles{datum.faceRectangles}, + faceKeypoints{datum.faceKeypoints}, + handKeypoints{datum.handKeypoints}, // Other parameters scaleInputToOutput{datum.scaleInputToOutput}, scaleNetToOutput{datum.scaleNetToOutput}, @@ -43,10 +44,11 @@ namespace op outputData = datum.outputData; cvOutputData = datum.cvOutputData; // Resulting Array data - poseKeyPoints = datum.poseKeyPoints; + poseKeypoints = datum.poseKeypoints; poseHeatMaps = datum.poseHeatMaps, - faceKeyPoints = datum.faceKeyPoints, - handKeyPoints = datum.handKeyPoints, + faceRectangles = datum.faceRectangles, + faceKeypoints = datum.faceKeypoints, + handKeypoints = datum.handKeypoints, // Other parameters scaleInputToOutput = datum.scaleInputToOutput; scaleNetToOutput = datum.scaleNetToOutput; @@ -79,10 +81,11 @@ namespace op std::swap(outputData, datum.outputData); std::swap(cvOutputData, datum.cvOutputData); // Resulting Array data - std::swap(poseKeyPoints, datum.poseKeyPoints); + std::swap(poseKeypoints, datum.poseKeypoints); std::swap(poseHeatMaps, datum.poseHeatMaps); - std::swap(faceKeyPoints, datum.faceKeyPoints); - std::swap(handKeyPoints, datum.handKeyPoints); + std::swap(faceRectangles, datum.faceRectangles); + std::swap(faceKeypoints, datum.faceKeypoints); + std::swap(handKeypoints, datum.handKeypoints); // Other parameters std::swap(elementRendered, datum.elementRendered); } @@ -106,10 +109,11 @@ namespace op std::swap(outputData, datum.outputData); std::swap(cvOutputData, datum.cvOutputData); // Resulting Array data - std::swap(poseKeyPoints, datum.poseKeyPoints); + std::swap(poseKeypoints, datum.poseKeypoints); std::swap(poseHeatMaps, datum.poseHeatMaps); - std::swap(faceKeyPoints, datum.faceKeyPoints); - std::swap(handKeyPoints, datum.handKeyPoints); + std::swap(faceRectangles, datum.faceRectangles); + std::swap(faceKeypoints, datum.faceKeypoints); + std::swap(handKeypoints, datum.handKeypoints); // Other parameters scaleInputToOutput = datum.scaleInputToOutput; scaleNetToOutput = datum.scaleNetToOutput; @@ -143,10 +147,11 @@ namespace op datum.outputData = outputData.clone(); datum.cvOutputData = cvOutputData.clone(); // Resulting Array data - datum.poseKeyPoints = poseKeyPoints.clone(); + datum.poseKeypoints = poseKeypoints.clone(); datum.poseHeatMaps = poseHeatMaps.clone(); - datum.faceKeyPoints = faceKeyPoints.clone(); - datum.handKeyPoints = handKeyPoints.clone(); + datum.faceRectangles = faceRectangles; + datum.faceKeypoints = faceKeypoints.clone(); + datum.handKeypoints = handKeypoints.clone(); // Other parameters datum.scaleInputToOutput = scaleInputToOutput; datum.scaleNetToOutput = scaleNetToOutput; diff --git a/src/openpose/core/defineTemplates.cpp b/src/openpose/core/defineTemplates.cpp index e0584a17..676a25dd 100644 --- a/src/openpose/core/defineTemplates.cpp +++ b/src/openpose/core/defineTemplates.cpp @@ -4,6 +4,6 @@ namespace op { DEFINE_TEMPLATE_DATUM(WCvMatToOpInput); DEFINE_TEMPLATE_DATUM(WCvMatToOpOutput); - DEFINE_TEMPLATE_DATUM(WKeyPointScaler); + DEFINE_TEMPLATE_DATUM(WKeypointScaler); DEFINE_TEMPLATE_DATUM(WOpOutputToCvMat); } diff --git a/src/openpose/core/keyPointScaler.cpp b/src/openpose/core/keypointScaler.cpp similarity index 73% rename from src/openpose/core/keyPointScaler.cpp rename to src/openpose/core/keypointScaler.cpp index 49b5f43f..c2081f75 100644 --- a/src/openpose/core/keyPointScaler.cpp +++ b/src/openpose/core/keypointScaler.cpp @@ -1,15 +1,15 @@ -#include +#include #include -#include +#include namespace op { - KeyPointScaler::KeyPointScaler(const ScaleMode scaleMode) : + KeypointScaler::KeypointScaler(const ScaleMode scaleMode) : mScaleMode{scaleMode} { } - void KeyPointScaler::scale(Array& arrayToScale, const float scaleInputToOutput, const float scaleNetToOutput, const cv::Size& producerSize) const + void KeypointScaler::scale(Array& arrayToScale, const float scaleInputToOutput, const float scaleNetToOutput, const Point& producerSize) const { try { @@ -22,7 +22,7 @@ namespace op } } - void KeyPointScaler::scale(std::vector>& arrayToScalesToScale, const float scaleInputToOutput, const float scaleNetToOutput, const cv::Size& producerSize) const + void KeypointScaler::scale(std::vector>& arrayToScalesToScale, const float scaleInputToOutput, const float scaleNetToOutput, const Point& producerSize) const { try { @@ -31,29 +31,29 @@ namespace op // InputResolution if (mScaleMode == ScaleMode::InputResolution) for (auto& arrayToScale : arrayToScalesToScale) - scaleKeyPoints(arrayToScale, 1.f/scaleInputToOutput); + scaleKeypoints(arrayToScale, 1.f/scaleInputToOutput); // NetOutputResolution else if (mScaleMode == ScaleMode::NetOutputResolution) for (auto& arrayToScale : arrayToScalesToScale) - scaleKeyPoints(arrayToScale, 1.f/scaleNetToOutput); + scaleKeypoints(arrayToScale, 1.f/scaleNetToOutput); // [0,1] else if (mScaleMode == ScaleMode::ZeroToOne) { const auto scale = 1.f/scaleInputToOutput; - const auto scaleX = scale / ((float)producerSize.width - 1.f); - const auto scaleY = scale / ((float)producerSize.height - 1.f); + const auto scaleX = scale / ((float)producerSize.x - 1.f); + const auto scaleY = scale / ((float)producerSize.y - 1.f); for (auto& arrayToScale : arrayToScalesToScale) - scaleKeyPoints(arrayToScale, scaleX, scaleY); + scaleKeypoints(arrayToScale, scaleX, scaleY); } // [-1,1] else if (mScaleMode == ScaleMode::PlusMinusOne) { const auto scale = 2.f/scaleInputToOutput; - const auto scaleX = (scale / ((float)producerSize.width - 1.f)); - const auto scaleY = (scale / ((float)producerSize.height - 1.f)); + const auto scaleX = (scale / ((float)producerSize.x - 1.f)); + const auto scaleY = (scale / ((float)producerSize.y - 1.f)); const auto offset = -1.f; for (auto& arrayToScale : arrayToScalesToScale) - scaleKeyPoints(arrayToScale, scaleX, scaleY, offset, offset); + scaleKeypoints(arrayToScale, scaleX, scaleY, offset, offset); } // Unknown else diff --git a/src/openpose/core/opOutputToCvMat.cpp b/src/openpose/core/opOutputToCvMat.cpp index 8141b1dd..834435c9 100644 --- a/src/openpose/core/opOutputToCvMat.cpp +++ b/src/openpose/core/opOutputToCvMat.cpp @@ -4,7 +4,7 @@ namespace op { - OpOutputToCvMat::OpOutputToCvMat(const cv::Size& outputResolution) : + OpOutputToCvMat::OpOutputToCvMat(const Point& outputResolution) : mOutputResolution{outputResolution} { } diff --git a/src/openpose/core/point.cpp b/src/openpose/core/point.cpp new file mode 100644 index 00000000..474b9ced --- /dev/null +++ b/src/openpose/core/point.cpp @@ -0,0 +1,179 @@ +#include +#include +#include + +namespace op +{ + template + Point::Point(const T x_, const T y_) : + x{x_}, + y{y_} + { + } + + template + Point::Point(const Point& point) + { + try + { + x = point.x; + y = point.y; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + template + Point& Point::operator=(const Point& point) + { + try + { + x = point.x; + y = point.y; + // Return + return *this; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return *this; + } + } + + template + Point::Point(Point&& point) + { + try + { + x = point.x; + y = point.y; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + template + Point& Point::operator=(Point&& point) + { + try + { + x = point.x; + y = point.y; + // Return + return *this; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return *this; + } + } + + template + Point& Point::operator+=(const Point& point) + { + try + { + x += point.x; + y += point.y; + // Return + return *this; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return *this; + } + } + + template + Point& Point::operator+=(const T value) + { + try + { + x += value; + y += value; + // Return + return *this; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return *this; + } + } + + template + Point& Point::operator-=(const Point& point) + { + try + { + x -= point.x; + y -= point.y; + // Return + return *this; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return *this; + } + } + + template + Point& Point::operator-=(const T value) + { + try + { + x -= value; + y -= value; + // Return + return *this; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return *this; + } + } + + template + Point& Point::operator*=(const T value) + { + try + { + x *= value; + y *= value; + // Return + return *this; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return *this; + } + } + + template + Point& Point::operator/=(const T value) + { + try + { + x /= value; + y /= value; + // Return + return *this; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return *this; + } + } + + COMPILE_TEMPLATE_BASIC_TYPES(Point); +} diff --git a/src/openpose/core/rectangle.cpp b/src/openpose/core/rectangle.cpp new file mode 100644 index 00000000..7a024324 --- /dev/null +++ b/src/openpose/core/rectangle.cpp @@ -0,0 +1,115 @@ +#include +#include +#include + +namespace op +{ + template + Rectangle::Rectangle(const T x_, const T y_, const T width_, const T height_) : + x{x_}, + y{y_}, + width{width_}, + height{height_} + { + } + + template + Rectangle::Rectangle(const Rectangle& rectangle) + { + try + { + x = rectangle.x; + y = rectangle.y; + width = rectangle.width; + height = rectangle.height; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + template + Rectangle& Rectangle::operator=(const Rectangle& rectangle) + { + try + { + x = rectangle.x; + y = rectangle.y; + width = rectangle.width; + height = rectangle.height; + // Return + return *this; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return *this; + } + } + + template + Rectangle::Rectangle(Rectangle&& rectangle) + { + try + { + x = rectangle.x; + y = rectangle.y; + width = rectangle.width; + height = rectangle.height; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + template + Rectangle& Rectangle::operator=(Rectangle&& rectangle) + { + try + { + x = rectangle.x; + y = rectangle.y; + width = rectangle.width; + height = rectangle.height; + // Return + return *this; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return *this; + } + } + + template + Point Rectangle::center() const + { + try + { + return Point{T(x + width / 2), T(y + height / 2)}; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return Point{}; + } + } + + template + Point Rectangle::bottomRight() const + { + try + { + return Point{T(x + width), T(y + height)}; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return Point{}; + } + } + + COMPILE_TEMPLATE_BASIC_TYPES(Rectangle); +} diff --git a/src/openpose/core/renderer.cpp b/src/openpose/core/renderer.cpp index 8e6eb374..bc916ea7 100644 --- a/src/openpose/core/renderer.cpp +++ b/src/openpose/core/renderer.cpp @@ -5,9 +5,14 @@ namespace op { - Renderer::Renderer(const unsigned long long volume) : + Renderer::Renderer(const unsigned long long volume, const float alphaKeypoint, const float alphaHeatMap, const unsigned int elementToRender, + const unsigned int numberElementsToRender) : spGpuMemoryPtr{std::make_shared()}, + spElementToRender{std::make_shared>(elementToRender)}, + spNumberElementsToRender{std::make_shared(numberElementsToRender)}, mVolume{volume}, + mAlphaKeypoint{alphaKeypoint}, + mAlphaHeatMap{alphaHeatMap}, mIsFirstRenderer{true}, mIsLastRenderer{true}, spGpuMemoryAllocated{std::make_shared(false)} @@ -40,28 +45,110 @@ namespace op } } - std::pair, std::shared_ptr> Renderer::getGpuMemoryAndSetAsFirst() + void Renderer::increaseElementToRender(const int increment) { try { - mIsLastRenderer = false; - return std::make_pair(spGpuMemoryPtr, spGpuMemoryAllocated); + auto elementToRender = (((int)(*spElementToRender) + increment) % (int)(*spNumberElementsToRender)); + // Handling negative increments + while (elementToRender < 0) + elementToRender += *spNumberElementsToRender; + // Update final value + *spElementToRender = elementToRender; } catch (const std::exception& e) { error(e.what(), __LINE__, __FUNCTION__, __FILE__); - return std::make_pair(nullptr, nullptr); } } - void Renderer::setGpuMemoryAndSetIfLast(const std::pair, std::shared_ptr>& gpuMemory, const bool isLast) + void Renderer::setElementToRender(const int elementToRender) + { + try + { + *spElementToRender = elementToRender % *spNumberElementsToRender; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + std::tuple, std::shared_ptr, std::shared_ptr>, std::shared_ptr> Renderer::getSharedParameters() + { + try + { + mIsLastRenderer = false; + return std::make_tuple(spGpuMemoryPtr, spGpuMemoryAllocated, spElementToRender, spNumberElementsToRender); + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return std::make_tuple(nullptr, nullptr, nullptr, nullptr); + } + } + + void Renderer::setSharedParametersAndIfLast(const std::tuple, std::shared_ptr, std::shared_ptr>, + std::shared_ptr>& tuple, const bool isLast) { try { mIsFirstRenderer = false; mIsLastRenderer = isLast; - spGpuMemoryPtr = gpuMemory.first; - spGpuMemoryAllocated = gpuMemory.second; + spGpuMemoryPtr = std::get<0>(tuple); + spGpuMemoryAllocated = std::get<1>(tuple); + spElementToRender = std::get<2>(tuple); + spNumberElementsToRender = std::get<3>(tuple); + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + float Renderer::getAlphaKeypoint() const + { + try + { + return mAlphaKeypoint; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return 0.f; + } + } + + void Renderer::setAlphaKeypoint(const float alphaKeypoint) + { + try + { + mAlphaKeypoint = alphaKeypoint; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + float Renderer::getAlphaHeatMap() const + { + try + { + return mAlphaHeatMap; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return 0.f; + } + } + + void Renderer::setAlphaHeatMap(const float alphaHeatMap) + { + try + { + mAlphaHeatMap = alphaHeatMap; } catch (const std::exception& e) { diff --git a/src/openpose/core/scaleKeyPoints.cpp b/src/openpose/core/scaleKeypoints.cpp similarity index 69% rename from src/openpose/core/scaleKeyPoints.cpp rename to src/openpose/core/scaleKeypoints.cpp index 1018e8c8..9952fde1 100644 --- a/src/openpose/core/scaleKeyPoints.cpp +++ b/src/openpose/core/scaleKeypoints.cpp @@ -1,15 +1,15 @@ #include -#include +#include namespace op { const std::string errorMessage = "This function is only for array of dimension: [sizeA x sizeB x 3]."; - void scaleKeyPoints(Array& keyPoints, const float scale) + void scaleKeypoints(Array& keypoints, const float scale) { try { - scaleKeyPoints(keyPoints, scale, scale); + scaleKeypoints(keypoints, scale, scale); } catch (const std::exception& e) { @@ -17,18 +17,18 @@ namespace op } } - void scaleKeyPoints(Array& keyPoints, const float scaleX, const float scaleY) + void scaleKeypoints(Array& keypoints, const float scaleX, const float scaleY) { try { if (scaleX != 1. && scaleY != 1.) { // Error check - if (!keyPoints.empty() && keyPoints.getSize(2) != 3) + if (!keypoints.empty() && keypoints.getSize(2) != 3) error(errorMessage, __LINE__, __FUNCTION__, __FILE__); // Get #people and #parts - const auto numberPeople = keyPoints.getSize(0); - const auto numberParts = keyPoints.getSize(1); + const auto numberPeople = keypoints.getSize(0); + const auto numberParts = keypoints.getSize(1); // For each person for (auto person = 0 ; person < numberPeople ; person++) { @@ -36,8 +36,8 @@ namespace op for (auto part = 0 ; part < numberParts ; part++) { const auto finalIndex = 3*(person*numberParts + part); - keyPoints[finalIndex] *= scaleX; - keyPoints[finalIndex+1] *= scaleY; + keypoints[finalIndex] *= scaleX; + keypoints[finalIndex+1] *= scaleY; } } } @@ -48,18 +48,18 @@ namespace op } } - void scaleKeyPoints(Array& keyPoints, const float scaleX, const float scaleY, const float offsetX, const float offsetY) + void scaleKeypoints(Array& keypoints, const float scaleX, const float scaleY, const float offsetX, const float offsetY) { try { if (scaleX != 1. && scaleY != 1.) { // Error check - if (!keyPoints.empty() && keyPoints.getSize(2) != 3) + if (!keypoints.empty() && keypoints.getSize(2) != 3) error(errorMessage, __LINE__, __FUNCTION__, __FILE__); // Get #people and #parts - const auto numberPeople = keyPoints.getSize(0); - const auto numberParts = keyPoints.getSize(1); + const auto numberPeople = keypoints.getSize(0); + const auto numberParts = keypoints.getSize(1); // For each person for (auto person = 0 ; person < numberPeople ; person++) { @@ -67,8 +67,8 @@ namespace op for (auto part = 0 ; part < numberParts ; part++) { const auto finalIndex = 3*(person*numberParts + part); - keyPoints[finalIndex] = keyPoints[finalIndex] * scaleX + offsetX; - keyPoints[finalIndex+1] = keyPoints[finalIndex+1] * scaleY + offsetY; + keypoints[finalIndex] = keypoints[finalIndex] * scaleX + offsetX; + keypoints[finalIndex+1] = keypoints[finalIndex+1] * scaleY + offsetY; } } } diff --git a/src/openpose/experimental/face/defineTemplates.cpp b/src/openpose/experimental/face/defineTemplates.cpp deleted file mode 100644 index 2a90f6f2..00000000 --- a/src/openpose/experimental/face/defineTemplates.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -namespace op -{ - DEFINE_TEMPLATE_DATUM(experimental::WFaceExtractor); - DEFINE_TEMPLATE_DATUM(experimental::WFaceRenderer); -} diff --git a/src/openpose/experimental/face/faceExtractor.cpp b/src/openpose/experimental/face/faceExtractor.cpp deleted file mode 100644 index 7c416236..00000000 --- a/src/openpose/experimental/face/faceExtractor.cpp +++ /dev/null @@ -1,154 +0,0 @@ -#include // CV_WARP_INVERSE_MAP, CV_INTER_LINEAR -#include -#include -#include -#include -#include -#include -#include -#include -#include // For commented debugging section - -namespace op -{ - namespace experimental - { - FaceExtractor::FaceExtractor(const std::string& modelFolder, const int gpuId, const PoseModel poseModel) : - mNetOutputSize{368, 368}, - mOutputSize{1280, 720}, - mNeck{poseBodyPartMapStringToKey(poseModel, "Neck")}, - mNose{poseBodyPartMapStringToKey(poseModel, std::vector{"Nose", "Head"})}, - mLEar{poseBodyPartMapStringToKey(poseModel, std::vector{"LEar", "Head"})}, - mREar{poseBodyPartMapStringToKey(poseModel, std::vector{"REar", "Head"})}, - mLEye{poseBodyPartMapStringToKey(poseModel, std::vector{"LEye", "Head"})}, - mREye{poseBodyPartMapStringToKey(poseModel, std::vector{"REye", "Head"})}, - spNet{std::make_shared(std::array{1, 3, mNetOutputSize.height, mNetOutputSize.width}, modelFolder + FACE_PROTOTXT, modelFolder + FACE_TRAINED_MODEL, gpuId)}, - spResizeAndMergeCaffe{std::make_shared>()}, - spNmsCaffe{std::make_shared>()}, - mFaceImageCrop{mNetOutputSize.area()*3} - { - try - { -error("Hands and face extraction is not implemented yet. COMING SOON!", __LINE__, __FUNCTION__, __FILE__); - // Properties - for (auto& property : mProperties) - property = 0.; - mProperties[(int)FaceProperty::NMSThreshold] = FACE_DEFAULT_NMS_THRESHOLD; - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - - void FaceExtractor::initializationOnThread() - { - try - { - log("Starting initialization on thread.", Priority::Low, __LINE__, __FUNCTION__, __FILE__); - - // Get thread id - mThreadId = {std::this_thread::get_id()}; - - // Caffe net - spNet->initializationOnThread(); - spCaffeNetOutputBlob = ((NetCaffe*)spNet.get())->getOutputBlob(); - cudaCheck(__LINE__, __FUNCTION__, __FILE__); - - // HeatMaps extractor blob and layer - spHeatMapsBlob = {std::make_shared>(1,1,1,1)}; - const bool mergeFirstDimension = true; - spResizeAndMergeCaffe->Reshape({spCaffeNetOutputBlob.get()}, {spHeatMapsBlob.get()}, FACE_CCN_DECREASE_FACTOR, mergeFirstDimension); - cudaCheck(__LINE__, __FUNCTION__, __FILE__); - - // Pose extractor blob and layer - spPeaksBlob = {std::make_shared>(1,1,1,1)}; - spNmsCaffe->Reshape({spHeatMapsBlob.get()}, {spPeaksBlob.get()}, FACE_MAX_PEAKS, FACE_NUMBER_PARTS); - cudaCheck(__LINE__, __FUNCTION__, __FILE__); - - log("Finished initialization on thread.", Priority::Low, __LINE__, __FUNCTION__, __FILE__); - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - - void FaceExtractor::forwardPass(const Array& poseKeyPoints, const cv::Mat& cvInputData) - { - try - { -UNUSED(poseKeyPoints); -UNUSED(cvInputData); - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - - Array FaceExtractor::getFaceKeyPoints() const - { - try - { - checkThread(); - return mFaceKeyPoints; - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - return Array{}; - } - } - - double FaceExtractor::get(const FaceProperty property) const - { - try - { - return mProperties.at((int)property); - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - return 0.; - } - } - - void FaceExtractor::set(const FaceProperty property, const double value) - { - try - { - mProperties.at((int)property) = {value}; - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - - void FaceExtractor::increase(const FaceProperty property, const double value) - { - try - { - mProperties[(int)property] = mProperties.at((int)property) + value; - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - - void FaceExtractor::checkThread() const - { - try - { - if(mThreadId != std::this_thread::get_id()) - error("The CPU/GPU pointer data cannot be accessed from a different thread.", __LINE__, __FUNCTION__, __FILE__); - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - } -} diff --git a/src/openpose/experimental/face/faceRenderer.cpp b/src/openpose/experimental/face/faceRenderer.cpp deleted file mode 100644 index 44f6428b..00000000 --- a/src/openpose/experimental/face/faceRenderer.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -namespace op -{ - namespace experimental - { - FaceRenderer::FaceRenderer(const cv::Size& frameSize) : - Renderer{(unsigned long long)(frameSize.area() * 3)}, - mFrameSize{frameSize} - { - } - - FaceRenderer::~FaceRenderer() - { - try - { - // Free CUDA pointers - Note that if pointers are 0 (i.e. nullptr), no operation is performed. - cudaFree(pGpuFace); - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - - void FaceRenderer::initializationOnThread() - { - try - { - Renderer::initializationOnThread(); - cudaMalloc((void**)(&pGpuFace), FACE_NUMBER_PARTS * 3 * sizeof(float) ); - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - - void FaceRenderer::renderFace(Array& outputData, const Array& faceKeyPoints) - { - try - { - if (!faceKeyPoints.empty()) - { - cpuToGpuMemoryIfNotCopiedYet(outputData.getPtr()); - cudaMemcpy(pGpuFace, faceKeyPoints.getConstPtr(), FACE_NUMBER_PARTS*3 * sizeof(float), cudaMemcpyHostToDevice); - renderFaceGpu(*spGpuMemoryPtr, mFrameSize, pGpuFace, faceKeyPoints.getSize(0)); - cudaCheck(__LINE__, __FUNCTION__, __FILE__); - } - // GPU memory to CPU if last renderer - gpuToCpuMemoryIfLastRenderer(outputData.getPtr()); - cudaCheck(__LINE__, __FUNCTION__, __FILE__); - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - } -} diff --git a/src/openpose/experimental/filestream/defineTemplates.cpp b/src/openpose/experimental/filestream/defineTemplates.cpp index c5913845..7043ae99 100644 --- a/src/openpose/experimental/filestream/defineTemplates.cpp +++ b/src/openpose/experimental/filestream/defineTemplates.cpp @@ -2,5 +2,5 @@ namespace op { - DEFINE_TEMPLATE_DATUM(experimental::WPoseJsonCocoSaver); + DEFINE_TEMPLATE_DATUM(experimental::WCocoJsonSaver); } diff --git a/src/openpose/experimental/hand/handExtractor.cpp b/src/openpose/experimental/hand/handExtractor.cpp index a91dda83..738513c3 100644 --- a/src/openpose/experimental/hand/handExtractor.cpp +++ b/src/openpose/experimental/hand/handExtractor.cpp @@ -22,7 +22,7 @@ namespace op mLElbow{poseBodyPartMapStringToKey(poseModel, "LElbow")}, mNeck{poseBodyPartMapStringToKey(poseModel, "Neck")}, mHeadNose{poseBodyPartMapStringToKey(poseModel, std::vector{"Nose", "Head"})}, - spNet{std::make_shared(std::array{2, 3, mNetOutputSize.height, mNetOutputSize.width}, modelFolder + HAND_PROTOTXT, modelFolder + HAND_TRAINED_MODEL, gpuId)}, + spNet{std::make_shared(std::array{2, 3, mNetOutputSize.y, mNetOutputSize.x}, modelFolder + HAND_PROTOTXT, modelFolder + HAND_TRAINED_MODEL, gpuId)}, spResizeAndMergeCaffe{std::make_shared>()}, spNmsCaffe{std::make_shared>()}, mLeftHandCrop{mNetOutputSize.area()*3}, @@ -32,7 +32,7 @@ namespace op { try { -error("Hands and face extraction is not implemented yet. COMING SOON!", __LINE__, __FUNCTION__, __FILE__); +error("Hands extraction is not implemented yet. COMING SOON!", __LINE__, __FUNCTION__, __FILE__); // Properties for (auto& property : mProperties) property = 0.; @@ -66,7 +66,7 @@ error("Hands and face extraction is not implemented yet. COMING SOON!", __LINE__ // Pose extractor blob and layer spPeaksBlob = {std::make_shared>(1,1,1,1)}; - spNmsCaffe->Reshape({spHeatMapsBlob.get()}, {spPeaksBlob.get()}, HAND_MAX_PEAKS, HAND_NUMBER_PARTS); + spNmsCaffe->Reshape({spHeatMapsBlob.get()}, {spPeaksBlob.get()}, HAND_MAX_PEAKS, HAND_NUMBER_PARTS+1); cudaCheck(__LINE__, __FUNCTION__, __FILE__); log("Finished initialization on thread.", Priority::Low, __LINE__, __FUNCTION__, __FILE__); @@ -90,7 +90,7 @@ UNUSED(cvInputData); } } - Array HandExtractor::getHandKeyPoints() const + Array HandExtractor::getHandKeypoints() const { try { diff --git a/src/openpose/experimental/hand/handRenderGpu.cu b/src/openpose/experimental/hand/handRenderGpu.cu index 16fddde0..99922b67 100644 --- a/src/openpose/experimental/hand/handRenderGpu.cu +++ b/src/openpose/experimental/hand/handRenderGpu.cu @@ -7,7 +7,7 @@ namespace op { - __constant__ const unsigned char PART_PAIRS_GPU[] = HAND_PAIRS_TO_RENDER; + __constant__ const unsigned int PART_PAIRS_GPU[] = HAND_PAIRS_TO_RENDER; __constant__ const float RGB_COLORS[] = { 179.f, 0.f, 0.f, 204.f, 0.f, 0.f, @@ -45,9 +45,9 @@ namespace op const auto globalIdx = threadIdx.y * blockDim.x + threadIdx.x; // Shared parameters - __shared__ float2 sharedMins[HAND_MAX_NUMBER_HANDS]; - __shared__ float2 sharedMaxs[HAND_MAX_NUMBER_HANDS]; - __shared__ float sharedScaleF[HAND_MAX_NUMBER_HANDS]; + __shared__ float2 sharedMins[HAND_MAX_HANDS]; + __shared__ float2 sharedMaxs[HAND_MAX_HANDS]; + __shared__ float sharedScaleF[HAND_MAX_HANDS]; // Other parameters const auto numberPartPairs = sizeof(PART_PAIRS_GPU) / (2*sizeof(PART_PAIRS_GPU[0])); @@ -56,13 +56,13 @@ namespace op const auto stickwidth = fastMin(targetWidth, targetHeight) / 80.f; // Render key points - renderKeyPoints(targetPtr, sharedMaxs, sharedMins, sharedScaleF, + renderKeypoints(targetPtr, sharedMaxs, sharedMins, sharedScaleF, globalIdx, x, y, targetWidth, targetHeight, handsPtr, PART_PAIRS_GPU, numberHands, HAND_NUMBER_PARTS, numberPartPairs, RGB_COLORS, numberColors, radius, stickwidth, threshold, alphaColorToAdd); } - void renderHandsGpu(float* framePtr, const cv::Size& frameSize, const float* const handsPtr, const int numberHands, const float alphaColorToAdd) + void renderHandsGpu(float* framePtr, const Point& frameSize, const float* const handsPtr, const int numberHands, const float alphaColorToAdd) { try { @@ -72,7 +72,7 @@ namespace op dim3 threadsPerBlock; dim3 numBlocks; std::tie(threadsPerBlock, numBlocks) = getNumberCudaThreadsAndBlocks(frameSize); - renderHandsParts<<>>(framePtr, frameSize.width, frameSize.height, handsPtr, numberHands, threshold, alphaColorToAdd); + renderHandsParts<<>>(framePtr, frameSize.x, frameSize.y, handsPtr, numberHands, threshold, alphaColorToAdd); cudaCheck(__LINE__, __FUNCTION__, __FILE__); } } diff --git a/src/openpose/experimental/hand/handRenderer.cpp b/src/openpose/experimental/hand/handRenderer.cpp index 07c5de1b..1a30e284 100644 --- a/src/openpose/experimental/hand/handRenderer.cpp +++ b/src/openpose/experimental/hand/handRenderer.cpp @@ -10,8 +10,8 @@ namespace op { namespace experimental { - HandRenderer::HandRenderer(const cv::Size& frameSize) : - Renderer{(unsigned long long)(frameSize.area() * 3)}, + HandRenderer::HandRenderer(const Point& frameSize) : + Renderer{(unsigned long long)(frameSize.area() * 3), HAND_DEFAULT_ALPHA_KEYPOINT, HAND_DEFAULT_ALPHA_HEAT_MAP}, mFrameSize{frameSize} { } @@ -34,7 +34,7 @@ namespace op try { Renderer::initializationOnThread(); - cudaMalloc((void**)(&pGpuHands), 2*HAND_NUMBER_PARTS * 3 * sizeof(float) ); + cudaMalloc((void**)(&pGpuHands), 2*HAND_NUMBER_PARTS * 3 * sizeof(float)); } catch (const std::exception& e) { @@ -42,15 +42,20 @@ namespace op } } - void HandRenderer::renderHands(Array& outputData, const Array& handKeyPoints) + void HandRenderer::renderHands(Array& outputData, const Array& handKeypoints) { try { - if (!handKeyPoints.empty()) + const auto elementRendered = spElementToRender->load(); // I prefer std::round(T&) over intRound(T) for std::atomic + const auto numberPeople = handKeypoints.getSize(0); + // GPU rendering + if (numberPeople > 0 && elementRendered == 0) { cpuToGpuMemoryIfNotCopiedYet(outputData.getPtr()); - cudaMemcpy(pGpuHands, handKeyPoints.getConstPtr(), 2*HAND_NUMBER_PARTS*3 * sizeof(float), cudaMemcpyHostToDevice); - renderHandsGpu(*spGpuMemoryPtr, mFrameSize, pGpuHands, handKeyPoints.getSize(0)); + // Draw faceKeypoints + cudaMemcpy(pGpuHands, handKeypoints.getConstPtr(), 2*HAND_NUMBER_PARTS*3 * sizeof(float), cudaMemcpyHostToDevice); + renderHandsGpu(*spGpuMemoryPtr, mFrameSize, pGpuHands, handKeypoints.getSize(0)); + // CUDA check cudaCheck(__LINE__, __FUNCTION__, __FILE__); } // GPU memory to CPU if last renderer diff --git a/src/openpose/face/defineTemplates.cpp b/src/openpose/face/defineTemplates.cpp new file mode 100644 index 00000000..48b1c4e9 --- /dev/null +++ b/src/openpose/face/defineTemplates.cpp @@ -0,0 +1,8 @@ +#include + +namespace op +{ + DEFINE_TEMPLATE_DATUM(WFaceDetector); + DEFINE_TEMPLATE_DATUM(WFaceExtractor); + DEFINE_TEMPLATE_DATUM(WFaceRenderer); +} diff --git a/src/openpose/face/faceDetector.cpp b/src/openpose/face/faceDetector.cpp new file mode 100644 index 00000000..68e749d2 --- /dev/null +++ b/src/openpose/face/faceDetector.cpp @@ -0,0 +1,147 @@ +#include // CV_WARP_INVERSE_MAP, CV_INTER_LINEAR +#include +#include +#include +#include + +namespace op +{ + FaceDetector::FaceDetector(const PoseModel poseModel) : + mNeck{poseBodyPartMapStringToKey(poseModel, "Neck")}, + mNose{poseBodyPartMapStringToKey(poseModel, std::vector{"Nose", "Head"})}, + mLEar{poseBodyPartMapStringToKey(poseModel, std::vector{"LEar", "Head"})}, + mREar{poseBodyPartMapStringToKey(poseModel, std::vector{"REar", "Head"})}, + mLEye{poseBodyPartMapStringToKey(poseModel, std::vector{"LEye", "Head"})}, + mREye{poseBodyPartMapStringToKey(poseModel, std::vector{"REye", "Head"})} + { + } + + float getDistance(const float* posePtr, const int elementA, const int elementB) + { + try + { + const auto pixelX = posePtr[elementA*3] - posePtr[elementB*3]; + const auto pixelY = posePtr[elementA*3+1] - posePtr[elementB*3+1]; + return std::sqrt(pixelX*pixelX+pixelY*pixelY); + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return -1.f; + } + } + + inline Rectangle getFaceFromPoseKeypoints(const Array& poseKeypoints, const unsigned int personIndex, const unsigned int neck, + const unsigned int nose, const unsigned int lEar, const unsigned int rEar, + const unsigned int lEye, const unsigned int rEye, const float threshold) + { + try + { + Point pointTopLeft{0.f, 0.f}; + auto faceSize = 0.f; + + const auto* posePtr = &poseKeypoints.at(personIndex*poseKeypoints.getSize(1)*poseKeypoints.getSize(2)); + const auto neckScoreAbove = (posePtr[neck*3+2] > threshold); + const auto noseScoreAbove = (posePtr[nose*3+2] > threshold); + const auto lEarScoreAbove = (posePtr[lEar*3+2] > threshold); + const auto rEarScoreAbove = (posePtr[rEar*3+2] > threshold); + const auto lEyeScoreAbove = (posePtr[lEye*3+2] > threshold); + const auto rEyeScoreAbove = (posePtr[rEye*3+2] > threshold); + + auto counter = 0; + // Face and neck given (e.g. MPI) + if (nose == lEar && lEar == rEar) + { + if (neckScoreAbove && noseScoreAbove) + { + pointTopLeft.x = posePtr[nose*3]; + pointTopLeft.y = posePtr[nose*3+1]; + faceSize = 1.33f * getDistance(posePtr, neck, nose); + } + } + // Face as average between different body keypoints (e.g. COCO) + else + { + // factor * dist(neck, nose) + if (neckScoreAbove && noseScoreAbove) + { + // If profile (i.e. only 1 eye and ear visible) --> avg(nose, eye & ear position) + if ((lEyeScoreAbove) == (lEarScoreAbove) + && (rEyeScoreAbove) == (rEarScoreAbove) + && (lEyeScoreAbove) != (rEyeScoreAbove)) + { + if (lEyeScoreAbove) + { + pointTopLeft.x += (posePtr[lEye*3] + posePtr[lEar*3] + posePtr[nose*3]) / 3.f; + pointTopLeft.y += (posePtr[lEye*3+1] + posePtr[lEar*3+1] + posePtr[nose*3+1]) / 3.f; + faceSize += 0.85 * (getDistance(posePtr, nose, lEye) + getDistance(posePtr, nose, lEar) + getDistance(posePtr, neck, nose)); + } + else // if(lEyeScoreAbove) + { + pointTopLeft.x += (posePtr[rEye*3] + posePtr[rEar*3] + posePtr[nose*3]) / 3.f; + pointTopLeft.y += (posePtr[rEye*3+1] + posePtr[rEar*3+1] + posePtr[nose*3+1]) / 3.f; + faceSize += 0.85 * (getDistance(posePtr, nose, rEye) + getDistance(posePtr, nose, rEar) + getDistance(posePtr, neck, nose)); + } + } + // else --> 2 * dist(neck, nose) + else + { + pointTopLeft.x += (posePtr[neck*3] + posePtr[nose*3]) / 2.f; + pointTopLeft.y += (posePtr[neck*3+1] + posePtr[nose*3+1]) / 2.f; + faceSize += 2.f * getDistance(posePtr, neck, nose); + } + counter++; + } + // 3 * dist(lEye, rEye) + if (lEyeScoreAbove && rEyeScoreAbove) + { + pointTopLeft.x += (posePtr[lEye*3] + posePtr[rEye*3]) / 2.f; + pointTopLeft.y += (posePtr[lEye*3+1] + posePtr[rEye*3+1]) / 2.f; + faceSize += 3.f * getDistance(posePtr, lEye, rEye); + counter++; + } + // 2 * dist(lEar, rEar) + if (lEarScoreAbove && rEarScoreAbove) + { + pointTopLeft.x += (posePtr[lEar*3] + posePtr[rEar*3]) / 2.f; + pointTopLeft.y += (posePtr[lEar*3+1] + posePtr[rEar*3+1]) / 2.f; + faceSize += 2.f * getDistance(posePtr, lEar, rEar); + counter++; + } + // Average (if counter > 0) + if (counter > 0) + { + pointTopLeft /= (float)counter; + faceSize /= counter; + } + } + return Rectangle{pointTopLeft.x - faceSize / 2, pointTopLeft.y - faceSize / 2, faceSize, faceSize}; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return Rectangle{}; + } + } + + std::vector> FaceDetector::detectFaces(const Array& poseKeypoints) + { + try + { + const auto numberPeople = poseKeypoints.getSize(0); + std::vector> faceRectangles(numberPeople); + const auto threshold = 0.25f; + // If no poseKeypoints detected -> no way to detect face location + // Otherwise, get face position(s) + if (!poseKeypoints.empty()) + for (auto person = 0 ; person < numberPeople ; person++) + faceRectangles.at(person) = getFaceFromPoseKeypoints(poseKeypoints, person, mNeck, mNose, mLEar, mREar, mLEye, mREye, threshold); + return faceRectangles; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return {}; + } + } +} diff --git a/src/openpose/face/faceExtractor.cpp b/src/openpose/face/faceExtractor.cpp new file mode 100644 index 00000000..6996e397 --- /dev/null +++ b/src/openpose/face/faceExtractor.cpp @@ -0,0 +1,244 @@ +#include // CV_WARP_INVERSE_MAP, CV_INTER_LINEAR +#include +#include +#include +#include +#include +#include +#include +#include + +namespace op +{ + FaceExtractor::FaceExtractor(const Point& netInputSize, const Point& netOutputSize, const std::string& modelFolder, const int gpuId) : + mNetOutputSize{netOutputSize}, + spNet{std::make_shared(std::array{1, 3, mNetOutputSize.y, mNetOutputSize.x}, modelFolder + FACE_PROTOTXT, modelFolder + FACE_TRAINED_MODEL, gpuId)}, + spResizeAndMergeCaffe{std::make_shared>()}, + spNmsCaffe{std::make_shared>()}, + mFaceImageCrop{mNetOutputSize.area()*3} + { + try + { + checkE(netOutputSize, netInputSize, "Net input and output size must be equal.", __LINE__, __FUNCTION__, __FILE__); + // Properties + for (auto& property : mProperties) + property = 0.; + mProperties[(int)FaceProperty::NMSThreshold] = FACE_DEFAULT_NMS_THRESHOLD; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + void FaceExtractor::initializationOnThread() + { + try + { + log("Starting initialization on thread.", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + + // Get thread id + mThreadId = {std::this_thread::get_id()}; + + // Caffe net + spNet->initializationOnThread(); + spCaffeNetOutputBlob = ((NetCaffe*)spNet.get())->getOutputBlob(); + cudaCheck(__LINE__, __FUNCTION__, __FILE__); + + // HeatMaps extractor blob and layer + spHeatMapsBlob = {std::make_shared>(1,1,1,1)}; + const bool mergeFirstDimension = true; + spResizeAndMergeCaffe->Reshape({spCaffeNetOutputBlob.get()}, {spHeatMapsBlob.get()}, FACE_CCN_DECREASE_FACTOR, mergeFirstDimension); + cudaCheck(__LINE__, __FUNCTION__, __FILE__); + + // Pose extractor blob and layer + spPeaksBlob = {std::make_shared>(1,1,1,1)}; + spNmsCaffe->Reshape({spHeatMapsBlob.get()}, {spPeaksBlob.get()}, FACE_MAX_PEAKS, FACE_NUMBER_PARTS+1); + cudaCheck(__LINE__, __FUNCTION__, __FILE__); + + log("Finished initialization on thread.", Priority::Low, __LINE__, __FUNCTION__, __FILE__); + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + void FaceExtractor::forwardPass(const std::vector>& faceRectangles, const cv::Mat& cvInputData) + { + try + { + if (!faceRectangles.empty()) + { + // Security checks + if (cvInputData.empty()) + error("Empty cvInputData.", __LINE__, __FUNCTION__, __FILE__); + + // Set face size + const auto numberPeople = (int)faceRectangles.size(); + mFaceKeypoints.reset({numberPeople, FACE_NUMBER_PARTS, 3}, 0); + +// log("\nAreas:"); +// cv::Mat cvInputDataCopy = cvInputData.clone(); + for (auto person = 0 ; person < numberPeople ; person++) + { + // Only consider faces with a minimum pixel area + const auto faceAreaSquared = std::sqrt(faceRectangles.at(person).area()); + // Get parts + if (faceAreaSquared > 60) + { + const auto& faceRectangle = faceRectangles.at(person); +// log(faceAreaSquared); +// cv::rectangle(cvInputDataCopy, +// cv::Point{(int)faceRectangle.x, (int)faceRectangle.y}, +// // cv::Point{(int)(faceRectangle.x + faceRectangle.width), (int)(faceRectangle.y + faceRectangle.height)}, +// cv::Point{(int)faceRectangle.bottomRight().x, (int)faceRectangle.bottomRight().y}, +// cv::Scalar{255,0,255}, 2); + // Get face position(s) + const Point faceCenterPosition{faceRectangle.topLeft()}; + const auto faceSize = fastMax(faceRectangle.width, faceRectangle.height); + + // Resize and shift image to face rectangle positions + const double scaleFace = faceSize / (double)fastMin(mNetOutputSize.x, mNetOutputSize.y); + cv::Mat Mscaling = cv::Mat::eye(2, 3, CV_64F); + Mscaling.at(0,0) = scaleFace; + Mscaling.at(1,1) = scaleFace; + Mscaling.at(0,2) = faceCenterPosition.x; + Mscaling.at(1,2) = faceCenterPosition.y; + + cv::Mat faceImage; + cv::warpAffine(cvInputData, faceImage, Mscaling, cv::Size{mNetOutputSize.x, mNetOutputSize.y}, CV_INTER_LINEAR | CV_WARP_INVERSE_MAP, cv::BORDER_CONSTANT, cv::Scalar(0,0,0)); + + // cv::Mat -> float* + uCharCvMatToFloatPtr(mFaceImageCrop.getPtr(), faceImage, true); + // 1. Caffe deep network + auto* inputDataGpuPtr = spNet->getInputDataGpuPtr(); + cudaMemcpy(inputDataGpuPtr, mFaceImageCrop.getPtr(), mNetOutputSize.area() * 3 * sizeof(float), cudaMemcpyHostToDevice); + spNet->forwardPass(); + + // 2. Resize heat maps + merge different scales + #ifndef CPU_ONLY + spResizeAndMergeCaffe->Forward_gpu({spCaffeNetOutputBlob.get()}, {spHeatMapsBlob.get()}); + cudaCheck(__LINE__, __FUNCTION__, __FILE__); + #else + spResizeAndMergeCaffe->Forward_cpu({spCaffeNetOutputBlob.get()}, {spHeatMapsBlob.get()}); + #endif + + // 3. Get peaks by Non-Maximum Suppression + spNmsCaffe->setThreshold(get(FaceProperty::NMSThreshold)); + #ifndef CPU_ONLY + spNmsCaffe->Forward_gpu({spHeatMapsBlob.get()}, {spPeaksBlob.get()}); + cudaCheck(__LINE__, __FUNCTION__, __FILE__); + #else + spNmsCaffe->Forward_cpu({spHeatMapsBlob.get()}, {spPeaksBlob.get()}); + #endif + + const auto* facePeaksPtr = spPeaksBlob->mutable_cpu_data(); + const auto facePeaksOffset = (FACE_MAX_PEAKS+1) * 3; + + for (auto part = 0 ; part < FACE_NUMBER_PARTS ; part++) + { + // Get max peak + const int numPeaks = intRound(facePeaksPtr[facePeaksOffset*part]); + auto maxScore = -1.f; + auto maxPeak = -1; + for (auto peak = 0 ; peak < numPeaks ; peak++) + { + const auto xyIndex = facePeaksOffset * part + (1 + peak) * 3; + const auto score = facePeaksPtr[xyIndex + 2]; + if (score > maxScore) + { + maxScore = score; + maxPeak = peak; + } + } + // Fill face keypoints + if (maxPeak >= 0) + { + const auto xyIndex = facePeaksOffset * part + (1 + maxPeak) * 3; + const auto x = facePeaksPtr[xyIndex]; + const auto y = facePeaksPtr[xyIndex + 1]; + const auto score = facePeaksPtr[xyIndex + 2]; + const auto baseIndex = (person * FACE_NUMBER_PARTS + part) * 3; + mFaceKeypoints[baseIndex] = Mscaling.at(0,0) * x + Mscaling.at(0,1) * y + Mscaling.at(0,2); + mFaceKeypoints[baseIndex+1] = Mscaling.at(1,0) * x + Mscaling.at(1,1) * y + Mscaling.at(1,2); + mFaceKeypoints[baseIndex+2] = score; + } + } + } + } +// cv::imshow("AcvInputDataCopy", cvInputDataCopy); + } + else + mFaceKeypoints.reset(); + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + Array FaceExtractor::getFaceKeypoints() const + { + try + { + checkThread(); + return mFaceKeypoints; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return Array{}; + } + } + + double FaceExtractor::get(const FaceProperty property) const + { + try + { + return mProperties.at((int)property); + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + return 0.; + } + } + + void FaceExtractor::set(const FaceProperty property, const double value) + { + try + { + mProperties.at((int)property) = {value}; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + void FaceExtractor::increase(const FaceProperty property, const double value) + { + try + { + mProperties[(int)property] = mProperties.at((int)property) + value; + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + void FaceExtractor::checkThread() const + { + try + { + if(mThreadId != std::this_thread::get_id()) + error("The CPU/GPU pointer data cannot be accessed from a different thread.", __LINE__, __FUNCTION__, __FILE__); + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } +} diff --git a/src/openpose/experimental/face/faceRenderGpu.cu b/src/openpose/face/faceRenderGpu.cu similarity index 72% rename from src/openpose/experimental/face/faceRenderGpu.cu rename to src/openpose/face/faceRenderGpu.cu index bc14bf39..b8d66d75 100644 --- a/src/openpose/experimental/face/faceRenderGpu.cu +++ b/src/openpose/face/faceRenderGpu.cu @@ -1,14 +1,14 @@ -#include +#include #include #include #include #include -#include +#include namespace op { const dim3 THREADS_PER_BLOCK{128, 128, 1}; - __constant__ const unsigned char PART_PAIRS_GPU[] = FACE_PAIRS_TO_RENDER; + __constant__ const unsigned int PART_PAIRS_GPU[] = FACE_PAIRS_TO_RENDER; __constant__ const float RGB_COLORS[] = { 255.f, 255.f, 255.f, }; @@ -23,9 +23,9 @@ namespace op const auto globalIdx = threadIdx.y * blockDim.x + threadIdx.x; // Shared parameters - __shared__ float2 sharedMins[FACE_MAX_NUMBER_FACE]; - __shared__ float2 sharedMaxs[FACE_MAX_NUMBER_FACE]; - __shared__ float sharedScaleF[FACE_MAX_NUMBER_FACE]; + __shared__ float2 sharedMins[FACE_MAX_FACES]; + __shared__ float2 sharedMaxs[FACE_MAX_FACES]; + __shared__ float sharedScaleF[FACE_MAX_FACES]; // Other parameters const auto numberPartPairs = sizeof(PART_PAIRS_GPU) / (2*sizeof(PART_PAIRS_GPU[0])); @@ -34,21 +34,21 @@ namespace op const auto stickwidth = fastMin(targetWidth, targetHeight) / 250.f; // Render key points - renderKeyPoints(targetPtr, sharedMaxs, sharedMins, sharedScaleF, + renderKeypoints(targetPtr, sharedMaxs, sharedMins, sharedScaleF, globalIdx, x, y, targetWidth, targetHeight, facePtr, PART_PAIRS_GPU, numberFaces, FACE_NUMBER_PARTS, numberPartPairs, RGB_COLORS, numberColors, radius, stickwidth, threshold, alphaColorToAdd); } - void renderFaceGpu(float* framePtr, const cv::Size& frameSize, const float* const facePtr, const int numberFaces, const float alphaColorToAdd) + void renderFaceGpu(float* framePtr, const Point& frameSize, const float* const facePtr, const int numberFaces, const float alphaColorToAdd) { try { if (numberFaces > 0) { - const auto threshold = 0.5f; + const auto threshold = 0.4f; const auto numBlocks = getNumberCudaBlocks(frameSize, THREADS_PER_BLOCK); - renderFaceParts<<>>(framePtr, frameSize.width, frameSize.height, facePtr, numberFaces, threshold, alphaColorToAdd); + renderFaceParts<<>>(framePtr, frameSize.x, frameSize.y, facePtr, numberFaces, threshold, alphaColorToAdd); cudaCheck(__LINE__, __FUNCTION__, __FILE__); } } diff --git a/src/openpose/face/faceRenderer.cpp b/src/openpose/face/faceRenderer.cpp new file mode 100644 index 00000000..48689d86 --- /dev/null +++ b/src/openpose/face/faceRenderer.cpp @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include +#include +#include + +namespace op +{ + FaceRenderer::FaceRenderer(const Point& frameSize, const float alphaKeypoint, const float alphaHeatMap) : + Renderer{(unsigned long long)(frameSize.area() * 3), alphaKeypoint, alphaHeatMap}, + mFrameSize{frameSize} + { + } + + FaceRenderer::~FaceRenderer() + { + try + { + // Free CUDA pointers - Note that if pointers are 0 (i.e. nullptr), no operation is performed. + cudaFree(pGpuFace); + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + void FaceRenderer::initializationOnThread() + { + try + { + Renderer::initializationOnThread(); + cudaMalloc((void**)(&pGpuFace), POSE_MAX_PEOPLE * FACE_NUMBER_PARTS * 3 * sizeof(float)); + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } + + void FaceRenderer::renderFace(Array& outputData, const Array& faceKeypoints) + { + try + { + const auto elementRendered = spElementToRender->load(); // I prefer std::round(T&) over intRound(T) for std::atomic + const auto numberPeople = faceKeypoints.getSize(0); + // GPU rendering + if (numberPeople > 0 && elementRendered == 0) + { + cpuToGpuMemoryIfNotCopiedYet(outputData.getPtr()); + // Draw faceKeypoints + cudaMemcpy(pGpuFace, faceKeypoints.getConstPtr(), faceKeypoints.getSize(0) * FACE_NUMBER_PARTS * 3 * sizeof(float), cudaMemcpyHostToDevice); + renderFaceGpu(*spGpuMemoryPtr, mFrameSize, pGpuFace, faceKeypoints.getSize(0), getAlphaKeypoint()); + // CUDA check + cudaCheck(__LINE__, __FUNCTION__, __FILE__); + } + // GPU memory to CPU if last renderer + gpuToCpuMemoryIfLastRenderer(outputData.getPtr()); + cudaCheck(__LINE__, __FUNCTION__, __FILE__); + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } +} diff --git a/src/openpose/filestream/poseJsonCocoSaver.cpp b/src/openpose/filestream/cocoJsonSaver.cpp similarity index 80% rename from src/openpose/filestream/poseJsonCocoSaver.cpp rename to src/openpose/filestream/cocoJsonSaver.cpp index ea267e5e..f36f379f 100644 --- a/src/openpose/filestream/poseJsonCocoSaver.cpp +++ b/src/openpose/filestream/cocoJsonSaver.cpp @@ -1,9 +1,9 @@ #include -#include +#include namespace op { - PoseJsonCocoSaver::PoseJsonCocoSaver(const std::string& filePathToSave, const bool humanReadable) : + CocoJsonSaver::CocoJsonSaver(const std::string& filePathToSave, const bool humanReadable) : mJsonOfstream{filePathToSave, humanReadable}, mFirstElementAdded{false} { @@ -16,7 +16,7 @@ namespace op error(e.what(), __LINE__, __FUNCTION__, __FILE__); } } - PoseJsonCocoSaver::~PoseJsonCocoSaver() + CocoJsonSaver::~CocoJsonSaver() { try { @@ -28,12 +28,12 @@ namespace op } } - void PoseJsonCocoSaver::record(const Array& poseKeyPoints, const unsigned long long imageId) + void CocoJsonSaver::record(const Array& poseKeypoints, const unsigned long long imageId) { try { - const auto numberPeople = poseKeyPoints.getSize(0); - const auto numberBodyParts = poseKeyPoints.getSize(1); + const auto numberPeople = poseKeypoints.getSize(0); + const auto numberBodyParts = poseKeypoints.getSize(1); for (auto person = 0 ; person < numberPeople ; person++) { // Comma at any moment but first element @@ -58,16 +58,16 @@ namespace op mJsonOfstream.plainText("1"); mJsonOfstream.comma(); - // keypoints - i.e. poseKeyPoints + // keypoints - i.e. poseKeypoints mJsonOfstream.key("keypoints"); mJsonOfstream.arrayOpen(); const std::vector indexesInCocoOrder{0, 15, 14, 17, 16, 5, 2, 6, 3, 7, 4, 11, 8, 12, 9, 13, 10}; for (auto bodyPart = 0 ; bodyPart < indexesInCocoOrder.size() ; bodyPart++) { const auto finalIndex = 3*(person*numberBodyParts + indexesInCocoOrder.at(bodyPart)); - mJsonOfstream.plainText(poseKeyPoints[finalIndex]); + mJsonOfstream.plainText(poseKeypoints[finalIndex]); mJsonOfstream.comma(); - mJsonOfstream.plainText(poseKeyPoints[finalIndex+1]); + mJsonOfstream.plainText(poseKeypoints[finalIndex+1]); mJsonOfstream.comma(); mJsonOfstream.plainText(1); if (bodyPart < numberBodyParts-1) diff --git a/src/openpose/filestream/defineTemplates.cpp b/src/openpose/filestream/defineTemplates.cpp index e3fb15ed..2bc4b75d 100644 --- a/src/openpose/filestream/defineTemplates.cpp +++ b/src/openpose/filestream/defineTemplates.cpp @@ -2,8 +2,12 @@ namespace op { - DEFINE_TEMPLATE_DATUM(WImageSaver); + DEFINE_TEMPLATE_DATUM(WFaceJsonSaver); + DEFINE_TEMPLATE_DATUM(WFaceSaver); + DEFINE_TEMPLATE_DATUM(WHandJsonSaver); + DEFINE_TEMPLATE_DATUM(WHandSaver); DEFINE_TEMPLATE_DATUM(WHeatMapSaver); + DEFINE_TEMPLATE_DATUM(WImageSaver); DEFINE_TEMPLATE_DATUM(WPoseJsonSaver); DEFINE_TEMPLATE_DATUM(WPoseSaver); DEFINE_TEMPLATE_DATUM(WVideoSaver); diff --git a/src/openpose/filestream/poseJsonSaver.cpp b/src/openpose/filestream/keypointJsonSaver.cpp similarity index 57% rename from src/openpose/filestream/poseJsonSaver.cpp rename to src/openpose/filestream/keypointJsonSaver.cpp index bf58058e..63f4b9cd 100644 --- a/src/openpose/filestream/poseJsonSaver.cpp +++ b/src/openpose/filestream/keypointJsonSaver.cpp @@ -1,29 +1,29 @@ #include #include -#include +#include namespace op { - PoseJsonSaver::PoseJsonSaver(const std::string& directoryPath) : + KeypointJsonSaver::KeypointJsonSaver(const std::string& directoryPath) : FileSaver{directoryPath} { } - void PoseJsonSaver::savePoseKeyPoints(const std::vector>& poseKeyPointsVector, const std::string& fileName) const + void KeypointJsonSaver::saveKeypoints(const std::vector>& keypointVector, const std::string& fileName, const std::string& keypointName) const { try { // Record json - if (!poseKeyPointsVector.empty()) + if (!keypointVector.empty()) { // File path (no extension) - const auto fileNameNoExtension = getNextFileName(fileName) + "_pose"; + const auto fileNameNoExtension = getNextFileName(fileName) + "_" + keypointName; const bool humanReadable = true; - for (auto i = 0; i < poseKeyPointsVector.size(); i++) + for (auto i = 0; i < keypointVector.size(); i++) { const auto finalFileName = fileNameNoExtension + (i != 0 ? "_" + std::to_string(i) : "") + ".json"; - savePoseJson(poseKeyPointsVector[i], finalFileName, humanReadable); + savePoseJson(keypointVector[i], finalFileName, humanReadable); } } } diff --git a/src/openpose/filestream/keypointSaver.cpp b/src/openpose/filestream/keypointSaver.cpp new file mode 100644 index 00000000..eeb499fe --- /dev/null +++ b/src/openpose/filestream/keypointSaver.cpp @@ -0,0 +1,41 @@ +#include +#include +#include + +namespace op +{ + KeypointSaver::KeypointSaver(const std::string& directoryPath, const DataFormat format) : + FileSaver{directoryPath}, + mFormat{format} + { + } + + void KeypointSaver::saveKeypoints(const std::vector>& keypointVector, const std::string& fileName, const std::string& keypointName) const + { + try + { + if (!keypointVector.empty()) + { + // File path (no extension) + const auto fileNameNoExtension = getNextFileName(fileName) + "_" + keypointName; + + // Get vector of people poses + std::vector cvMatPoses(keypointVector.size()); + for (auto i = 0; i < keypointVector.size(); i++) + cvMatPoses[i] = keypointVector[i].getConstCvMat(); + + // Get names inside file + std::vector keypointVectorNames(cvMatPoses.size()); + for (auto i = 0; i < cvMatPoses.size(); i++) + keypointVectorNames[i] = {keypointName + "_" + std::to_string(i)}; + + // Record people poses in desired format + saveData(cvMatPoses, keypointVectorNames, fileNameNoExtension, mFormat); + } + } + catch (const std::exception& e) + { + error(e.what(), __LINE__, __FUNCTION__, __FILE__); + } + } +} diff --git a/src/openpose/filestream/poseSaver.cpp b/src/openpose/filestream/poseSaver.cpp deleted file mode 100644 index e9bb87f6..00000000 --- a/src/openpose/filestream/poseSaver.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include -#include -#include - -namespace op -{ - PoseSaver::PoseSaver(const std::string& directoryPath, const DataFormat format) : - FileSaver{directoryPath}, - mFormat{format} - { - } - - void PoseSaver::savePoseKeyPoints(const std::vector>& poseKeyPointsVector, const std::string& fileName) const - { - try - { - if (!poseKeyPointsVector.empty()) - { - // File path (no extension) - const auto fileNameNoExtension = getNextFileName(fileName) + "_pose"; - - // Get vector of people poses - std::vector cvMatPoses(poseKeyPointsVector.size()); - for (auto i = 0; i < poseKeyPointsVector.size(); i++) - cvMatPoses[i] = poseKeyPointsVector[i].getConstCvMat(); - - // Get names inside file - std::vector poseKeyPointsVectorNames(cvMatPoses.size()); - for (auto i = 0; i < cvMatPoses.size(); i++) - poseKeyPointsVectorNames[i] = {"pose_" + std::to_string(i)}; - - // Record people poses in desired format - saveData(cvMatPoses, poseKeyPointsVectorNames, fileNameNoExtension, mFormat); - } - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } -} diff --git a/src/openpose/filestream/videoSaver.cpp b/src/openpose/filestream/videoSaver.cpp index 9db10f38..3fa27e8f 100644 --- a/src/openpose/filestream/videoSaver.cpp +++ b/src/openpose/filestream/videoSaver.cpp @@ -3,16 +3,16 @@ namespace op { - VideoSaver::VideoSaver(const std::string& videoSaverPath, const int cvFourcc, const double fps, const cv::Size& cvSize) : + VideoSaver::VideoSaver(const std::string& videoSaverPath, const int cvFourcc, const double fps, const Point& cvSize) : VideoSaver::VideoSaver{std::vector{videoSaverPath}, cvFourcc, fps, cvSize} { } - VideoSaver::VideoSaver(const std::vector& videoSaverPaths, const int cvFourcc, const double fps, const cv::Size& cvSize) + VideoSaver::VideoSaver(const std::vector& videoSaverPaths, const int cvFourcc, const double fps, const Point& cvSize) { try { - if (cvSize.width <= 0 || cvSize.height <= 0) + if (cvSize.x <= 0 || cvSize.y <= 0) error("Desired frame size to save frames is <= 0.", __LINE__, __FUNCTION__, __FILE__); if (fps <= 0.) @@ -20,7 +20,7 @@ namespace op for (const auto& videoSaverPath : videoSaverPaths) { - mVideoWriters.emplace_back(videoSaverPath, cvFourcc, fps, cvSize); + mVideoWriters.emplace_back(videoSaverPath, cvFourcc, fps, cv::Size{cvSize.x, cvSize.y}); if (!mVideoWriters.crbegin()->isOpened()) { diff --git a/src/openpose/gui/frameDisplayer.cpp b/src/openpose/gui/frameDisplayer.cpp index bac91669..1b3992a7 100644 --- a/src/openpose/gui/frameDisplayer.cpp +++ b/src/openpose/gui/frameDisplayer.cpp @@ -4,7 +4,7 @@ namespace op { - FrameDisplayer::FrameDisplayer(const cv::Size& windowedSize, const std::string& windowedName, const bool fullScreen) : + FrameDisplayer::FrameDisplayer(const Point& windowedSize, const std::string& windowedName, const bool fullScreen) : mWindowedSize{windowedSize}, mWindowName{windowedName}, mGuiDisplayMode{(fullScreen ? GuiDisplayMode::FullScreen : GuiDisplayMode::Windowed)} @@ -17,7 +17,7 @@ namespace op { setGuiDisplayMode(mGuiDisplayMode); - const cv::Mat blackFrame{mWindowedSize.height, mWindowedSize.width, CV_32FC3, {0,0,0}}; + const cv::Mat blackFrame{mWindowedSize.y, mWindowedSize.x, CV_32FC3, {0,0,0}}; FrameDisplayer::displayFrame(blackFrame); cv::waitKey(1); // This one will show most probably a white image (I guess the program does not have time to render in 1 msec) // cv::waitKey(1000); // This one will show the desired black image @@ -40,7 +40,7 @@ namespace op cv::setWindowProperty(mWindowName, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN); else if (mGuiDisplayMode == GuiDisplayMode::Windowed) { - cv::resizeWindow(mWindowName, mWindowedSize.width, mWindowedSize.height); + cv::resizeWindow(mWindowName, mWindowedSize.x, mWindowedSize.y); cv::setWindowProperty(mWindowName, CV_WND_PROP_FULLSCREEN, CV_WINDOW_NORMAL); } else diff --git a/src/openpose/gui/gui.cpp b/src/openpose/gui/gui.cpp index 400945e7..e236b440 100644 --- a/src/openpose/gui/gui.cpp +++ b/src/openpose/gui/gui.cpp @@ -17,7 +17,7 @@ namespace op if (!helpCvMat.empty()) { const auto fullScreen = false; - FrameDisplayer frameDisplayer{helpCvMat.size(), "OpenPose - GUI Help", fullScreen}; + FrameDisplayer frameDisplayer{Point{helpCvMat.cols, helpCvMat.rows}, "OpenPose - GUI Help", fullScreen}; frameDisplayer.displayFrame(helpCvMat, 33); } } @@ -149,7 +149,7 @@ namespace op } } - Gui::Gui(const bool fullScreen, const cv::Size& outputSize, const std::shared_ptr>& isRunningSharedPtr, + Gui::Gui(const bool fullScreen, const Point& outputSize, const std::shared_ptr>& isRunningSharedPtr, const std::shared_ptr, std::atomic>>& videoSeekSharedPtr, const std::vector>& poseExtractors, const std::vector>& poseRenderers) : mFrameDisplayer{outputSize, "OpenPose - GUI", fullScreen}, diff --git a/src/openpose/gui/guiInfoAdder.cpp b/src/openpose/gui/guiInfoAdder.cpp index eec686f1..d1818270 100644 --- a/src/openpose/gui/guiInfoAdder.cpp +++ b/src/openpose/gui/guiInfoAdder.cpp @@ -46,9 +46,9 @@ namespace op } } - GuiInfoAdder::GuiInfoAdder(const cv::Size& outputSize, const int numberGpus, const bool guiEnabled) : + GuiInfoAdder::GuiInfoAdder(const Point& outputSize, const int numberGpus, const bool guiEnabled) : mOutputSize{outputSize}, - mBorderMargin{intRound(fastMax(mOutputSize.width, mOutputSize.height) * 0.025)}, + mBorderMargin{intRound(fastMax(mOutputSize.x, mOutputSize.y) * 0.025)}, mNumberGpus{numberGpus}, mGuiEnabled{guiEnabled}, mFpsCounter{0u}, @@ -57,7 +57,7 @@ namespace op { } - void GuiInfoAdder::addInfo(cv::Mat& cvOutputData, const Array& poseKeyPoints, const unsigned long long id, const std::string& elementRenderedName) + void GuiInfoAdder::addInfo(cv::Mat& cvOutputData, const Array& poseKeypoints, const unsigned long long id, const std::string& elementRenderedName) { try { @@ -90,12 +90,12 @@ namespace op // Display element to display or help std::string message = (!mLastElementRenderedName.empty() ? mLastElementRenderedName : (mGuiEnabled ? "'h' for help" : "")); if (!message.empty()) - putTextOnCvMat(cvOutputData, message, {intRound(mOutputSize.width - mBorderMargin), mBorderMargin}, white, true); + putTextOnCvMat(cvOutputData, message, {intRound(mOutputSize.x - mBorderMargin), mBorderMargin}, white, true); // Frame number - putTextOnCvMat(cvOutputData, "Frame " + std::to_string(id), {mBorderMargin, (int)(mOutputSize.height - mBorderMargin)}, white, false); + putTextOnCvMat(cvOutputData, "Frame " + std::to_string(id), {mBorderMargin, (int)(mOutputSize.y - mBorderMargin)}, white, false); // Number people - const auto textToDisplay = std::to_string(poseKeyPoints.getSize(0)) + " people"; - putTextOnCvMat(cvOutputData, textToDisplay, {(int)(mOutputSize.width - mBorderMargin), (int)(mOutputSize.height - mBorderMargin)}, white, true); + const auto textToDisplay = std::to_string(poseKeypoints.getSize(0)) + " people"; + putTextOnCvMat(cvOutputData, textToDisplay, {(int)(mOutputSize.x - mBorderMargin), (int)(mOutputSize.y - mBorderMargin)}, white, true); } catch (const std::exception& e) { diff --git a/src/openpose/pose/bodyPartConnectorBase.cpp b/src/openpose/pose/bodyPartConnectorBase.cpp index f8f2326a..604198d4 100644 --- a/src/openpose/pose/bodyPartConnectorBase.cpp +++ b/src/openpose/pose/bodyPartConnectorBase.cpp @@ -7,7 +7,7 @@ namespace op { template - void connectBodyPartsCpu(Array& poseKeyPoints, const T* const heatMapPtr, const T* const peaksPtr, const PoseModel poseModel, const cv::Size& heatMapSize, const int maxPeaks, + void connectBodyPartsCpu(Array& poseKeypoints, const T* const heatMapPtr, const T* const peaksPtr, const PoseModel poseModel, const Point& heatMapSize, const int maxPeaks, const int interMinAboveThreshold, const T interThreshold, const int minSubsetCnt, const T minSubsetScore, const T scaleFactor) { try @@ -146,11 +146,11 @@ namespace op auto count = 0; for (auto lm=0; lm < numInter; lm++) { - const auto mX = fastMin(heatMapSize.width-1, intRound(sX + lm*dX/numInter)); - const auto mY = fastMin(heatMapSize.height-1, intRound(sY + lm*dY/numInter)); + const auto mX = fastMin(heatMapSize.x-1, intRound(sX + lm*dX/numInter)); + const auto mY = fastMin(heatMapSize.y-1, intRound(sY + lm*dY/numInter)); checkGE(mX, 0, "", __LINE__, __FUNCTION__, __FILE__); checkGE(mY, 0, "", __LINE__, __FUNCTION__, __FILE__); - const auto idx = mY * heatMapSize.width + mX; + const auto idx = mY * heatMapSize.x + mX; const auto score = (vecX*mapX[idx] + vecY*mapY[idx]); if (score > interThreshold) { @@ -290,11 +290,11 @@ namespace op error("Bad subsetCounter. Bug in in this function if this happens.", __LINE__, __FUNCTION__, __FILE__); } - // Fill and return poseKeyPoints + // Fill and return poseKeypoints if (numberPeople > 0) - poseKeyPoints.reset({numberPeople, (int)numberBodyParts, 3}); + poseKeypoints.reset({numberPeople, (int)numberBodyParts, 3}); else - poseKeyPoints.reset(); + poseKeypoints.reset(); for (auto person = 0 ; person < validSubsetIndexes.size() ; person++) { const auto& subsetI = subset[validSubsetIndexes[person]].first; @@ -304,15 +304,15 @@ namespace op const auto bodyPartIndex = subsetI[bodyPart]; if (bodyPartIndex > 0) { - poseKeyPoints[baseOffset] = peaksPtr[bodyPartIndex-2] * scaleFactor; - poseKeyPoints[baseOffset + 1] = peaksPtr[bodyPartIndex-1] * scaleFactor; - poseKeyPoints[baseOffset + 2] = peaksPtr[bodyPartIndex]; + poseKeypoints[baseOffset] = peaksPtr[bodyPartIndex-2] * scaleFactor; + poseKeypoints[baseOffset + 1] = peaksPtr[bodyPartIndex-1] * scaleFactor; + poseKeypoints[baseOffset + 2] = peaksPtr[bodyPartIndex]; } else { - poseKeyPoints[baseOffset] = 0.f; - poseKeyPoints[baseOffset + 1] = 0.f; - poseKeyPoints[baseOffset + 2] = 0.f; + poseKeypoints[baseOffset] = 0.f; + poseKeypoints[baseOffset + 1] = 0.f; + poseKeypoints[baseOffset + 2] = 0.f; } } } @@ -323,10 +323,10 @@ namespace op } } - template void connectBodyPartsCpu(Array& poseKeyPoints, const float* const heatMapPtr, const float* const peaksPtr, const PoseModel poseModel, const cv::Size& heatMapSize, + template void connectBodyPartsCpu(Array& poseKeypoints, const float* const heatMapPtr, const float* const peaksPtr, const PoseModel poseModel, const Point& heatMapSize, const int maxPeaks, const int interMinAboveThreshold, const float interThreshold, const int minSubsetCnt, const float minSubsetScore, const float scaleFactor); - template void connectBodyPartsCpu(Array& poseKeyPoints, const double* const heatMapPtr, const double* const peaksPtr, const PoseModel poseModel, const cv::Size& heatMapSize, + template void connectBodyPartsCpu(Array& poseKeypoints, const double* const heatMapPtr, const double* const peaksPtr, const PoseModel poseModel, const Point& heatMapSize, const int maxPeaks, const int interMinAboveThreshold, const double interThreshold, const int minSubsetCnt, const double minSubsetScore, const double scaleFactor); } diff --git a/src/openpose/pose/bodyPartConnectorBase.cu b/src/openpose/pose/bodyPartConnectorBase.cu index 4d70c658..2c6b5a8f 100644 --- a/src/openpose/pose/bodyPartConnectorBase.cu +++ b/src/openpose/pose/bodyPartConnectorBase.cu @@ -5,12 +5,12 @@ namespace op { template - void connectBodyPartsGpu(Array& poseKeyPoints, T* posePtr, const T* const heatMapPtr, const T* const peaksPtr, const PoseModel poseModel, const cv::Size& heatMapSize, + void connectBodyPartsGpu(Array& poseKeypoints, T* posePtr, const T* const heatMapPtr, const T* const peaksPtr, const PoseModel poseModel, const Point& heatMapSize, const int maxPeaks, const int interMinAboveThreshold, const T interThreshold, const int minSubsetCnt, const T minSubsetScore, const T scaleFactor) { try { - UNUSED(poseKeyPoints); + UNUSED(poseKeypoints); UNUSED(posePtr); UNUSED(heatMapPtr); UNUSED(peaksPtr); @@ -31,10 +31,10 @@ namespace op } } - template void connectBodyPartsGpu(Array& poseKeyPoints, float* posePtr, const float* const heatMapPtr, const float* const peaksPtr, const PoseModel poseModel, - const cv::Size& heatMapSize, const int maxPeaks, const int interMinAboveThreshold, const float interThreshold, const int minSubsetCnt, + template void connectBodyPartsGpu(Array& poseKeypoints, float* posePtr, const float* const heatMapPtr, const float* const peaksPtr, const PoseModel poseModel, + const Point& heatMapSize, const int maxPeaks, const int interMinAboveThreshold, const float interThreshold, const int minSubsetCnt, const float minSubsetScore, const float scaleFactor); - template void connectBodyPartsGpu(Array& poseKeyPoints, double* posePtr, const double* const heatMapPtr, const double* const peaksPtr, const PoseModel poseModel, - const cv::Size& heatMapSize, const int maxPeaks, const int interMinAboveThreshold, const double interThreshold, const int minSubsetCnt, + template void connectBodyPartsGpu(Array& poseKeypoints, double* posePtr, const double* const heatMapPtr, const double* const peaksPtr, const PoseModel poseModel, + const Point& heatMapSize, const int maxPeaks, const int interMinAboveThreshold, const double interThreshold, const int minSubsetCnt, const double minSubsetScore, const double scaleFactor); } diff --git a/src/openpose/pose/bodyPartConnectorCaffe.cpp b/src/openpose/pose/bodyPartConnectorCaffe.cpp index ecd2ce89..b43b8368 100644 --- a/src/openpose/pose/bodyPartConnectorCaffe.cpp +++ b/src/openpose/pose/bodyPartConnectorCaffe.cpp @@ -131,7 +131,7 @@ namespace op } template - void BodyPartConnectorCaffe::Forward_cpu(const std::vector*>& bottom, Array& poseKeyPoints) + void BodyPartConnectorCaffe::Forward_cpu(const std::vector*>& bottom, Array& poseKeypoints) { try { @@ -139,7 +139,7 @@ namespace op const auto* const heatMapsPtr = heatMapsBlob->cpu_data(); // ~8.5ms / 114 const auto* const peaksPtr = bottom.at(1)->cpu_data(); // ~0.02ms const auto maxPeaks = mTopSize[1]; - connectBodyPartsCpu(poseKeyPoints, heatMapsPtr, peaksPtr, mPoseModel, cv::Size{heatMapsBlob->shape(3), heatMapsBlob->shape(2)}, maxPeaks, + connectBodyPartsCpu(poseKeypoints, heatMapsPtr, peaksPtr, mPoseModel, Point{heatMapsBlob->shape(3), heatMapsBlob->shape(2)}, maxPeaks, mInterMinAboveThreshold, mInterThreshold, mMinSubsetCnt, mMinSubsetScore, mScaleNetToOutput); } catch (const std::exception& e) @@ -149,7 +149,7 @@ namespace op } template - void BodyPartConnectorCaffe::Forward_gpu(const std::vector*>& bottom, const std::vector*>& top, Array& poseKeyPoints) + void BodyPartConnectorCaffe::Forward_gpu(const std::vector*>& bottom, const std::vector*>& top, Array& poseKeypoints) { try { @@ -157,7 +157,7 @@ namespace op const auto* const heatMapsPtr = heatMapsBlob->gpu_data(); const auto* const peaksPtr = bottom.at(1)->gpu_data(); const auto maxPeaks = mTopSize[1]; - connectBodyPartsGpu(poseKeyPoints, top.at(0)->mutable_gpu_data(), heatMapsPtr, peaksPtr, mPoseModel, cv::Size{heatMapsBlob->shape(3), heatMapsBlob->shape(2)}, maxPeaks, + connectBodyPartsGpu(poseKeypoints, top.at(0)->mutable_gpu_data(), heatMapsPtr, peaksPtr, mPoseModel, Point{heatMapsBlob->shape(3), heatMapsBlob->shape(2)}, maxPeaks, mInterMinAboveThreshold, mInterThreshold, mMinSubsetCnt, mMinSubsetScore, mScaleNetToOutput); } catch (const std::exception& e) diff --git a/src/openpose/pose/poseExtractor.cpp b/src/openpose/pose/poseExtractor.cpp index da4114c6..88185285 100644 --- a/src/openpose/pose/poseExtractor.cpp +++ b/src/openpose/pose/poseExtractor.cpp @@ -7,6 +7,78 @@ namespace op { + // In case I wanna order the pose keypoints by area + // inline int getPersonArea(const float* posePtr, const int numberBodyParts, const float threshold) + // { + // try + // { + // if (numberBodyParts < 1) + // error("Number body parts must be > 0", __LINE__, __FUNCTION__, __FILE__); + + // unsigned int minX = -1; + // unsigned int maxX = 0u; + // unsigned int minY = -1; + // unsigned int maxY = 0u; + // for (auto part = 0 ; part < numberBodyParts ; part++) + // { + // const auto score = posePtr[3*part + 2]; + // if (score > threshold) + // { + // const auto x = posePtr[3*part]; + // const auto y = posePtr[3*part + 1]; + // // Set X + // if (maxX < x) + // maxX = x; + // if (minX > x) + // minX = x; + // // Set Y + // if (maxY < y) + // maxY = y; + // if (minY > y) + // minY = y; + // } + // } + // return (maxX - minX) * (maxY - minY); + // } + // catch (const std::exception& e) + // { + // error(e.what(), __LINE__, __FUNCTION__, __FILE__); + // return 0; + // } + // } + + // inline int getPersonWithMaxArea(const Array& poseKeypoints, const float threshold) + // { + // try + // { + // if (!poseKeypoints.empty()) + // { + // const auto numberPeople = poseKeypoints.getSize(0); + // const auto numberBodyParts = poseKeypoints.getSize(1); + // const auto area = numberBodyParts * poseKeypoints.getSize(2); + // auto biggestPoseIndex = -1; + // auto biggestArea = -1; + // for (auto person = 0 ; person < numberPeople ; person++) + // { + // const auto newPersonArea = getPersonArea(&poseKeypoints[person*area], numberBodyParts, threshold); + // if (newPersonArea > biggestArea) + // { + // biggestArea = newPersonArea; + // biggestPoseIndex = person; + // } + // } + // return biggestPoseIndex; + // } + // else + // return -1; + // } + // catch (const std::exception& e) + // { + // error(e.what(), __LINE__, __FUNCTION__, __FILE__); + // return -1; + // } + // } + bool heatMapTypesHas(const std::vector& heatMapTypes, const HeatMapType heatMapType) { try @@ -43,19 +115,19 @@ namespace op } } - PoseExtractor::PoseExtractor(const cv::Size& netOutputSize, const cv::Size& outputSize, const PoseModel poseModel, const std::vector& heatMapTypes, - const ScaleMode heatMapScaleMode) : + PoseExtractor::PoseExtractor(const Point& netOutputSize, const Point& outputSize, const PoseModel poseModel, const std::vector& heatMapTypes, + const ScaleMode heatMapScale) : mPoseModel{poseModel}, mNetOutputSize{netOutputSize}, mOutputSize{outputSize}, mHeatMapTypes{heatMapTypes}, - mHeatMapScaleMode{heatMapScaleMode} + mHeatMapScaleMode{heatMapScale} { try { // Error check if (mHeatMapScaleMode != ScaleMode::ZeroToOne && mHeatMapScaleMode != ScaleMode::PlusMinusOne && mHeatMapScaleMode != ScaleMode::UnsignedChar) - error("The ScaleMode heatMapScaleMode must be ZeroToOne, PlusMinusOne or UnsignedChar.", __LINE__, __FUNCTION__, __FILE__); + error("The ScaleMode heatMapScale must be ZeroToOne, PlusMinusOne or UnsignedChar.", __LINE__, __FUNCTION__, __FILE__); // Properties for (auto& property : mProperties) @@ -95,7 +167,7 @@ namespace op { // Allocate memory const auto numberHeatMapChannels = getNumberHeatMapChannels(mHeatMapTypes, mPoseModel); - poseHeatMaps.reset({numberHeatMapChannels, mNetOutputSize.height, mNetOutputSize.width}); + poseHeatMaps.reset({numberHeatMapChannels, mNetOutputSize.y, mNetOutputSize.x}); // Copy memory const auto channelOffset = poseHeatMaps.getVolume(1, 2); @@ -167,12 +239,12 @@ namespace op } } - Array PoseExtractor::getPoseKeyPoints() const + Array PoseExtractor::getPoseKeypoints() const { try { checkThread(); - return mPoseKeyPoints; + return mPoseKeypoints; } catch (const std::exception& e) { diff --git a/src/openpose/pose/poseExtractorCaffe.cpp b/src/openpose/pose/poseExtractorCaffe.cpp index ea9c9cdf..15b5d55f 100644 --- a/src/openpose/pose/poseExtractorCaffe.cpp +++ b/src/openpose/pose/poseExtractorCaffe.cpp @@ -10,11 +10,11 @@ namespace op { - PoseExtractorCaffe::PoseExtractorCaffe(const cv::Size& netInputSize, const cv::Size& netOutputSize, const cv::Size& outputSize, const int scaleNumber, + PoseExtractorCaffe::PoseExtractorCaffe(const Point& netInputSize, const Point& netOutputSize, const Point& outputSize, const int scaleNumber, const float scaleGap, const PoseModel poseModel, const std::string& modelFolder, const int gpuId, const std::vector& heatMapTypes, - const ScaleMode heatMapScaleMode) : - PoseExtractor{netOutputSize, outputSize, poseModel, heatMapTypes, heatMapScaleMode}, - spNet{std::make_shared(std::array{scaleNumber, 3, (int)netInputSize.height, (int)netInputSize.width}, + const ScaleMode heatMapScale) : + PoseExtractor{netOutputSize, outputSize, poseModel, heatMapTypes, heatMapScale}, + spNet{std::make_shared(std::array{scaleNumber, 3, (int)netInputSize.y, (int)netInputSize.x}, modelFolder + POSE_PROTOTXT[(int)poseModel], modelFolder + POSE_TRAINED_MODEL[(int)poseModel], gpuId)}, spResizeAndMergeCaffe{std::make_shared>()}, spNmsCaffe{std::make_shared>()}, @@ -70,7 +70,7 @@ namespace op } } - void PoseExtractorCaffe::forwardPass(const Array& inputNetData, const cv::Size& inputDataSize) + void PoseExtractorCaffe::forwardPass(const Array& inputNetData, const Point& inputDataSize) { try { @@ -100,7 +100,7 @@ namespace op // Get scale net to output const auto scaleProducerToNetInput = resizeGetScaleFactor(inputDataSize, mNetOutputSize); - const cv::Size netSize{intRound(scaleProducerToNetInput*inputDataSize.width), intRound(scaleProducerToNetInput*inputDataSize.height)}; + const Point netSize{intRound(scaleProducerToNetInput*inputDataSize.x), intRound(scaleProducerToNetInput*inputDataSize.y)}; mScaleNetToOutput = {(float)resizeGetScaleFactor(netSize, mOutputSize)}; // 4. Connecting body parts @@ -111,8 +111,8 @@ namespace op spBodyPartConnectorCaffe->setMinSubsetScore((float)get(PoseProperty::ConnectMinSubsetScore)); // GPU version not implemented yet - spBodyPartConnectorCaffe->Forward_cpu({spHeatMapsBlob.get(), spPeaksBlob.get()}, mPoseKeyPoints); - // spBodyPartConnectorCaffe->Forward_gpu({spHeatMapsBlob.get(), spPeaksBlob.get()}, {spPoseBlob.get()}, mPoseKeyPoints); + spBodyPartConnectorCaffe->Forward_cpu({spHeatMapsBlob.get(), spPeaksBlob.get()}, mPoseKeypoints); + // spBodyPartConnectorCaffe->Forward_gpu({spHeatMapsBlob.get(), spPeaksBlob.get()}, {spPoseBlob.get()}, mPoseKeypoints); } catch (const std::exception& e) { diff --git a/src/openpose/pose/poseRenderGpu.cu b/src/openpose/pose/poseRenderGpu.cu index b7ab7566..7a5cea0c 100644 --- a/src/openpose/pose/poseRenderGpu.cu +++ b/src/openpose/pose/poseRenderGpu.cu @@ -10,8 +10,8 @@ namespace op { // PI digits: http://www.piday.org/million/ __constant__ const float PI = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745f; - __constant__ const unsigned char COCO_PAIRS_GPU[] = POSE_COCO_PAIRS_TO_RENDER; - __constant__ const unsigned char MPI_PAIRS_GPU[] = POSE_MPI_PAIRS_TO_RENDER; + __constant__ const unsigned int COCO_PAIRS_GPU[] = POSE_COCO_PAIRS_TO_RENDER; + __constant__ const unsigned int MPI_PAIRS_GPU[] = POSE_MPI_PAIRS_TO_RENDER; __constant__ const float COCO_RGB_COLORS[] = { 255.f, 0.f, 0.f, 255.f, 85.f, 0.f, @@ -168,7 +168,7 @@ namespace op const auto stickwidth = fastMin(targetWidth, targetHeight) / 120.f; // Render key points - renderKeyPoints(targetPtr, sharedMaxs, sharedMins, sharedScaleF, + renderKeypoints(targetPtr, sharedMaxs, sharedMins, sharedScaleF, globalIdx, x, y, targetWidth, targetHeight, posePtr, COCO_PAIRS_GPU, numberPeople, POSE_COCO_NUMBER_PARTS, numberPartPairs, COCO_RGB_COLORS, numberColors, radius, stickwidth, threshold, alphaColorToAdd, blendOriginalFrame, (googlyEyes ? 14 : -1), (googlyEyes ? 15 : -1)); @@ -193,7 +193,7 @@ namespace op const auto stickwidth = fastMin(targetWidth, targetHeight) / 120.f; // Render key points - renderKeyPoints(targetPtr, sharedMaxs, sharedMins, sharedScaleF, + renderKeypoints(targetPtr, sharedMaxs, sharedMins, sharedScaleF, globalIdx, x, y, targetWidth, targetHeight, posePtr, MPI_PAIRS_GPU, numberPeople, POSE_MPI_NUMBER_PARTS, numberPartPairs, MPI_RGB_COLORS, numberColors, radius, stickwidth, threshold, alphaColorToAdd, blendOriginalFrame); @@ -215,7 +215,7 @@ namespace op const auto xHeatMap = fastTruncate(int(xSource + 1e-5), 0, widthHeatMap); const auto yHeatMap = fastTruncate(int(ySource + 1e-5), 0, heightHeatMap); const auto heatMapArea = widthHeatMap * heightHeatMap; - for (unsigned char part = 0 ; part < numberBodyParts ; part++) + for (auto part = 0u ; part < numberBodyParts ; part++) { const auto offsetOrigin = part * heatMapArea; const auto value = __saturatef(heatMapPtr[offsetOrigin + yHeatMap*widthHeatMap + xHeatMap]); // __saturatef = trucate to [0,1] @@ -340,21 +340,21 @@ namespace op } } - inline void renderKeyPointsPartAffinityAux(float* framePtr, const PoseModel poseModel, const cv::Size& frameSize, - const float* const heatMapPtr, const cv::Size& heatMapSize, const float scaleToKeepRatio, + inline void renderKeypointsPartAffinityAux(float* framePtr, const PoseModel poseModel, const Point& frameSize, + const float* const heatMapPtr, const Point& heatMapSize, const float scaleToKeepRatio, const int part, const int partsToRender, const float alphaBlending) { try { //framePtr = width * height * 3 - //heatMapPtr = heatMapSize.width * heatMapSize.height * #body parts + //heatMapPtr = heatMapSize.x * heatMapSize.y * #body parts checkAlpha(alphaBlending); const auto heatMapOffset = POSE_NUMBER_BODY_PARTS[(int)poseModel] * heatMapSize.area(); dim3 threadsPerBlock; dim3 numBlocks; std::tie(threadsPerBlock, numBlocks) = getNumberCudaThreadsAndBlocks(frameSize); - renderPartAffinities<<>>(framePtr, frameSize.width, frameSize.height, heatMapPtr, heatMapSize.width, - heatMapSize.height, scaleToKeepRatio, partsToRender, part, alphaBlending); + renderPartAffinities<<>>(framePtr, frameSize.x, frameSize.y, heatMapPtr, heatMapSize.x, + heatMapSize.y, scaleToKeepRatio, partsToRender, part, alphaBlending); cudaCheck(__LINE__, __FUNCTION__, __FILE__); } catch (const std::exception& e) @@ -363,7 +363,7 @@ namespace op } } - void renderPoseGpu(float* framePtr, const PoseModel poseModel, const int numberPeople, const cv::Size& frameSize, const float* const posePtr, + void renderPoseGpu(float* framePtr, const PoseModel poseModel, const int numberPeople, const Point& frameSize, const float* const posePtr, const bool googlyEyes, const bool blendOriginalFrame, const float alphaBlending) { try @@ -371,8 +371,8 @@ namespace op if (numberPeople > 0 || !blendOriginalFrame) { //framePtr = width * height * 3 - //heatMapPtr = heatMapSize.width * heatMapSize.height * #body parts - //posePtr = 3 (x,y,score) * #Body parts * numberPeople + //heatMapPtr = heatMapSize.x * heatMapSize.y * #body parts + //posePtr = 3 (x,y,score) * #Body parts * numberPeople if (googlyEyes && poseModel != PoseModel::COCO_18) error("Bool googlyEyes only compatible with PoseModel::COCO_18.", __LINE__, __FUNCTION__, __FILE__); @@ -382,10 +382,10 @@ namespace op const auto threshold = getThresholdForPose(poseModel); if (poseModel == PoseModel::COCO_18) - renderPoseCoco<<>>(framePtr, frameSize.width, frameSize.height, posePtr, numberPeople, + renderPoseCoco<<>>(framePtr, frameSize.x, frameSize.y, posePtr, numberPeople, threshold, googlyEyes, blendOriginalFrame, alphaBlending); else if (poseModel == PoseModel::MPI_15 || poseModel == PoseModel::MPI_15_4) - renderPoseMpi29Parts<<>>(framePtr, frameSize.width, frameSize.height, posePtr, + renderPoseMpi29Parts<<>>(framePtr, frameSize.x, frameSize.y, posePtr, numberPeople, threshold, blendOriginalFrame, alphaBlending); else error("Unvalid Model.", __LINE__, __FUNCTION__, __FILE__); @@ -398,13 +398,13 @@ namespace op } } - void renderBodyPartGpu(float* framePtr, const PoseModel poseModel, const cv::Size& frameSize, const float* const heatMapPtr, - const cv::Size& heatMapSize, const float scaleToKeepRatio, const int part, const float alphaBlending) + void renderBodyPartGpu(float* framePtr, const PoseModel poseModel, const Point& frameSize, const float* const heatMapPtr, + const Point& heatMapSize, const float scaleToKeepRatio, const int part, const float alphaBlending) { try { //framePtr = width * height * 3 - //heatMapPtr = heatMapSize.width * heatMapSize.height * #body parts + //heatMapPtr = heatMapSize.x * heatMapSize.y * #body parts checkAlpha(alphaBlending); dim3 threadsPerBlock; dim3 numBlocks; @@ -412,8 +412,8 @@ namespace op const auto numberBodyParts = POSE_NUMBER_BODY_PARTS[(int)poseModel]; const auto heatMapOffset = numberBodyParts * heatMapSize.area(); - renderBodyPartHeatMap<<>>(framePtr, frameSize.width, frameSize.height, heatMapPtr, heatMapSize.width, - heatMapSize.height, scaleToKeepRatio, part-1, numberBodyParts, alphaBlending); + renderBodyPartHeatMap<<>>(framePtr, frameSize.x, frameSize.y, heatMapPtr, heatMapSize.x, + heatMapSize.y, scaleToKeepRatio, part-1, numberBodyParts, alphaBlending); cudaCheck(__LINE__, __FUNCTION__, __FILE__); } catch (const std::exception& e) @@ -422,13 +422,13 @@ namespace op } } - void renderBodyPartsGpu(float* framePtr, const PoseModel poseModel, const cv::Size& frameSize, const float* const heatMapPtr, - const cv::Size& heatMapSize, const float scaleToKeepRatio, const float alphaBlending) + void renderBodyPartsGpu(float* framePtr, const PoseModel poseModel, const Point& frameSize, const float* const heatMapPtr, + const Point& heatMapSize, const float scaleToKeepRatio, const float alphaBlending) { try { //framePtr = width * height * 3 - //heatMapPtr = heatMapSize.width * heatMapSize.height * #body parts + //heatMapPtr = heatMapSize.x * heatMapSize.y * #body parts checkAlpha(alphaBlending); dim3 threadsPerBlock; dim3 numBlocks; @@ -436,7 +436,7 @@ namespace op const auto numberBodyParts = POSE_NUMBER_BODY_PARTS[(int)poseModel]; const auto heatMapOffset = numberBodyParts * heatMapSize.area(); - renderBodyPartHeatMaps<<>>(framePtr, frameSize.width, frameSize.height, heatMapPtr, heatMapSize.width, heatMapSize.height, + renderBodyPartHeatMaps<<>>(framePtr, frameSize.x, frameSize.y, heatMapPtr, heatMapSize.x, heatMapSize.y, scaleToKeepRatio, numberBodyParts, alphaBlending); cudaCheck(__LINE__, __FUNCTION__, __FILE__); } @@ -446,12 +446,12 @@ namespace op } } - void renderPartAffinityFieldGpu(float* framePtr, const PoseModel poseModel, const cv::Size& frameSize, const float* const heatMapPtr, - const cv::Size& heatMapSize, const float scaleToKeepRatio, const int part, const float alphaBlending) + void renderPartAffinityFieldGpu(float* framePtr, const PoseModel poseModel, const Point& frameSize, const float* const heatMapPtr, + const Point& heatMapSize, const float scaleToKeepRatio, const int part, const float alphaBlending) { try { - renderKeyPointsPartAffinityAux(framePtr, poseModel, frameSize, heatMapPtr, heatMapSize, scaleToKeepRatio, part, 1, alphaBlending); + renderKeypointsPartAffinityAux(framePtr, poseModel, frameSize, heatMapPtr, heatMapSize, scaleToKeepRatio, part, 1, alphaBlending); } catch (const std::exception& e) { @@ -459,13 +459,13 @@ namespace op } } - void renderPartAffinityFieldsGpu(float* framePtr, const PoseModel poseModel, const cv::Size& frameSize, const float* const heatMapPtr, - const cv::Size& heatMapSize, const float scaleToKeepRatio, const float alphaBlending) + void renderPartAffinityFieldsGpu(float* framePtr, const PoseModel poseModel, const Point& frameSize, const float* const heatMapPtr, + const Point& heatMapSize, const float scaleToKeepRatio, const float alphaBlending) { try { const auto numberBodyPartPairs = (int)POSE_BODY_PART_PAIRS[(int)poseModel].size()/2; - renderKeyPointsPartAffinityAux(framePtr, poseModel, frameSize, heatMapPtr, heatMapSize, scaleToKeepRatio, POSE_NUMBER_BODY_PARTS[(int)poseModel]+1, + renderKeypointsPartAffinityAux(framePtr, poseModel, frameSize, heatMapPtr, heatMapSize, scaleToKeepRatio, POSE_NUMBER_BODY_PARTS[(int)poseModel]+1, numberBodyPartPairs, alphaBlending); } catch (const std::exception& e) diff --git a/src/openpose/pose/poseRenderer.cpp b/src/openpose/pose/poseRenderer.cpp index 2adcd7e6..c349d4a5 100644 --- a/src/openpose/pose/poseRenderer.cpp +++ b/src/openpose/pose/poseRenderer.cpp @@ -37,22 +37,19 @@ namespace op } } - PoseRenderer::PoseRenderer(const cv::Size& heatMapsSize, const cv::Size& outputSize, const PoseModel poseModel, const std::shared_ptr& poseExtractor, - const bool blendOriginalFrame, const float alphaPose, const float alphaHeatMap, const unsigned int elementToRender) : - Renderer{(unsigned long long)(outputSize.area() * 3)}, + PoseRenderer::PoseRenderer(const Point& heatMapsSize, const Point& outputSize, const PoseModel poseModel, const std::shared_ptr& poseExtractor, + const bool blendOriginalFrame, const float alphaKeypoint, const float alphaHeatMap, const unsigned int elementToRender) : + // #body elements to render = #body parts (size()) + #body part pair connections + 3 (+whole pose +whole heatmaps +PAFs) + // POSE_BODY_PART_MAPPING crashes on Windows, replaced by getPoseBodyPartMapping + Renderer{(unsigned long long)(outputSize.area() * 3), alphaKeypoint, alphaHeatMap, elementToRender, + (unsigned int)(getPoseBodyPartMapping(poseModel).size() + POSE_BODY_PART_PAIRS[(int)poseModel].size()/2 + 3)}, // mNumberElementsToRender mHeatMapsSize{heatMapsSize}, mOutputSize{outputSize}, mPoseModel{poseModel}, mPartIndexToName{createPartToName(poseModel)}, - // #body elements to render = #body parts (size()) + #body part pair connections + 3 (+whole pose +whole heatmaps +PAFs) - // POSE_BODY_PART_MAPPING crashes on Windows, replaced by getPoseBodyPartMapping - mNumberElementsToRender{(int)(getPoseBodyPartMapping(mPoseModel).size() + POSE_BODY_PART_PAIRS[(int)mPoseModel].size()/2 + 3)}, spPoseExtractor{poseExtractor}, - mAlphaPose{alphaPose}, - mAlphaHeatMap{alphaHeatMap}, mBlendOriginalFrame{blendOriginalFrame}, mShowGooglyEyes{false}, - mElementToRender{elementToRender}, pGpuPose{nullptr} { } @@ -77,7 +74,7 @@ namespace op // GPU memory allocation for rendering log("Starting initialization on thread.", Priority::Low, __LINE__, __FUNCTION__, __FILE__); Renderer::initializationOnThread(); - cudaMalloc((void**)(&pGpuPose), POSE_MAX_PEOPLE * POSE_NUMBER_BODY_PARTS[(int)mPoseModel] * 3 * sizeof(float) ); + cudaMalloc((void**)(&pGpuPose), POSE_MAX_PEOPLE * POSE_NUMBER_BODY_PARTS[(int)mPoseModel] * 3 * sizeof(float)); cudaCheck(__LINE__, __FUNCTION__, __FILE__); log("Finished initialization on thread.", Priority::Low, __LINE__, __FUNCTION__, __FILE__); } @@ -87,85 +84,6 @@ namespace op } } - void PoseRenderer::increaseElementToRender(const int increment) - { - try - { - auto elementToRender = (((int)mElementToRender + increment) % mNumberElementsToRender); - // Handling negative increments - while (elementToRender < 0) - elementToRender += mNumberElementsToRender; - // Update final value - mElementToRender = elementToRender; - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - - void PoseRenderer::setElementToRender(const int elementToRender) - { - try - { - mElementToRender = elementToRender % mNumberElementsToRender; - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - - float PoseRenderer::getAlphaPose() const - { - try - { - return mAlphaPose; - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - return 0.f; - } - } - - void PoseRenderer::setAlphaPose(const float alphaPose) - { - try - { - mAlphaPose = alphaPose; - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - - float PoseRenderer::getAlphaHeatMap() const - { - try - { - return mAlphaHeatMap; - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - return 0.f; - } - } - - void PoseRenderer::setAlphaHeatMap(const float alphaHeatMap) - { - try - { - mAlphaHeatMap = alphaHeatMap; - } - catch (const std::exception& e) - { - error(e.what(), __LINE__, __FUNCTION__, __FILE__); - } - } - bool PoseRenderer::getBlendOriginalFrame() const { try @@ -216,7 +134,7 @@ namespace op } } - std::pair PoseRenderer::renderPose(Array& outputData, const Array& poseKeyPoints, const float scaleNetToOutput) + std::pair PoseRenderer::renderPose(Array& outputData, const Array& poseKeypoints, const float scaleNetToOutput) { try { @@ -224,9 +142,9 @@ namespace op if (outputData.empty()) error("Empty outputData.", __LINE__, __FUNCTION__, __FILE__); - const auto elementRendered = mElementToRender.load(); // I prefer std::round(T&) over intRound(T) for std::atomic + const auto elementRendered = spElementToRender->load(); // I prefer std::round(T&) over intRound(T) for std::atomic + const auto numberPeople = poseKeypoints.getSize(0); std::string elementRenderedName; - const auto numberPeople = poseKeyPoints.getSize(0); // GPU rendering if (numberPeople > 0 || elementRendered != 0 || !mBlendOriginalFrame) @@ -235,12 +153,12 @@ namespace op cudaCheck(__LINE__, __FUNCTION__, __FILE__); const auto numberBodyParts = POSE_NUMBER_BODY_PARTS[(int)mPoseModel]; const auto numberBodyPartsPlusBkg = numberBodyParts+1; - // Draw poseKeyPoints + // Draw poseKeypoints if (elementRendered == 0) { - if (!poseKeyPoints.empty()) - cudaMemcpy(pGpuPose, poseKeyPoints.getConstPtr(), numberPeople * numberBodyParts * 3 * sizeof(float), cudaMemcpyHostToDevice); - renderPoseGpu(*spGpuMemoryPtr, mPoseModel, numberPeople, mOutputSize, pGpuPose, mShowGooglyEyes, mBlendOriginalFrame, mAlphaPose); + if (!poseKeypoints.empty()) + cudaMemcpy(pGpuPose, poseKeypoints.getConstPtr(), numberPeople * numberBodyParts * 3 * sizeof(float), cudaMemcpyHostToDevice); + renderPoseGpu(*spGpuMemoryPtr, mPoseModel, numberPeople, mOutputSize, pGpuPose, mShowGooglyEyes, mBlendOriginalFrame, getAlphaKeypoint()); } else { @@ -251,21 +169,21 @@ namespace op { elementRenderedName = mPartIndexToName.at(elementRendered-1); renderBodyPartGpu(*spGpuMemoryPtr, mPoseModel, mOutputSize, spPoseExtractor->getHeatMapCpuConstPtr(), mHeatMapsSize, - scaleNetToOutput, elementRendered, (mBlendOriginalFrame ? mAlphaHeatMap : 1.f)); + scaleNetToOutput, elementRendered, (mBlendOriginalFrame ? getAlphaHeatMap() : 1.f)); } // Draw PAFs (Part Affinity Fields) else if (elementRendered == numberBodyPartsPlusBkg+1) { elementRenderedName = "Heatmaps"; renderBodyPartsGpu(*spGpuMemoryPtr, mPoseModel, mOutputSize, spPoseExtractor->getHeatMapCpuConstPtr(), mHeatMapsSize, scaleNetToOutput, - (mBlendOriginalFrame ? mAlphaHeatMap : 1.f)); + (mBlendOriginalFrame ? getAlphaHeatMap() : 1.f)); } // Draw PAFs (Part Affinity Fields) else if (elementRendered == numberBodyPartsPlusBkg+2) { elementRenderedName = "PAFs (Part Affinity Fields)"; renderPartAffinityFieldsGpu(*spGpuMemoryPtr, mPoseModel, mOutputSize, spPoseExtractor->getHeatMapCpuConstPtr(), - mHeatMapsSize, scaleNetToOutput, (mBlendOriginalFrame ? mAlphaHeatMap : 1.f)); + mHeatMapsSize, scaleNetToOutput, (mBlendOriginalFrame ? getAlphaHeatMap() : 1.f)); } // Draw affinity between 2 body parts else @@ -275,7 +193,7 @@ namespace op elementRenderedName = mPartIndexToName.at(affinityPartMapped); elementRenderedName = elementRenderedName.substr(0, elementRenderedName.find("(")); renderPartAffinityFieldGpu(*spGpuMemoryPtr, mPoseModel, mOutputSize, spPoseExtractor->getHeatMapCpuConstPtr(), - mHeatMapsSize, scaleNetToOutput, affinityPartMapped, (mBlendOriginalFrame ? mAlphaHeatMap : 1.f)); + mHeatMapsSize, scaleNetToOutput, affinityPartMapped, (mBlendOriginalFrame ? getAlphaHeatMap() : 1.f)); } } } diff --git a/src/openpose/producer/imageDirectoryReader.cpp b/src/openpose/producer/imageDirectoryReader.cpp index fc3dc377..72fd3d9a 100644 --- a/src/openpose/producer/imageDirectoryReader.cpp +++ b/src/openpose/producer/imageDirectoryReader.cpp @@ -49,7 +49,7 @@ namespace op // Check frame integrity. This function also checks width/height changes. However, if it is performed after setWidth/setHeight this is performed over the new resolution (so they always match). checkFrameIntegrity(frame); // Update size, since images might have different size between each one of them - mResolution = {frame.size()}; + mResolution = Point{frame.cols, frame.rows}; return frame; } catch (const std::exception& e) @@ -66,16 +66,16 @@ namespace op if (capProperty == CV_CAP_PROP_FRAME_WIDTH) { if (get(ProducerProperty::Rotation) == 0. || get(ProducerProperty::Rotation) == 180.) - return mResolution.width; + return mResolution.x; else - return mResolution.height; + return mResolution.y; } else if (capProperty == CV_CAP_PROP_FRAME_HEIGHT) { if (get(ProducerProperty::Rotation) == 0. || get(ProducerProperty::Rotation) == 180.) - return mResolution.height; + return mResolution.y; else - return mResolution.width; + return mResolution.x; } else if (capProperty == CV_CAP_PROP_POS_FRAMES) return (double)mFrameNameCounter; @@ -101,9 +101,9 @@ namespace op try { if (capProperty == CV_CAP_PROP_FRAME_WIDTH) - mResolution.width = {(int)value}; + mResolution.x = {(int)value}; else if (capProperty == CV_CAP_PROP_FRAME_HEIGHT) - mResolution.height = {(int)value}; + mResolution.y = {(int)value}; else if (capProperty == CV_CAP_PROP_POS_FRAMES) mFrameNameCounter = fastTruncate((long long)value, 0ll, (long long)mImageDirectoryPath.size()-1); else if (capProperty == CV_CAP_PROP_FRAME_COUNT || capProperty == CV_CAP_PROP_FPS) diff --git a/src/openpose/producer/webcamReader.cpp b/src/openpose/producer/webcamReader.cpp index bbe67316..f1136899 100644 --- a/src/openpose/producer/webcamReader.cpp +++ b/src/openpose/producer/webcamReader.cpp @@ -6,19 +6,19 @@ namespace op { - WebcamReader::WebcamReader(const int webcamIndex, const cv::Size webcamResolution) : + WebcamReader::WebcamReader(const int webcamIndex, const Point webcamResolution) : VideoCaptureReader{webcamIndex}, mFrameNameCounter{-1} { try { - if (webcamResolution != cv::Size{}) + if (webcamResolution != Point{}) { - set(CV_CAP_PROP_FRAME_WIDTH, webcamResolution.width); - set(CV_CAP_PROP_FRAME_HEIGHT, webcamResolution.height); - if ((int)get(CV_CAP_PROP_FRAME_WIDTH) != webcamResolution.width || (int)get(CV_CAP_PROP_FRAME_HEIGHT) != webcamResolution.height) + set(CV_CAP_PROP_FRAME_WIDTH, webcamResolution.x); + set(CV_CAP_PROP_FRAME_HEIGHT, webcamResolution.y); + if ((int)get(CV_CAP_PROP_FRAME_WIDTH) != webcamResolution.x || (int)get(CV_CAP_PROP_FRAME_HEIGHT) != webcamResolution.y) { - const std::string logMessage{ "Desired webcam resolution " + std::to_string(webcamResolution.width) + "x" + std::to_string(webcamResolution.height) + const std::string logMessage{ "Desired webcam resolution " + std::to_string(webcamResolution.x) + "x" + std::to_string(webcamResolution.y) + " could not being set. Final resolution: " + std::to_string(intRound(get(CV_CAP_PROP_FRAME_WIDTH))) + "x" + std::to_string(intRound(get(CV_CAP_PROP_FRAME_HEIGHT))) }; log(logMessage, Priority::Max, __LINE__, __FUNCTION__, __FILE__); diff --git a/src/openpose/utilities/cuda.cpp b/src/openpose/utilities/cuda.cpp index 63987fb3..831464cd 100644 --- a/src/openpose/utilities/cuda.cpp +++ b/src/openpose/utilities/cuda.cpp @@ -6,7 +6,8 @@ namespace op { - const dim3 THREADS_PER_BLOCK_SMALL{32, 32, 1}; + const dim3 THREADS_PER_BLOCK_TINY{32, 32, 1}; + const dim3 THREADS_PER_BLOCK_SMALL{64, 64, 1}; const dim3 THREADS_PER_BLOCK_MEDIUM{128, 128, 1}; const dim3 THREADS_PER_BLOCK_BIG{256, 256, 1}; @@ -17,12 +18,20 @@ namespace op error("Cuda check failed (" + std::to_string(errorCode) + " vs. " + std::to_string(cudaSuccess) + "): " + cudaGetErrorString(errorCode), line, function, file); } - dim3 getNumberCudaBlocks(const cv::Size& frameSize, const dim3 numberCudaThreads) + int getGpuNumber() + { + int gpuNumber; + cudaGetDeviceCount(&gpuNumber); + cudaCheck(__LINE__, __FUNCTION__, __FILE__); + return gpuNumber; + } + + dim3 getNumberCudaBlocks(const Point& frameSize, const dim3 numberCudaThreads) { try { - return dim3{getNumberCudaBlocks((unsigned int)frameSize.width, numberCudaThreads.x), - getNumberCudaBlocks((unsigned int)frameSize.height, numberCudaThreads.y), + return dim3{getNumberCudaBlocks((unsigned int)frameSize.x, numberCudaThreads.x), + getNumberCudaBlocks((unsigned int)frameSize.y, numberCudaThreads.y), numberCudaThreads.z}; } catch (const std::exception& e) @@ -32,17 +41,22 @@ namespace op } } - std::pair getNumberCudaThreadsAndBlocks(const cv::Size& frameSize) + std::pair getNumberCudaThreadsAndBlocks(const Point& frameSize) { try { - // Image <= 1280x720 --> THREADS_PER_BLOCK_SMALL - // Image < 16K --> THREADS_PER_BLOCK_MEDIUM - // Image > 16K --> THREADS_PER_BLOCK_BIG - const auto maxValue = fastMax(frameSize.width, frameSize.height); - const auto threadsPerBlock = (maxValue < 1281 ? THREADS_PER_BLOCK_SMALL - : (maxValue < 16384 ? THREADS_PER_BLOCK_MEDIUM - : THREADS_PER_BLOCK_BIG)); + // Image <= 480p --> THREADS_PER_BLOCK_TINY + // Image <= 720p --> THREADS_PER_BLOCK_SMALL + // Image <= 16K --> THREADS_PER_BLOCK_MEDIUM + // Image > 16K --> THREADS_PER_BLOCK_BIG + const auto maxValue = fastMax(frameSize.x, frameSize.y); + auto threadsPerBlock = THREADS_PER_BLOCK_TINY; + if (maxValue >= 16384) + threadsPerBlock = THREADS_PER_BLOCK_BIG; + else if (maxValue > 1280) + threadsPerBlock = THREADS_PER_BLOCK_MEDIUM; + else if (maxValue > 640) + threadsPerBlock = THREADS_PER_BLOCK_SMALL; return std::make_pair(threadsPerBlock, getNumberCudaBlocks(frameSize, threadsPerBlock)); } catch (const std::exception& e) diff --git a/src/openpose/utilities/errorAndLog.cpp b/src/openpose/utilities/errorAndLog.cpp index a787ddf1..8cff2247 100644 --- a/src/openpose/utilities/errorAndLog.cpp +++ b/src/openpose/utilities/errorAndLog.cpp @@ -160,8 +160,8 @@ namespace op // ConfigureError - Private variables - std::vector sErrorModes {ErrorMode::StdRuntimeError}; - // std::vector sErrorModes {ErrorMode::StdCerr, ErrorMode::StdRuntimeError}; + // std::vector sErrorModes {ErrorMode::StdRuntimeError}; + std::vector sErrorModes {ErrorMode::StdCerr, ErrorMode::StdRuntimeError}; std::mutex sErrorModesMutex {}; std::vector ConfigureError::getErrorModes() diff --git a/src/openpose/utilities/openCv.cpp b/src/openpose/utilities/openCv.cpp index 075a2342..afc69aa6 100644 --- a/src/openpose/utilities/openCv.cpp +++ b/src/openpose/utilities/openCv.cpp @@ -4,7 +4,7 @@ namespace op { - void putTextOnCvMat(cv::Mat& cvMat, const std::string& textToDisplay, const cv::Point& position, const cv::Scalar& color, const bool normalizeWidth) + void putTextOnCvMat(cv::Mat& cvMat, const std::string& textToDisplay, const Point& position, const cv::Scalar& color, const bool normalizeWidth) { try { @@ -15,8 +15,8 @@ namespace op const auto shadowOffset = 2; int baseline = 0; const auto textSize = cv::getTextSize(textToDisplay, font, fontScale, fontThickness, &baseline); - const cv::Point finalPosition{position.x - (normalizeWidth ? textSize.width : 0), position.y + textSize.height/2}; - cv::putText(cvMat, textToDisplay, cv::Point{finalPosition.x+shadowOffset, finalPosition.y+shadowOffset}, font, fontScale, cv::Scalar{0,0,0}, fontThickness); + const cv::Size finalPosition{position.x - (normalizeWidth ? textSize.width : 0), position.y + textSize.height/2}; + cv::putText(cvMat, textToDisplay, cv::Size{finalPosition.width + shadowOffset, finalPosition.height + shadowOffset}, font, fontScale, cv::Scalar{0,0,0}, fontThickness); cv::putText(cvMat, textToDisplay, finalPosition, font, fontScale, color, fontThickness); } catch (const std::exception& e) @@ -25,23 +25,23 @@ namespace op } } - void floatPtrToUCharCvMat(cv::Mat& cvMat, const float* const floatImage, const cv::Size& resolutionSize, const int resolutionChannels) + void floatPtrToUCharCvMat(cv::Mat& cvMat, const float* const floatImage, const Point& resolutionSize, const int resolutionChannels) { try { // float* (deep net format): C x H x W // cv::Mat (OpenCV format): H x W x C - if (cvMat.rows != resolutionSize.height || cvMat.cols != resolutionSize.width || cvMat.type() != CV_8UC3) - cvMat = cv::Mat{resolutionSize.height, resolutionSize.width, CV_8UC3}; - const auto offsetBetweenChannels = resolutionSize.width * resolutionSize.height; + if (cvMat.rows != resolutionSize.y || cvMat.cols != resolutionSize.x || cvMat.type() != CV_8UC3) + cvMat = cv::Mat{resolutionSize.y, resolutionSize.x, CV_8UC3}; + const auto offsetBetweenChannels = resolutionSize.x * resolutionSize.y; for (auto c = 0; c < resolutionChannels; c++) { const auto offsetChannelC = c*offsetBetweenChannels; - for (auto y = 0; y < resolutionSize.height; y++) + for (auto y = 0; y < resolutionSize.y; y++) { - const auto cvMatOffsetY = y*resolutionSize.width; - const auto floatImageOffsetY = offsetChannelC + y*resolutionSize.width; - for (auto x = 0; x < resolutionSize.width; x++) + const auto cvMatOffsetY = y*resolutionSize.x; + const auto floatImageOffsetY = offsetChannelC + y*resolutionSize.x; + for (auto x = 0; x < resolutionSize.x; x++) { const auto value = uchar( fastTruncate(intRound(floatImage[floatImageOffsetY + x]), 0, 255) ); cvMat.at(resolutionChannels*(cvMatOffsetY + x) + c) = value; @@ -140,12 +140,12 @@ namespace op } } - double resizeGetScaleFactor(const cv::Size& initialSize, const cv::Size& targetSize) + double resizeGetScaleFactor(const Point& initialSize, const Point& targetSize) { try { - const auto ratioWidth = targetSize.width / (double)initialSize.width; - const auto ratioHeight = targetSize.height / (double)initialSize.height; + const auto ratioWidth = targetSize.x / (double)initialSize.x; + const auto ratioHeight = targetSize.y / (double)initialSize.y; return fastMin(ratioWidth, ratioHeight); } catch (const std::exception& e) @@ -155,16 +155,17 @@ namespace op } } - cv::Mat resizeFixedAspectRatio(const cv::Mat& cvMat, const double scaleFactor, const cv::Size& targetSize, const int borderMode, const cv::Scalar& borderValue) + cv::Mat resizeFixedAspectRatio(const cv::Mat& cvMat, const double scaleFactor, const Point& targetSize, const int borderMode, const cv::Scalar& borderValue) { try { + const cv::Size cvTargetSize{targetSize.x, targetSize.y}; cv::Mat resultingCvMat; cv::Mat M = cv::Mat::eye(2,3,CV_64F); M.at(0,0) = scaleFactor; M.at(1,1) = scaleFactor; - if (scaleFactor != 1. || targetSize != cvMat.size()) - cv::warpAffine(cvMat, resultingCvMat, M, targetSize, (scaleFactor < 1. ? cv::INTER_AREA : cv::INTER_CUBIC), borderMode, borderValue); + if (scaleFactor != 1. || cvTargetSize != cvMat.size()) + cv::warpAffine(cvMat, resultingCvMat, M, cvTargetSize, (scaleFactor < 1. ? cv::INTER_AREA : cv::INTER_CUBIC), borderMode, borderValue); else resultingCvMat = cvMat.clone(); return resultingCvMat; diff --git a/src/openpose/wrapper/wrapperStructFace.cpp b/src/openpose/wrapper/wrapperStructFace.cpp index d65dd7d4..86061a15 100644 --- a/src/openpose/wrapper/wrapperStructFace.cpp +++ b/src/openpose/wrapper/wrapperStructFace.cpp @@ -2,11 +2,13 @@ namespace op { - namespace experimental + WrapperStructFace::WrapperStructFace(const bool enable_, const Point& netInputSize_, const bool renderOutput_, const float alphaKeypoint_, + const float alphaHeatMap_) : + enable{enable_}, + netInputSize{netInputSize_}, + renderOutput{renderOutput_}, + alphaKeypoint{alphaKeypoint_}, + alphaHeatMap{alphaHeatMap_} { - WrapperStructFace::WrapperStructFace(const bool extractAndRenderFace_) : - extractAndRenderFace{extractAndRenderFace_} - { - } } } diff --git a/src/openpose/wrapper/wrapperStructOutput.cpp b/src/openpose/wrapper/wrapperStructOutput.cpp index 463e9fa1..65636ae4 100644 --- a/src/openpose/wrapper/wrapperStructOutput.cpp +++ b/src/openpose/wrapper/wrapperStructOutput.cpp @@ -2,16 +2,16 @@ namespace op { - WrapperStructOutput::WrapperStructOutput(const bool displayGui_, const bool guiVerbose_, const bool fullScreen_, const std::string& writePose_, - const DataFormat writePoseDataFormat_, const std::string& writePoseJson_, const std::string& writeCocoJson_, + WrapperStructOutput::WrapperStructOutput(const bool displayGui_, const bool guiVerbose_, const bool fullScreen_, const std::string& writeKeypoint_, + const DataFormat writeKeypointFormat_, const std::string& writeKeypointJson_, const std::string& writeCocoJson_, const std::string& writeImages_, const std::string& writeImagesFormat_, const std::string& writeVideo_, const std::string& writeHeatMaps_, const std::string& writeHeatMapsFormat_) : displayGui{displayGui_}, guiVerbose{guiVerbose_}, fullScreen{fullScreen_}, - writePose{writePose_}, - writePoseDataFormat{writePoseDataFormat_}, - writePoseJson{writePoseJson_}, + writeKeypoint{writeKeypoint_}, + writeKeypointFormat{writeKeypointFormat_}, + writeKeypointJson{writeKeypointJson_}, writeCocoJson{writeCocoJson_}, writeImages{writeImages_}, writeImagesFormat{writeImagesFormat_}, diff --git a/src/openpose/wrapper/wrapperStructPose.cpp b/src/openpose/wrapper/wrapperStructPose.cpp index 9f07be4a..5d1a3b0e 100644 --- a/src/openpose/wrapper/wrapperStructPose.cpp +++ b/src/openpose/wrapper/wrapperStructPose.cpp @@ -2,14 +2,14 @@ namespace op { - WrapperStructPose::WrapperStructPose(const cv::Size& netInputSize_, const cv::Size& outputSize_, const ScaleMode poseScaleMode_, const int gpuNumber_, + WrapperStructPose::WrapperStructPose(const Point& netInputSize_, const Point& outputSize_, const ScaleMode keypointScale_, const int gpuNumber_, const int gpuNumberStart_, const int scalesNumber_, const float scaleGap_, const bool renderOutput_, - const PoseModel poseModel_, const bool blendOriginalFrame_, const float alphaPose_, const float alphaHeatMap_, + const PoseModel poseModel_, const bool blendOriginalFrame_, const float alphaKeypoint_, const float alphaHeatMap_, const int defaultPartToRender_, const std::string& modelFolder_, const std::vector& heatMapTypes_, - const ScaleMode heatMapScaleMode_) : + const ScaleMode heatMapScale_) : netInputSize{netInputSize_}, outputSize{outputSize_}, - poseScaleMode{poseScaleMode_}, + keypointScale{keypointScale_}, gpuNumber{gpuNumber_}, gpuNumberStart{gpuNumberStart_}, scalesNumber{scalesNumber_}, @@ -17,12 +17,12 @@ namespace op renderOutput{renderOutput_}, poseModel{poseModel_}, blendOriginalFrame{blendOriginalFrame_}, - alphaPose{alphaPose_}, + alphaKeypoint{alphaKeypoint_}, alphaHeatMap{alphaHeatMap_}, defaultPartToRender{defaultPartToRender_}, modelFolder{modelFolder_}, heatMapTypes{heatMapTypes_}, - heatMapScaleMode{heatMapScaleMode_} + heatMapScale{heatMapScale_} { } }