mirror of
https://github.com/gosticks/openpose.git
synced 2026-08-12 04:10:28 +00:00
More general COCO JSON generator
This commit is contained in:
@@ -241,9 +241,9 @@ Each flag is divided into flag name, default value, and description.
|
||||
- DEFINE_string(write_video_3d, "", "Analogous to `--write_video`, but applied to the 3D output.");
|
||||
- DEFINE_string(write_video_adam, "", "Experimental, not available yet. Analogous to `--write_video`, but applied to Adam model.");
|
||||
- DEFINE_string(write_json, "", "Directory to write OpenPose output in JSON format. It includes body, hand, and face pose keypoints (2-D and 3-D), as well as pose candidates (if `--part_candidates` enabled).");
|
||||
- DEFINE_string(write_coco_json, "", "Full file path to write people pose data with JSON COCO validation format.");
|
||||
- DEFINE_string(write_coco_foot_json, "", "Full file path to write people foot pose data with JSON COCO validation format.");
|
||||
- DEFINE_int32(write_coco_json_variant, 0, "Currently, this option is experimental and only makes effect on car JSON generation. It selects the COCO variant for cocoJsonSaver.");
|
||||
- DEFINE_string(write_coco_json, "", "Full file path to write people pose data with JSON COCO validation format. If foot, face, hands, etc. JSON is also desired (`--write_coco_json_variants`), they are saved with different file name suffix.");
|
||||
- DEFINE_int32(write_coco_json_variants, 1, "Add 1 for body, add 2 for foot, 4 for face, and/or 8 for hands. Use 0 to use all the possible candidates. E.g., 7 would mean body+foot+face COCO JSON.");
|
||||
- DEFINE_int32(write_coco_json_variant, 0, "Currently, this option is experimental and only makes effect on car JSON generation. It selects the COCO variant for cocoJsonSaver.");
|
||||
- DEFINE_string(write_heatmaps, "", "Directory to write body pose heatmaps in 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`. For lossless compression, recommended `png` for integer `heatmaps_scale` and `float` for floating values.");
|
||||
- DEFINE_string(write_keypoint, "", "(Deprecated, use `write_json`) Directory to write the people pose keypoint data. Set format with `write_keypoint_format`.");
|
||||
|
||||
@@ -323,6 +323,7 @@ OpenPose Library - Release Notes
|
||||
31. Removed boost::shared_ptr and caffe::Blob dependencies from the headers. No 3rdparty dependencies left on headers (except dim3 for CUDA).
|
||||
32. Added Array `poseNetOutput` to Datum so that user can introduce his custom network output.
|
||||
33. OpenPose will never provoke a core dumped or crash. Exceptions in threads (`errorWorker()` instead of `error()`) lead to stopping the threads and reporting the error from the main thread, while exceptions in destructors (`errorDestructor()` instead of `error()`) are reported with std::cerr but not thrown as std::exceptions.
|
||||
34. When reading a directory of images, they will be sorted in natural order (rather than regular sort).
|
||||
2. Functions or parameters renamed:
|
||||
1. By default, python example `tutorial_developer/python_2_pose_from_heatmaps.py` was using 2 scales starting at -1x736, changed to 1 scale at -1x368.
|
||||
2. WrapperStructPose default parameters changed to match those of the OpenPose demo binary.
|
||||
@@ -339,6 +340,7 @@ OpenPose Library - Release Notes
|
||||
11. Moved most sh scripts into the `scripts/` folder. Only models/getModels.sh and the `*.bat` files are kept under `models/` and `3rdparty/windows`.
|
||||
12. For Python compatibility and scalability increase, template `TDatums` used for `include/openpose/wrapper/wrapper.hpp` has changed from `std::vector<Datum>` to `std::vector<std::shared_ptr<Datum>>`, including the respective changes in all the worker classes. In addition, some template classes have been simplified to only take 1 template parameter for user simplicity.
|
||||
13. Renamed intRound, charRound, etc. by positiveIntRound, positiveCharRound, etc. so that people can realize it is not safe for negative numbers.
|
||||
14. Replaced flag `--write_coco_foot_json` by `--write_coco_json_variants` in order to generalize to any COCO JSON format (i.e., hand, face, etc).
|
||||
3. Main bugs fixed:
|
||||
1. CMake-GUI was forcing to Release mode, allowed Debug modes too.
|
||||
2. NMS returns in index 0 the number of found peaks. However, while the number of peaks was truncated to a maximum of 127, this index 0 was saving the real number instead of the truncated one.
|
||||
|
||||
@@ -96,7 +96,7 @@ void configureWrapper(op::Wrapper& opWrapper)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -114,7 +114,7 @@ void configureWrapper(op::WrapperT<op::UserDatum>& opWrapperT)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -132,7 +132,7 @@ void configureWrapper(op::Wrapper& opWrapper)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -134,7 +134,7 @@ void configureWrapper(op::Wrapper& opWrapper)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -140,7 +140,7 @@ void configureWrapper(op::Wrapper& opWrapper)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -135,7 +135,7 @@ void configureWrapper(op::Wrapper& opWrapper)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -135,7 +135,7 @@ void configureWrapper(op::Wrapper& opWrapper)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -164,7 +164,7 @@ void configureWrapper(op::Wrapper& opWrapper)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -135,7 +135,7 @@ void configureWrapper(op::Wrapper& opWrapper)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -146,7 +146,7 @@ void configureWrapper(op::Wrapper& opWrapper)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -171,7 +171,7 @@ void configureWrapper(op::Wrapper& opWrapper)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -243,7 +243,7 @@ void configureWrapper(op::WrapperT<UserDatum>& opWrapperT)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -159,7 +159,7 @@ void configureWrapper(op::Wrapper& opWrapper)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -129,7 +129,7 @@ void configureWrapper(op::Wrapper& opWrapper)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -130,7 +130,7 @@ void configureWrapper(op::Wrapper& opWrapper)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -186,7 +186,7 @@ void configureWrapper(op::Wrapper& opWrapper)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -299,7 +299,7 @@ void configureWrapper(op::WrapperT<UserDatum>& opWrapperT)
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -23,7 +23,8 @@ namespace op
|
||||
*/
|
||||
explicit CocoJsonSaver(
|
||||
const std::string& filePathToSave, const PoseModel poseModel, const bool humanReadable = true,
|
||||
const CocoJsonFormat cocoJsonFormat = CocoJsonFormat::Body, const int mCocoJsonVariant = 0);
|
||||
const int cocoJsonVariants = 1, const CocoJsonFormat cocoJsonFormat = CocoJsonFormat::Body,
|
||||
const int cocoJsonVariant = 0);
|
||||
|
||||
virtual ~CocoJsonSaver();
|
||||
|
||||
@@ -33,10 +34,8 @@ namespace op
|
||||
|
||||
private:
|
||||
const PoseModel mPoseModel;
|
||||
const CocoJsonFormat mCocoJsonFormat;
|
||||
const int mCocoJsonVariant;
|
||||
JsonOfstream mJsonOfstream;
|
||||
bool mFirstElementAdded;
|
||||
std::vector<std::tuple<JsonOfstream, CocoJsonFormat, bool>> mJsonOfstreams;
|
||||
|
||||
DELETE_COPY(CocoJsonSaver);
|
||||
};
|
||||
|
||||
@@ -14,7 +14,8 @@ namespace op
|
||||
enum class CocoJsonFormat : unsigned char
|
||||
{
|
||||
Body,
|
||||
Hand,
|
||||
Hand21,
|
||||
Hand42,
|
||||
Face,
|
||||
Foot,
|
||||
Car,
|
||||
|
||||
@@ -11,6 +11,21 @@ namespace op
|
||||
public:
|
||||
explicit JsonOfstream(const std::string& filePath, const bool humanReadable = true);
|
||||
|
||||
/**
|
||||
* Move constructor.
|
||||
* It destroys the original JsonOfstream to be moved.
|
||||
* @param array JsonOfstream to be moved.
|
||||
*/
|
||||
JsonOfstream(JsonOfstream&& jsonOfstream);
|
||||
|
||||
/**
|
||||
* Move assignment.
|
||||
* Similar to JsonOfstream(JsonOfstream&& jsonOfstream).
|
||||
* @param array JsonOfstream to be moved.
|
||||
* @return The resulting JsonOfstream.
|
||||
*/
|
||||
JsonOfstream& operator=(JsonOfstream&& jsonOfstream);
|
||||
|
||||
virtual ~JsonOfstream();
|
||||
|
||||
void objectOpen();
|
||||
@@ -39,7 +54,7 @@ namespace op
|
||||
void enter();
|
||||
|
||||
private:
|
||||
const bool mHumanReadable;
|
||||
bool mHumanReadable;
|
||||
long long mBracesCounter;
|
||||
long long mBracketsCounter;
|
||||
std::ofstream mOfstream;
|
||||
|
||||
@@ -243,9 +243,12 @@ DEFINE_string(write_video_3d, "", "Analogous to `--write_v
|
||||
DEFINE_string(write_video_adam, "", "Experimental, not available yet. Analogous to `--write_video`, but applied to Adam model.");
|
||||
DEFINE_string(write_json, "", "Directory to write OpenPose output in JSON format. It includes body, hand, and face pose"
|
||||
" keypoints (2-D and 3-D), as well as pose candidates (if `--part_candidates` enabled).");
|
||||
DEFINE_string(write_coco_json, "", "Full file path to write people pose data with JSON COCO validation format.");
|
||||
DEFINE_string(write_coco_foot_json, "", "Full file path to write people foot pose data with JSON COCO validation format.");
|
||||
DEFINE_int32(write_coco_json_variant, 0, "Currently, this option is experimental and only makes effect on car JSON generation. It"
|
||||
DEFINE_string(write_coco_json, "", "Full file path to write people pose data with JSON COCO validation format. If foot, face,"
|
||||
" hands, etc. JSON is also desired (`--write_coco_json_variants`), they are saved with"
|
||||
" different file name suffix.");
|
||||
DEFINE_int32(write_coco_json_variants, 1, "Add 1 for body, add 2 for foot, 4 for face, and/or 8 for hands. Use 0 to use all the"
|
||||
" possible candidates. E.g., 7 would mean body+foot+face COCO JSON.");
|
||||
DEFINE_int32(write_coco_json_variant, 0, "Currently, this option is experimental and only makes effect on car JSON generation. It"
|
||||
" selects the COCO variant for cocoJsonSaver.");
|
||||
DEFINE_string(write_heatmaps, "", "Directory to write body pose heatmaps in PNG format. At least 1 `add_heatmaps_X` flag"
|
||||
" must be enabled.");
|
||||
|
||||
@@ -667,7 +667,7 @@ namespace op
|
||||
outputWs.emplace_back(std::make_shared<WHandSaver<TDatumsSP>>(keypointSaver));
|
||||
}
|
||||
log("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
|
||||
// Write OpenPose output data on disk in json format (body/hand/face keypoints, body part locations if
|
||||
// Write OpenPose output data on disk in JSON format (body/hand/face keypoints, body part locations if
|
||||
// enabled, etc.)
|
||||
if (!writeJsonCleaned.empty())
|
||||
{
|
||||
@@ -676,7 +676,7 @@ namespace op
|
||||
outputWs.emplace_back(std::make_shared<WPeopleJsonSaver<TDatumsSP>>(peopleJsonSaver));
|
||||
}
|
||||
log("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
|
||||
// Write people pose data on disk (COCO validation json format)
|
||||
// Write people pose/foot/face/hand/etc. data on disk (COCO validation JSON format)
|
||||
if (!wrapperStructOutput.writeCocoJson.empty())
|
||||
{
|
||||
log("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
|
||||
@@ -684,6 +684,7 @@ namespace op
|
||||
const auto humanFormat = true;
|
||||
const auto cocoJsonSaver = std::make_shared<CocoJsonSaver>(
|
||||
wrapperStructOutput.writeCocoJson, wrapperStructPose.poseModel, humanFormat,
|
||||
wrapperStructOutput.writeCocoJsonVariants,
|
||||
(wrapperStructPose.poseModel != PoseModel::CAR_22
|
||||
&& wrapperStructPose.poseModel != PoseModel::CAR_12
|
||||
? CocoJsonFormat::Body : CocoJsonFormat::Car),
|
||||
@@ -691,16 +692,6 @@ namespace op
|
||||
outputWs.emplace_back(std::make_shared<WCocoJsonSaver<TDatumsSP>>(cocoJsonSaver));
|
||||
}
|
||||
log("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
|
||||
// Write people foot pose data on disk (COCO validation json format for foot data)
|
||||
if (!wrapperStructOutput.writeCocoFootJson.empty())
|
||||
{
|
||||
// If humanFormat: bigger size (& maybe slower to process), but easier for user to read it
|
||||
const auto humanFormat = true;
|
||||
const auto cocoJsonSaver = std::make_shared<CocoJsonSaver>(
|
||||
wrapperStructOutput.writeCocoFootJson, wrapperStructPose.poseModel, humanFormat,
|
||||
CocoJsonFormat::Foot);
|
||||
outputWs.emplace_back(std::make_shared<WCocoJsonSaver<TDatumsSP>>(cocoJsonSaver));
|
||||
}
|
||||
log("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
|
||||
// Write frames as desired image format on hard disk
|
||||
if (!writeImagesCleaned.empty())
|
||||
|
||||
@@ -51,9 +51,11 @@ namespace op
|
||||
std::string writeCocoJson;
|
||||
|
||||
/**
|
||||
* Analogous to writeCocoJson but for foot keypoints.
|
||||
* It selects the COCO variants for cocoJsonSaver.
|
||||
* Add 1 for body, add 2 for foot, 4 for face, and/or 8 for hands. Use 0 to use all the possible candidates.
|
||||
* E.g., 7 would mean body+foot+face COCO JSON..
|
||||
*/
|
||||
std::string writeCocoFootJson;
|
||||
int writeCocoJsonVariants;
|
||||
|
||||
/**
|
||||
* Experimental option (only makes effect on car JSON generation).
|
||||
@@ -148,7 +150,7 @@ namespace op
|
||||
WrapperStructOutput(
|
||||
const double verbose = -1, const std::string& writeKeypoint = "",
|
||||
const DataFormat writeKeypointFormat = DataFormat::Xml, const std::string& writeJson = "",
|
||||
const std::string& writeCocoJson = "", const std::string& writeCocoFootJson = "",
|
||||
const std::string& writeCocoJson = "", const int writeCocoJsonVariants = 1,
|
||||
const int writeCocoJsonVariant = 1, const std::string& writeImages = "",
|
||||
const std::string& writeImagesFormat = "", const std::string& writeVideo = "",
|
||||
const double writeVideoFps = -1., const bool writeVideoWithAudio = false,
|
||||
|
||||
@@ -129,7 +129,7 @@ public:
|
||||
// Output (comment or use default argument to disable any output)
|
||||
const op::WrapperStructOutput wrapperStructOutput{
|
||||
FLAGS_cli_verbose, FLAGS_write_keypoint, op::stringToDataFormat(FLAGS_write_keypoint_format),
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_foot_json, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_json, FLAGS_write_coco_json, FLAGS_write_coco_json_variants, FLAGS_write_coco_json_variant,
|
||||
FLAGS_write_images, FLAGS_write_images_format, FLAGS_write_video, FLAGS_write_video_fps,
|
||||
FLAGS_write_video_with_audio, FLAGS_write_heatmaps, FLAGS_write_heatmaps_format, FLAGS_write_video_3d,
|
||||
FLAGS_write_video_adam, FLAGS_write_bvh, FLAGS_udp_host, FLAGS_udp_port};
|
||||
|
||||
@@ -16,14 +16,14 @@ JSON_FOLDER=../evaluation/coco_val_jsons/
|
||||
OP_BIN=./build/examples/openpose/openpose.bin
|
||||
|
||||
# 1 scale
|
||||
$OP_BIN --image_dir $IMAGE_FOLDER --display 0 --render_pose 0 --cli_verbose 0.2 --write_coco_json ${JSON_FOLDER}1.json --write_coco_foot_json ${JSON_FOLDER}1_foot.json
|
||||
# $OP_BIN --image_dir $IMAGE_FOLDER --display 0 --render_pose 0 --cli_verbose 0.2 --write_coco_json ${JSON_FOLDER}1_max.json --write_coco_foot_json ${JSON_FOLDER}1_foot_max.json \
|
||||
$OP_BIN --image_dir $IMAGE_FOLDER --display 0 --render_pose 0 --cli_verbose 0.2 --write_coco_json ${JSON_FOLDER}1.json --write_coco_json_variants 3
|
||||
# $OP_BIN --image_dir $IMAGE_FOLDER --display 0 --render_pose 0 --cli_verbose 0.2 --write_coco_json ${JSON_FOLDER}1_max.json --write_coco_json_variants 3 \
|
||||
# --maximize_positives
|
||||
|
||||
# # 4 scales
|
||||
# $OP_BIN --image_dir $IMAGE_FOLDER --display 0 --render_pose 0 --cli_verbose 0.2 --write_coco_json ${JSON_FOLDER}1_4.json --write_coco_foot_json ${JSON_FOLDER}4_foot.json \
|
||||
# $OP_BIN --image_dir $IMAGE_FOLDER --display 0 --render_pose 0 --cli_verbose 0.2 --write_coco_json ${JSON_FOLDER}1_4.json --write_coco_json_variants 3 \
|
||||
# --scale_number 4 --scale_gap 0.25 --net_resolution "1312x736"
|
||||
# $OP_BIN --image_dir $IMAGE_FOLDER --display 0 --render_pose 0 --cli_verbose 0.2 --write_coco_json ${JSON_FOLDER}1_4_max.json --write_coco_foot_json ${JSON_FOLDER}4_foot_max.json \
|
||||
# $OP_BIN --image_dir $IMAGE_FOLDER --display 0 --render_pose 0 --cli_verbose 0.2 --write_coco_json ${JSON_FOLDER}1_4_max.json --write_coco_json_variants 3 \
|
||||
# --scale_number 4 --scale_gap 0.25 --net_resolution "1312x736" --maximize_positives
|
||||
# # \
|
||||
# # --model_pose BODY_23 --model_folder ${JSON_FOLDER}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
|
||||
# Script for internal use. We might completely change it continuously and we will not answer questions about it.
|
||||
|
||||
clear && clear
|
||||
|
||||
# USAGE EXAMPLE
|
||||
# See ./scripts/tests/pose_accuracy_coco_test.sh
|
||||
|
||||
# Parameters
|
||||
IMAGE_FOLDER=/home/gines/devel/images/val2017/
|
||||
JSON_FOLDER=../evaluation/coco_val_jsons/
|
||||
OP_BIN=./build/examples/openpose/openpose.bin
|
||||
|
||||
# 1 scale
|
||||
$OP_BIN --image_dir $IMAGE_FOLDER --write_coco_foot_json ${JSON_FOLDER}1_foot.json --write_coco_json ${JSON_FOLDER}1.json --display 0 --render_pose 0
|
||||
|
||||
# # 4 scales
|
||||
# $OP_BIN --model_pose BODY_25 --image_dir $IMAGE_FOLDER --write_coco_foot_json ${JSON_FOLDER}1_4_foot.json --display 0 --render_pose 0 --scale_number 4 --scale_gap 0.25 --net_resolution "1312x736"
|
||||
@@ -41,12 +41,14 @@ namespace op
|
||||
// Add extrinsics if not empty
|
||||
if (!cameraExtrinsics.empty())
|
||||
mCameraExtrinsics.emplace_back(cameraExtrinsics.clone());
|
||||
else
|
||||
mCameraExtrinsics.emplace_back(cv::Mat::eye(3, 4, cameraIntrinsics.type()));
|
||||
// Add extrinsics (initial) if not empty
|
||||
if (!cameraExtrinsicsInitial.empty())
|
||||
mCameraExtrinsicsInitial.emplace_back(cameraExtrinsicsInitial.clone());
|
||||
// Otherwise, add cv::eye
|
||||
else
|
||||
mCameraExtrinsics.emplace_back(cv::Mat::eye(3, 4, cameraIntrinsics.type()));
|
||||
mCameraExtrinsicsInitial.emplace_back(cv::Mat::eye(3, 4, cameraIntrinsics.type()));
|
||||
mCameraMatrices.emplace_back(mCameraIntrinsics.back() * mCameraExtrinsics.back());
|
||||
// Undistortion cv::Mats
|
||||
mRemoveDistortionMaps1.resize(getNumberCameras());
|
||||
|
||||
@@ -1,38 +1,69 @@
|
||||
#include <numeric> // std::iota
|
||||
#include <openpose/pose/poseParametersRender.hpp>
|
||||
#include <openpose/utilities/fileSystem.hpp>
|
||||
#include <openpose/utilities/string.hpp>
|
||||
#include <openpose/filestream/cocoJsonSaver.hpp>
|
||||
|
||||
namespace op
|
||||
{
|
||||
CocoJsonSaver::CocoJsonSaver(const std::string& filePathToSave, const PoseModel poseModel,
|
||||
const bool humanReadable, const CocoJsonFormat cocoJsonFormat,
|
||||
const int cocoJsonVariant) :
|
||||
const bool humanReadable, const int cocoJsonVariants,
|
||||
const CocoJsonFormat cocoJsonFormat, const int cocoJsonVariant) :
|
||||
mPoseModel{poseModel},
|
||||
mCocoJsonFormat{cocoJsonFormat},
|
||||
mCocoJsonVariant{cocoJsonVariant},
|
||||
mJsonOfstream{filePathToSave, humanReadable},
|
||||
mFirstElementAdded{false}
|
||||
mCocoJsonVariant{cocoJsonVariant}
|
||||
{
|
||||
try
|
||||
{
|
||||
// Sanity check
|
||||
// Sanity checks
|
||||
if (filePathToSave.empty())
|
||||
error("Empty path given as output file path for saving COCO JSON format.",
|
||||
__LINE__, __FUNCTION__, __FILE__);
|
||||
if (cocoJsonVariants >= 32)
|
||||
error("Unkown value for cocoJsonFormat (flag `--write_coco_json_variants`).",
|
||||
__LINE__, __FUNCTION__, __FILE__);
|
||||
// Open mJsonOfstreams
|
||||
const auto filePath = getFullFilePathNoExtension(filePathToSave);
|
||||
const auto extension = getFileExtension(filePathToSave);
|
||||
// Body/cars
|
||||
if (cocoJsonVariants % 2 == 1 || cocoJsonVariants < 1)
|
||||
mJsonOfstreams.emplace_back(
|
||||
std::make_tuple(JsonOfstream{filePathToSave, humanReadable}, cocoJsonFormat, false));
|
||||
// Foot
|
||||
if ((cocoJsonVariants/2) % 2 == 1 || cocoJsonVariants < 1)
|
||||
mJsonOfstreams.emplace_back(
|
||||
std::make_tuple(JsonOfstream{filePath+"_foot."+extension, humanReadable}, CocoJsonFormat::Foot,
|
||||
false));
|
||||
// Face
|
||||
if ((cocoJsonVariants/4) % 2 == 1 || cocoJsonVariants < 1)
|
||||
mJsonOfstreams.emplace_back(
|
||||
std::make_tuple(JsonOfstream{filePath+"_face."+extension, humanReadable}, CocoJsonFormat::Face,
|
||||
false));
|
||||
// Hand21
|
||||
if ((cocoJsonVariants/8) % 2 == 1 || cocoJsonVariants < 1)
|
||||
mJsonOfstreams.emplace_back(
|
||||
std::make_tuple(JsonOfstream{filePath+"_hand21."+extension, humanReadable}, CocoJsonFormat::Hand21,
|
||||
false));
|
||||
// Hand42
|
||||
if ((cocoJsonVariants/16) % 2 == 1 || cocoJsonVariants < 1)
|
||||
mJsonOfstreams.emplace_back(
|
||||
std::make_tuple(JsonOfstream{filePath+"_hand42."+extension, humanReadable}, CocoJsonFormat::Hand42,
|
||||
false));
|
||||
// Open array
|
||||
mJsonOfstream.arrayOpen();
|
||||
for (auto& jsonOfstream : mJsonOfstreams)
|
||||
std::get<0>(jsonOfstream).arrayOpen();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
|
||||
}
|
||||
}
|
||||
|
||||
CocoJsonSaver::~CocoJsonSaver()
|
||||
{
|
||||
try
|
||||
{
|
||||
mJsonOfstream.arrayClose();
|
||||
for (auto& jsonOfstream : mJsonOfstreams)
|
||||
std::get<0>(jsonOfstream).arrayClose();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -54,153 +85,171 @@ namespace op
|
||||
if (numberPeople > 0)
|
||||
{
|
||||
const auto numberBodyParts = poseKeypoints.getSize(1);
|
||||
// Get indexesInCocoOrder
|
||||
std::vector<int> indexesInCocoOrder;
|
||||
// Body/car
|
||||
auto imageId = getLastNumber(imageName);
|
||||
if (mCocoJsonFormat == CocoJsonFormat::Body)
|
||||
// Iterate over all JsonOfstreams
|
||||
for (auto& jsonOfstreamAndFormat : mJsonOfstreams)
|
||||
{
|
||||
// Body
|
||||
if (numberBodyParts == 23)
|
||||
indexesInCocoOrder = std::vector<int>{0, 14,13,16,15, 4,1,5,2,6, 3,10,7,11, 8, 12, 9};
|
||||
else if (numberBodyParts == 18)
|
||||
indexesInCocoOrder = std::vector<int>{0, 15,14,17,16, 5,2,6,3,7, 4,11,8,12, 9, 13,10};
|
||||
else if (mPoseModel == PoseModel::BODY_25B || mPoseModel == PoseModel::BODY_95
|
||||
|| mPoseModel == PoseModel::BODY_135)
|
||||
auto& jsonOfstream = std::get<0>(jsonOfstreamAndFormat);
|
||||
const auto cocoJsonFormat = std::get<1>(jsonOfstreamAndFormat);
|
||||
auto& firstElementAdded = std::get<2>(jsonOfstreamAndFormat);
|
||||
// Get indexesInCocoOrder
|
||||
std::vector<int> indexesInCocoOrder;
|
||||
// Body/car
|
||||
auto imageId = frameNumber;
|
||||
if (cocoJsonFormat == CocoJsonFormat::Body)
|
||||
{
|
||||
indexesInCocoOrder = std::vector<int>(17);
|
||||
std::iota(indexesInCocoOrder.begin(), indexesInCocoOrder.end(), 0);
|
||||
}
|
||||
else if (numberBodyParts == 19 || numberBodyParts == 25 || numberBodyParts == 59)
|
||||
indexesInCocoOrder = std::vector<int>{0, 16,15,18,17, 5,2,6,3,7, 4,12,9,13,10, 14,11};
|
||||
// else if (numberBodyParts == 23)
|
||||
// indexesInCocoOrder = std::vector<int>{18,21,19,22,20, 4,1,5,2,6, 3,13,8,14, 9, 15,10};
|
||||
}
|
||||
// Hand
|
||||
else if (mCocoJsonFormat == CocoJsonFormat::Hand)
|
||||
{
|
||||
imageId = frameNumber;
|
||||
if (numberBodyParts == 135)
|
||||
{
|
||||
indexesInCocoOrder = std::vector<int>(42);
|
||||
indexesInCocoOrder[0] = 9;
|
||||
std::iota(indexesInCocoOrder.begin()+1, indexesInCocoOrder.end(), H135);
|
||||
indexesInCocoOrder[21] = 10;
|
||||
std::iota(indexesInCocoOrder.begin()+2, indexesInCocoOrder.end(), H135+20);
|
||||
}
|
||||
}
|
||||
// Face
|
||||
else if (mCocoJsonFormat == CocoJsonFormat::Face)
|
||||
{
|
||||
imageId = frameNumber;
|
||||
if (numberBodyParts == 135)
|
||||
{
|
||||
indexesInCocoOrder = std::vector<int>(70);
|
||||
std::iota(indexesInCocoOrder.begin(), indexesInCocoOrder.end(), F135);
|
||||
}
|
||||
}
|
||||
// Foot
|
||||
else if (mCocoJsonFormat == CocoJsonFormat::Foot)
|
||||
{
|
||||
if (numberBodyParts == 25 || numberBodyParts > 60)
|
||||
indexesInCocoOrder = std::vector<int>{19,20,21, 22,23,24};
|
||||
else if (numberBodyParts == 23)
|
||||
indexesInCocoOrder = std::vector<int>{17,18,19, 20,21,22};
|
||||
}
|
||||
// Car
|
||||
else if (mCocoJsonFormat == CocoJsonFormat::Car)
|
||||
{
|
||||
// Car12
|
||||
if (numberBodyParts == 12)
|
||||
indexesInCocoOrder = std::vector<int>{0,1,2,3, 4,5,6,7, 8, 8,9,10,11, 11};
|
||||
// Car22
|
||||
else if (numberBodyParts == 22)
|
||||
{
|
||||
// Dataset 1
|
||||
if (mCocoJsonVariant == 0)
|
||||
indexesInCocoOrder = std::vector<int>{0,1,2,3, 6,7, 12,13,14,15, 16,17};
|
||||
// Dataset 2
|
||||
else if (mCocoJsonVariant == 1)
|
||||
indexesInCocoOrder = std::vector<int>{0,1,2,3, 6,7, 12,13,14,15, 20,21};
|
||||
// Dataset 3
|
||||
else if (mCocoJsonVariant == 2)
|
||||
for (auto i = 0 ; i < 20 ; i++)
|
||||
indexesInCocoOrder.emplace_back(i);
|
||||
}
|
||||
}
|
||||
// Sanity check
|
||||
if (indexesInCocoOrder.empty())
|
||||
error("Invalid number of body parts (" + std::to_string(numberBodyParts) + ").",
|
||||
__LINE__, __FUNCTION__, __FILE__);
|
||||
// Save on JSON file
|
||||
for (auto person = 0 ; person < numberPeople ; person++)
|
||||
{
|
||||
bool foundAtLeast1Keypoint = true;
|
||||
// Foot
|
||||
if (mCocoJsonFormat == CocoJsonFormat::Foot)
|
||||
{
|
||||
// At least 1 valid keypoint?
|
||||
foundAtLeast1Keypoint = false;
|
||||
for (auto bodyPart = 0u ; bodyPart < indexesInCocoOrder.size() ; bodyPart++)
|
||||
imageId = getLastNumber(imageName);
|
||||
// Body
|
||||
if (numberBodyParts == 23)
|
||||
indexesInCocoOrder = std::vector<int>{0, 14,13,16,15, 4,1,5,2,6, 3,10,7,11, 8, 12, 9};
|
||||
else if (numberBodyParts == 18)
|
||||
indexesInCocoOrder = std::vector<int>{0, 15,14,17,16, 5,2,6,3,7, 4,11,8,12, 9, 13,10};
|
||||
else if (mPoseModel == PoseModel::BODY_25B || mPoseModel == PoseModel::BODY_95
|
||||
|| mPoseModel == PoseModel::BODY_135)
|
||||
{
|
||||
const auto finalIndex = 3*(person*numberBodyParts + indexesInCocoOrder.at(bodyPart));
|
||||
const auto validPoint = (poseKeypoints[finalIndex+2] > 0.f);
|
||||
if (validPoint)
|
||||
indexesInCocoOrder = std::vector<int>(17);
|
||||
std::iota(indexesInCocoOrder.begin(), indexesInCocoOrder.end(), 0);
|
||||
}
|
||||
else if (numberBodyParts == 19 || numberBodyParts == 25 || numberBodyParts == 59)
|
||||
indexesInCocoOrder = std::vector<int>{0, 16,15,18,17, 5,2,6,3,7, 4,12,9,13,10, 14,11};
|
||||
// else if (numberBodyParts == 23)
|
||||
// indexesInCocoOrder = std::vector<int>{18,21,19,22,20, 4,1,5,2,6, 3,13,8,14, 9, 15,10};
|
||||
}
|
||||
// Foot
|
||||
else if (cocoJsonFormat == CocoJsonFormat::Foot)
|
||||
{
|
||||
imageId = getLastNumber(imageName);
|
||||
if (numberBodyParts == 25 || numberBodyParts > 60)
|
||||
indexesInCocoOrder = std::vector<int>{19,20,21, 22,23,24};
|
||||
else if (numberBodyParts == 23)
|
||||
indexesInCocoOrder = std::vector<int>{17,18,19, 20,21,22};
|
||||
}
|
||||
// Face
|
||||
else if (cocoJsonFormat == CocoJsonFormat::Face)
|
||||
{
|
||||
if (numberBodyParts == 135)
|
||||
{
|
||||
indexesInCocoOrder = std::vector<int>(70);
|
||||
std::iota(indexesInCocoOrder.begin(), indexesInCocoOrder.end(), F135);
|
||||
}
|
||||
}
|
||||
// Hand21
|
||||
else if (cocoJsonFormat == CocoJsonFormat::Hand21)
|
||||
{
|
||||
if (numberBodyParts == 135)
|
||||
{
|
||||
indexesInCocoOrder = std::vector<int>(21);
|
||||
indexesInCocoOrder[0] = 10;
|
||||
std::iota(indexesInCocoOrder.begin()+1, indexesInCocoOrder.end(), H135+20);
|
||||
}
|
||||
}
|
||||
// Hand42
|
||||
else if (cocoJsonFormat == CocoJsonFormat::Hand42)
|
||||
{
|
||||
if (numberBodyParts == 135)
|
||||
{
|
||||
indexesInCocoOrder = std::vector<int>(42);
|
||||
indexesInCocoOrder[0] = 9;
|
||||
std::iota(indexesInCocoOrder.begin()+1, indexesInCocoOrder.end(), H135);
|
||||
indexesInCocoOrder[21] = 10;
|
||||
std::iota(indexesInCocoOrder.begin()+22, indexesInCocoOrder.end(), H135+20);
|
||||
}
|
||||
}
|
||||
// Car
|
||||
else if (cocoJsonFormat == CocoJsonFormat::Car)
|
||||
{
|
||||
imageId = getLastNumber(imageName);
|
||||
// Car12
|
||||
if (numberBodyParts == 12)
|
||||
indexesInCocoOrder = std::vector<int>{0,1,2,3, 4,5,6,7, 8, 8,9,10,11, 11};
|
||||
// Car22
|
||||
else if (numberBodyParts == 22)
|
||||
{
|
||||
// Dataset 1
|
||||
if (mCocoJsonVariant == 0)
|
||||
indexesInCocoOrder = std::vector<int>{0,1,2,3, 6,7, 12,13,14,15, 16,17};
|
||||
// Dataset 2
|
||||
else if (mCocoJsonVariant == 1)
|
||||
indexesInCocoOrder = std::vector<int>{0,1,2,3, 6,7, 12,13,14,15, 20,21};
|
||||
// Dataset 3
|
||||
else if (mCocoJsonVariant == 2)
|
||||
for (auto i = 0 ; i < 20 ; i++)
|
||||
indexesInCocoOrder.emplace_back(i);
|
||||
}
|
||||
}
|
||||
// Sanity check
|
||||
if (indexesInCocoOrder.empty())
|
||||
error("Invalid number of body parts (" + std::to_string(numberBodyParts) + ").",
|
||||
__LINE__, __FUNCTION__, __FILE__);
|
||||
// Save on JSON file
|
||||
for (auto person = 0 ; person < numberPeople ; person++)
|
||||
{
|
||||
bool foundAtLeast1Keypoint = true;
|
||||
// Foot
|
||||
if (cocoJsonFormat == CocoJsonFormat::Foot)
|
||||
{
|
||||
// At least 1 valid keypoint?
|
||||
foundAtLeast1Keypoint = false;
|
||||
for (auto bodyPart = 0u ; bodyPart < indexesInCocoOrder.size() ; bodyPart++)
|
||||
{
|
||||
foundAtLeast1Keypoint = true;
|
||||
break;
|
||||
const auto finalIndex = 3*(person*numberBodyParts + indexesInCocoOrder.at(bodyPart));
|
||||
const auto validPoint = (poseKeypoints[finalIndex+2] > 0.f);
|
||||
if (validPoint)
|
||||
{
|
||||
foundAtLeast1Keypoint = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foundAtLeast1Keypoint)
|
||||
{
|
||||
// Comma at any moment but first element
|
||||
if (mFirstElementAdded)
|
||||
if (foundAtLeast1Keypoint)
|
||||
{
|
||||
mJsonOfstream.comma();
|
||||
mJsonOfstream.enter();
|
||||
// Comma at any moment but first element
|
||||
if (firstElementAdded)
|
||||
{
|
||||
jsonOfstream.comma();
|
||||
jsonOfstream.enter();
|
||||
}
|
||||
else
|
||||
firstElementAdded = true;
|
||||
|
||||
// New element
|
||||
jsonOfstream.objectOpen();
|
||||
|
||||
// image_id
|
||||
jsonOfstream.key("image_id");
|
||||
jsonOfstream.plainText(imageId);
|
||||
jsonOfstream.comma();
|
||||
|
||||
// category_id
|
||||
jsonOfstream.key("category_id");
|
||||
jsonOfstream.plainText("1");
|
||||
jsonOfstream.comma();
|
||||
|
||||
// keypoints - i.e., poseKeypoints
|
||||
jsonOfstream.key("keypoints");
|
||||
jsonOfstream.arrayOpen();
|
||||
for (auto bodyPart = 0u ; bodyPart < indexesInCocoOrder.size() ; bodyPart++)
|
||||
{
|
||||
const auto finalIndex = 3*(person*numberBodyParts + indexesInCocoOrder.at(bodyPart));
|
||||
const auto validPoint = (poseKeypoints[finalIndex+2] > 0.f);
|
||||
jsonOfstream.plainText(validPoint ? poseKeypoints[finalIndex] : -1.f);
|
||||
jsonOfstream.comma();
|
||||
jsonOfstream.plainText(validPoint ? poseKeypoints[finalIndex+1] : -1.f);
|
||||
jsonOfstream.comma();
|
||||
jsonOfstream.plainText(validPoint ? 1 : 0);
|
||||
// jsonOfstream.plainText(poseKeypoints[finalIndex+2]); // For debugging
|
||||
if (bodyPart < indexesInCocoOrder.size() - 1u)
|
||||
jsonOfstream.comma();
|
||||
}
|
||||
jsonOfstream.arrayClose();
|
||||
jsonOfstream.comma();
|
||||
|
||||
// score
|
||||
jsonOfstream.key("score");
|
||||
jsonOfstream.plainText(poseScores[person]);
|
||||
|
||||
jsonOfstream.objectClose();
|
||||
}
|
||||
else
|
||||
mFirstElementAdded = true;
|
||||
|
||||
// New element
|
||||
mJsonOfstream.objectOpen();
|
||||
|
||||
// image_id
|
||||
mJsonOfstream.key("image_id");
|
||||
mJsonOfstream.plainText(imageId);
|
||||
mJsonOfstream.comma();
|
||||
|
||||
// category_id
|
||||
mJsonOfstream.key("category_id");
|
||||
mJsonOfstream.plainText("1");
|
||||
mJsonOfstream.comma();
|
||||
|
||||
// keypoints - i.e., poseKeypoints
|
||||
mJsonOfstream.key("keypoints");
|
||||
mJsonOfstream.arrayOpen();
|
||||
for (auto bodyPart = 0u ; bodyPart < indexesInCocoOrder.size() ; bodyPart++)
|
||||
{
|
||||
const auto finalIndex = 3*(person*numberBodyParts + indexesInCocoOrder.at(bodyPart));
|
||||
const auto validPoint = (poseKeypoints[finalIndex+2] > 0.f);
|
||||
mJsonOfstream.plainText(validPoint ? poseKeypoints[finalIndex] : -1.f);
|
||||
mJsonOfstream.comma();
|
||||
mJsonOfstream.plainText(validPoint ? poseKeypoints[finalIndex+1] : -1.f);
|
||||
mJsonOfstream.comma();
|
||||
mJsonOfstream.plainText(validPoint ? 1 : 0);
|
||||
// mJsonOfstream.plainText(poseKeypoints[finalIndex+2]); // For debugging
|
||||
if (bodyPart < indexesInCocoOrder.size() - 1u)
|
||||
mJsonOfstream.comma();
|
||||
}
|
||||
mJsonOfstream.arrayClose();
|
||||
mJsonOfstream.comma();
|
||||
|
||||
// score
|
||||
mJsonOfstream.key("score");
|
||||
mJsonOfstream.plainText(poseScores[person]);
|
||||
|
||||
mJsonOfstream.objectClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,39 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
JsonOfstream::JsonOfstream(JsonOfstream&& jsonOfstream) :
|
||||
mHumanReadable{jsonOfstream.mHumanReadable},
|
||||
mBracesCounter{jsonOfstream.mBracesCounter},
|
||||
mBracketsCounter{jsonOfstream.mBracketsCounter}
|
||||
{
|
||||
try
|
||||
{
|
||||
std::swap(mOfstream, jsonOfstream.mOfstream);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
|
||||
}
|
||||
}
|
||||
|
||||
JsonOfstream& JsonOfstream::operator=(JsonOfstream&& jsonOfstream)
|
||||
{
|
||||
try
|
||||
{
|
||||
mHumanReadable = jsonOfstream.mHumanReadable;
|
||||
mBracesCounter = jsonOfstream.mBracesCounter;
|
||||
mBracketsCounter = jsonOfstream.mBracketsCounter;
|
||||
std::swap(mOfstream, jsonOfstream.mOfstream);
|
||||
// Return
|
||||
return *this;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
JsonOfstream::~JsonOfstream()
|
||||
{
|
||||
try
|
||||
|
||||
@@ -636,7 +636,7 @@ namespace op
|
||||
|
||||
OP_API void _OPConfigureOutput(
|
||||
double verbose, char* writeKeypoint, uchar writeKeypointFormat, // DataFormat
|
||||
char* writeJson, char* writeCocoJson, char* writeCocoFootJson, int writeCocoJsonVariant, char* writeImages,
|
||||
char* writeJson, char* writeCocoJson, int writeCocoJsonVariants, int writeCocoJsonVariant, char* writeImages,
|
||||
char* writeImagesFormat, char* writeVideo, double writeVideoFps, bool writeVideoWithAudio,
|
||||
char* writeHeatMaps, char* writeHeatMapsFormat, char* writeVideo3D, char* writeVideoAdam, char* writeBvh,
|
||||
char* udpHost, char* udpPort)
|
||||
@@ -645,7 +645,7 @@ namespace op
|
||||
{
|
||||
spWrapperStructOutput = std::make_shared<WrapperStructOutput>(
|
||||
verbose, writeKeypoint, (DataFormat) writeKeypointFormat, writeJson, writeCocoJson,
|
||||
writeCocoFootJson, writeCocoJsonVariant, writeImages, writeImagesFormat, writeVideo, writeVideoFps,
|
||||
writeCocoJsonVariants, writeCocoJsonVariant, writeImages, writeImagesFormat, writeVideo, writeVideoFps,
|
||||
writeVideoWithAudio, writeHeatMaps, writeHeatMapsFormat, writeVideo3D, writeVideoAdam, writeBvh,
|
||||
udpHost, udpPort);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,39 @@
|
||||
|
||||
namespace op
|
||||
{
|
||||
bool compareNat(const std::string& a, const std::string& b)
|
||||
{
|
||||
if (a.empty())
|
||||
return true;
|
||||
else if (b.empty())
|
||||
return false;
|
||||
else if (std::isdigit(a[0]) && !std::isdigit(b[0]))
|
||||
return true;
|
||||
else if (!std::isdigit(a[0]) && std::isdigit(b[0]))
|
||||
return false;
|
||||
else if (!std::isdigit(a[0]) && !std::isdigit(b[0]))
|
||||
{
|
||||
if (std::toupper(a[0]) == std::toupper(b[0]))
|
||||
return compareNat(a.substr(1), b.substr(1));
|
||||
return (std::toupper(a[0]) < std::toupper(b[0]));
|
||||
}
|
||||
|
||||
// Both strings begin with digit --> parse both numbers
|
||||
std::istringstream issa(a);
|
||||
std::istringstream issb(b);
|
||||
int ia, ib;
|
||||
issa >> ia;
|
||||
issb >> ib;
|
||||
if (ia != ib)
|
||||
return ia < ib;
|
||||
|
||||
// Numbers are the same --> remove numbers and recurse
|
||||
std::string anew, bnew;
|
||||
std::getline(issa, anew);
|
||||
std::getline(issb, bnew);
|
||||
return (compareNat(anew, bnew));
|
||||
}
|
||||
|
||||
void makeDirectory(const std::string& directoryPath)
|
||||
{
|
||||
try
|
||||
@@ -321,8 +354,10 @@ namespace op
|
||||
specificExtensionPaths.emplace_back(filePath);
|
||||
std::swap(filePaths, specificExtensionPaths);
|
||||
}
|
||||
// Sort alphabetically
|
||||
std::sort(filePaths.begin(), filePaths.end());
|
||||
// // Sort alphabetically
|
||||
// std::sort(filePaths.begin(), filePaths.end());
|
||||
// Natural sort
|
||||
std::sort(filePaths.begin(), filePaths.end(), compareNat);
|
||||
// Return result
|
||||
return filePaths;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,6 @@ namespace op
|
||||
!wrapperStructOutput.writeImages.empty() || !wrapperStructOutput.writeVideo.empty()
|
||||
|| !wrapperStructOutput.writeKeypoint.empty() || !wrapperStructOutput.writeJson.empty()
|
||||
|| !wrapperStructOutput.writeCocoJson.empty() || !wrapperStructOutput.writeHeatMaps.empty()
|
||||
|| !wrapperStructOutput.writeCocoFootJson.empty()
|
||||
);
|
||||
const auto savingCvOutput = (
|
||||
!wrapperStructOutput.writeImages.empty() || !wrapperStructOutput.writeVideo.empty()
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace op
|
||||
{
|
||||
WrapperStructOutput::WrapperStructOutput(
|
||||
const double verbose_, const std::string& writeKeypoint_, const DataFormat writeKeypointFormat_,
|
||||
const std::string& writeJson_, const std::string& writeCocoJson_, const std::string& writeCocoFootJson_,
|
||||
const std::string& writeJson_, const std::string& writeCocoJson_, const int writeCocoJsonVariants_,
|
||||
const int writeCocoJsonVariant_, const std::string& writeImages_, const std::string& writeImagesFormat_,
|
||||
const std::string& writeVideo_, const double writeVideoFps_, const bool writeVideoWithAudio_,
|
||||
const std::string& writeHeatMaps_, const std::string& writeHeatMapsFormat_, const std::string& writeVideo3D_,
|
||||
@@ -15,7 +15,7 @@ namespace op
|
||||
writeKeypointFormat{writeKeypointFormat_},
|
||||
writeJson{writeJson_},
|
||||
writeCocoJson{writeCocoJson_},
|
||||
writeCocoFootJson{writeCocoFootJson_},
|
||||
writeCocoJsonVariants{writeCocoJsonVariants_},
|
||||
writeCocoJsonVariant{writeCocoJsonVariant_},
|
||||
writeImages{writeImages_},
|
||||
writeImagesFormat{writeImagesFormat_},
|
||||
|
||||
Reference in New Issue
Block a user