提交 063c0354 编写于 作者: G gineshidalgo99

More general COCO JSON generator

上级 caa794cf
......@@ -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}
#!/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());
......
#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);
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)
{
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};
}
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)
// Foot
else if (cocoJsonFormat == CocoJsonFormat::Foot)
{
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);
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 (mCocoJsonFormat == CocoJsonFormat::Face)
{
imageId = frameNumber;
if (numberBodyParts == 135)
// Face
else if (cocoJsonFormat == CocoJsonFormat::Face)
{
indexesInCocoOrder = std::vector<int>(70);
std::iota(indexesInCocoOrder.begin(), indexesInCocoOrder.end(), F135);
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)
// Hand21
else if (cocoJsonFormat == CocoJsonFormat::Hand21)
{
// 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);
if (numberBodyParts == 135)
{
indexesInCocoOrder = std::vector<int>(21);
indexesInCocoOrder[0] = 10;
std::iota(indexesInCocoOrder.begin()+1, indexesInCocoOrder.end(), H135+20);
}
}
}
// 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)
// Hand42
else if (cocoJsonFormat == CocoJsonFormat::Hand42)
{
// At least 1 valid keypoint?
foundAtLeast1Keypoint = false;
for (auto bodyPart = 0u ; bodyPart < indexesInCocoOrder.size() ; bodyPart++)
if (numberBodyParts == 135)
{
const auto finalIndex = 3*(person*numberBodyParts + indexesInCocoOrder.at(bodyPart));
const auto validPoint = (poseKeypoints[finalIndex+2] > 0.f);
if (validPoint)
{
foundAtLeast1Keypoint = true;
break;
}
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);
}
}
if (foundAtLeast1Keypoint)
// 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++)
{
// Comma at any moment but first element
if (mFirstElementAdded)
bool foundAtLeast1Keypoint = true;
// Foot
if (cocoJsonFormat == CocoJsonFormat::Foot)
{
mJsonOfstream.comma();
mJsonOfstream.enter();
// At least 1 valid keypoint?
foundAtLeast1Keypoint = false;
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);
if (validPoint)
{
foundAtLeast1Keypoint = true;
break;
}
}
}
else
mFirstElementAdded = true;
// New element
mJsonOfstream.objectOpen();
if (foundAtLeast1Keypoint)
{
// Comma at any moment but first element
if (firstElementAdded)
{
jsonOfstream.comma();
jsonOfstream.enter();
}
else
firstElementAdded = true;
// image_id
mJsonOfstream.key("image_id");
mJsonOfstream.plainText(imageId);
mJsonOfstream.comma();
// New element
jsonOfstream.objectOpen();
// category_id
mJsonOfstream.key("category_id");
mJsonOfstream.plainText("1");
mJsonOfstream.comma();
// image_id
jsonOfstream.key("image_id");
jsonOfstream.plainText(imageId);
jsonOfstream.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();
// category_id
jsonOfstream.key("category_id");
jsonOfstream.plainText("1");
jsonOfstream.comma();
// score
mJsonOfstream.key("score");
mJsonOfstream.plainText(poseScores[person]);
// 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();
mJsonOfstream.objectClose();
// score
jsonOfstream.key("score");
jsonOfstream.plainText(poseScores[person]);
jsonOfstream.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_},
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册