提交 91e466fe 编写于 作者: G gineshidalgo99

Keypoints saved in unique JSON file

上级 1f94ea31
......@@ -126,7 +126,8 @@ You just need to remove the OpenPose folder, by default called `openpose/`. E.g.
3. You can now compile it.
6. Download the body pose models:
1. Download the [COCO model (18 key-points)](http://posefs1.perception.cs.cmu.edu/Users/tsimon/Projects/coco/data/models/coco/pose_iter_440000.caffemodel) as `{openpose_folder}\models\pose\coco\pose_iter_440000.caffemodel`.
2. (Optionally) download the [MPI model (15 key-points, faster and less memory than COCO)](http://posefs1.perception.cs.cmu.edu/Users/tsimon/Projects/coco/data/models/mpi/pose_iter_160000.caffemodel) as `{openpose_folder}\models\pose\mpi\pose_iter_160000.caffemodel`.
2. Download the [face model (70 key-points)](http://posefs1.perception.cs.cmu.edu/OpenPose/models/face/pose_iter_116000.caffemodel) as `{openpose_folder}\models\face\pose_iter_116000.caffemodel`.
3. (Optionally) download the [MPI model (15 key-points, faster and less memory than COCO)](http://posefs1.perception.cs.cmu.edu/Users/tsimon/Projects/coco/data/models/mpi/pose_iter_160000.caffemodel) as `{openpose_folder}\models\pose\mpi\pose_iter_160000.caffemodel`.
7. If you have a webcam connected, you can test it by pressing the F5 key or the green play icon.
8. Otherwise, check [Quick Start](#quick-start) to verify OpenPose was properly compiled. In order to use the created exe from the command line, you have to:
1. Copy all the DLLs located on `{openpose_folder}\3rdparty\caffe\caffe-windows\build\install\bin\` on the exe folder: `{openpose_folder}\windows_project\x64\Release`.
......
......@@ -154,7 +154,7 @@ DEFINE_string(write_heatmaps, "", "Directory to write heat
DEFINE_string(write_heatmaps_format, "png", "File extension and format for `write_heatmaps`, analogous to `write_images_format`."
" Recommended `png` or any compressed and lossless format.");
int opRealTimePoseDemo()
int openPoseDemo()
{
// logging_level
op::check(0 <= FLAGS_logging_level && FLAGS_logging_level <= 255, "Wrong logging_level value.", __LINE__, __FUNCTION__, __FILE__);
......@@ -250,11 +250,11 @@ int opRealTimePoseDemo()
int main(int argc, char *argv[])
{
// Initializing google logging (Caffe uses it for logging)
google::InitGoogleLogging("opRealTimePoseDemo");
google::InitGoogleLogging("openPoseDemo");
// Parsing command line flags
gflags::ParseCommandLineFlags(&argc, &argv, true);
// Running opRealTimePoseDemo
return opRealTimePoseDemo();
// Running openPoseDemo
return openPoseDemo();
}
......@@ -22,7 +22,10 @@ namespace op
cv::Mat loadData(const std::string& cvMatName, const std::string& fileNameNoExtension, const DataFormat format);
// Json - Saving as *.json not available in OpenCV verions < 3.0, this function is a quick fix
void saveKeypointsJson(const Array<float>& pose, const std::string& fileName, const bool humanReadable, const std::string& keypointName);
void saveKeypointsJson(const Array<float>& keypoints, const std::string& keypointName, const std::string& fileName, const bool humanReadable);
// It will save a bunch of Array<float> elements
void saveKeypointsJson(const std::vector<std::pair<Array<float>, std::string>>& keypointVector, const std::string& fileName, const bool humanReadable);
// Save/load image
void saveImage(const cv::Mat& cvMat, const std::string& fullFilePath, const std::vector<int>& openCvCompressionParams = {CV_IMWRITE_JPEG_QUALITY, 100, CV_IMWRITE_PNG_COMPRESSION, 9});
......
#ifndef OPENPOSE_FILESTREAM_HEADERS_HPP
#define OPENPOSE_FILESTREAM_HEADERS_HPP
// storage module
// fileStream module
#include "cocoJsonSaver.hpp"
#include "enumClasses.hpp"
#include "fileSaver.hpp"
......@@ -13,13 +13,11 @@
#include "keypointSaver.hpp"
#include "videoSaver.hpp"
#include "wCocoJsonSaver.hpp"
#include "wFaceJsonSaver.hpp"
#include "wFaceSaver.hpp"
#include "wHandJsonSaver.hpp"
#include "wHandSaver.hpp"
#include "wImageSaver.hpp"
#include "wHeatMapSaver.hpp"
#include "wPoseJsonSaver.hpp"
#include "wKeypointJsonSaver.hpp"
#include "wPoseSaver.hpp"
#include "wVideoSaver.hpp"
......
......@@ -13,7 +13,8 @@ namespace op
public:
KeypointJsonSaver(const std::string& directoryPath);
void save(const std::vector<Array<float>>& keypointVector, const std::string& fileName, const std::string& keypointName) const;
void save(const std::vector<std::pair<Array<float>, std::string>>& keypointVector,
const std::string& fileName, const bool humanReadable = true) const;
};
}
......
#ifndef OPENPOSE_FILESTREAM_W_HAND_JSON_SAVER_HPP
#define OPENPOSE_FILESTREAM_W_HAND_JSON_SAVER_HPP
#include <memory> // std::shared_ptr
#include <string>
#include <openpose/thread/workerConsumer.hpp>
#include "keypointJsonSaver.hpp"
namespace op
{
template<typename TDatums>
class WHandJsonSaver : public WorkerConsumer<TDatums>
{
public:
explicit WHandJsonSaver(const std::shared_ptr<KeypointJsonSaver>& keypointJsonSaver);
void initializationOnThread();
void workConsumer(const TDatums& tDatums);
private:
const std::shared_ptr<KeypointJsonSaver> spKeypointJsonSaver;
DELETE_COPY(WHandJsonSaver);
};
}
// Implementation
#include <openpose/utilities/errorAndLog.hpp>
#include <openpose/utilities/macros.hpp>
#include <openpose/utilities/pointerContainer.hpp>
#include <openpose/utilities/profiler.hpp>
namespace op
{
template<typename TDatums>
WHandJsonSaver<TDatums>::WHandJsonSaver(const std::shared_ptr<KeypointJsonSaver>& keypointJsonSaver) :
spKeypointJsonSaver{keypointJsonSaver}
{
}
template<typename TDatums>
void WHandJsonSaver<TDatums>::initializationOnThread()
{
}
template<typename TDatums>
void WHandJsonSaver<TDatums>::workConsumer(const TDatums& tDatums)
{
try
{
if (checkNoNullNorEmpty(tDatums))
{
// Debugging log
dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
// Profiling speed
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
// T* to T
auto& tDatumsNoPtr = *tDatums;
// Record people hand data in json format
const auto fileName = (!tDatumsNoPtr[0].name.empty() ? tDatumsNoPtr[0].name : std::to_string(tDatumsNoPtr[0].id));
std::vector<Array<float>> keypointVector(tDatumsNoPtr.size());
// Left hand
for (auto i = 0; i < tDatumsNoPtr.size(); i++)
keypointVector[i] = tDatumsNoPtr[i].handKeypoints[0];
spKeypointJsonSaver->save(keypointVector, fileName, "hand_left_keypoints");
// Right hand
for (auto i = 0; i < tDatumsNoPtr.size(); i++)
keypointVector[i] = tDatumsNoPtr[i].handKeypoints[1];
spKeypointJsonSaver->save(keypointVector, fileName, "hand_right_keypoints");
// Profiling speed
Profiler::timerEnd(profilerKey);
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X);
// Debugging log
dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
}
}
catch (const std::exception& e)
{
this->stop();
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
COMPILE_TEMPLATE_DATUM(WHandJsonSaver);
}
#endif // OPENPOSE_FILESTREAM_W_HAND_JSON_SAVER_HPP
#ifndef OPENPOSE_FILESTREAM_W_FACE_JSON_SAVER_HPP
#define OPENPOSE_FILESTREAM_W_FACE_JSON_SAVER_HPP
#ifndef OPENPOSE_FILESTREAM_W_KEYPOINT_JSON_SAVER_HPP
#define OPENPOSE_FILESTREAM_W_KEYPOINT_JSON_SAVER_HPP
#include <memory> // std::shared_ptr
#include <string>
......@@ -9,10 +9,10 @@
namespace op
{
template<typename TDatums>
class WFaceJsonSaver : public WorkerConsumer<TDatums>
class WKeypointJsonSaver : public WorkerConsumer<TDatums>
{
public:
explicit WFaceJsonSaver(const std::shared_ptr<KeypointJsonSaver>& keypointJsonSaver);
explicit WKeypointJsonSaver(const std::shared_ptr<KeypointJsonSaver>& keypointJsonSaver);
void initializationOnThread();
......@@ -21,7 +21,7 @@ namespace op
private:
const std::shared_ptr<KeypointJsonSaver> spKeypointJsonSaver;
DELETE_COPY(WFaceJsonSaver);
DELETE_COPY(WKeypointJsonSaver);
};
}
......@@ -37,18 +37,18 @@ namespace op
namespace op
{
template<typename TDatums>
WFaceJsonSaver<TDatums>::WFaceJsonSaver(const std::shared_ptr<KeypointJsonSaver>& keypointJsonSaver) :
WKeypointJsonSaver<TDatums>::WKeypointJsonSaver(const std::shared_ptr<KeypointJsonSaver>& keypointJsonSaver) :
spKeypointJsonSaver{keypointJsonSaver}
{
}
template<typename TDatums>
void WFaceJsonSaver<TDatums>::initializationOnThread()
void WKeypointJsonSaver<TDatums>::initializationOnThread()
{
}
template<typename TDatums>
void WFaceJsonSaver<TDatums>::workConsumer(const TDatums& tDatums)
void WKeypointJsonSaver<TDatums>::workConsumer(const TDatums& tDatums)
{
try
{
......@@ -58,14 +58,26 @@ namespace op
dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
// Profiling speed
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
// T* to T
auto& tDatumsNoPtr = *tDatums;
// Record people face data in json format
std::vector<Array<float>> keypointVector(tDatumsNoPtr.size());
for (auto i = 0; i < tDatumsNoPtr.size(); i++)
keypointVector[i] = tDatumsNoPtr[i].faceKeypoints;
const auto fileName = (!tDatumsNoPtr[0].name.empty() ? tDatumsNoPtr[0].name : std::to_string(tDatumsNoPtr[0].id));
spKeypointJsonSaver->save(keypointVector, fileName, "face_keypoints");
// Save body/face/hand keypoints to JSON file
const auto& tDatumFirst = (*tDatums)[0];
const auto baseFileName = (!tDatumFirst.name.empty() ? tDatumFirst.name
: std::to_string(tDatumFirst.id)) + "_keypoints";
const bool humanReadable = true;
for (auto i = 0 ; i < tDatums->size() ; i++)
{
const auto& tDatum = (*tDatums)[i];
// const auto fileName = baseFileName;
const auto fileName = baseFileName + (i != 0 ? "_" + std::to_string(i) : "");
const std::vector<std::pair<Array<float>, std::string>> keypointVector{
std::make_pair(tDatum.poseKeypoints, "pose_keypoints"),
std::make_pair(tDatum.faceKeypoints, "face_keypoints"),
std::make_pair(tDatum.handKeypoints[0], "hand_left_keypoints"),
std::make_pair(tDatum.handKeypoints[1], "hand_right_keypoints")
};
// Save keypoints
spKeypointJsonSaver->save(keypointVector, fileName, humanReadable);
}
// Profiling speed
Profiler::timerEnd(profilerKey);
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X);
......@@ -80,7 +92,7 @@ namespace op
}
}
COMPILE_TEMPLATE_DATUM(WFaceJsonSaver);
COMPILE_TEMPLATE_DATUM(WKeypointJsonSaver);
}
#endif // OPENPOSE_FILESTREAM_W_FACE_JSON_SAVER_HPP
#endif // OPENPOSE_FILESTREAM_W_KEYPOINT_JSON_SAVER_HPP
#ifndef OPENPOSE_FILESTREAM_W_POSE_JSON_SAVER_HPP
#define OPENPOSE_FILESTREAM_W_POSE_JSON_SAVER_HPP
#include <memory> // std::shared_ptr
#include <string>
#include <openpose/thread/workerConsumer.hpp>
#include "keypointJsonSaver.hpp"
namespace op
{
template<typename TDatums>
class WPoseJsonSaver : public WorkerConsumer<TDatums>
{
public:
explicit WPoseJsonSaver(const std::shared_ptr<KeypointJsonSaver>& keypointJsonSaver);
void initializationOnThread();
void workConsumer(const TDatums& tDatums);
private:
const std::shared_ptr<KeypointJsonSaver> spKeypointJsonSaver;
DELETE_COPY(WPoseJsonSaver);
};
}
// Implementation
#include <openpose/utilities/errorAndLog.hpp>
#include <openpose/utilities/macros.hpp>
#include <openpose/utilities/pointerContainer.hpp>
#include <openpose/utilities/profiler.hpp>
namespace op
{
template<typename TDatums>
WPoseJsonSaver<TDatums>::WPoseJsonSaver(const std::shared_ptr<KeypointJsonSaver>& keypointJsonSaver) :
spKeypointJsonSaver{keypointJsonSaver}
{
}
template<typename TDatums>
void WPoseJsonSaver<TDatums>::initializationOnThread()
{
}
template<typename TDatums>
void WPoseJsonSaver<TDatums>::workConsumer(const TDatums& tDatums)
{
try
{
if (checkNoNullNorEmpty(tDatums))
{
// Debugging log
dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
// Profiling speed
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
// T* to T
auto& tDatumsNoPtr = *tDatums;
// Record people pose data in json format
std::vector<Array<float>> keypointVector(tDatumsNoPtr.size());
for (auto i = 0; i < tDatumsNoPtr.size(); i++)
keypointVector[i] = tDatumsNoPtr[i].poseKeypoints;
const auto fileName = (!tDatumsNoPtr[0].name.empty() ? tDatumsNoPtr[0].name : std::to_string(tDatumsNoPtr[0].id));
spKeypointJsonSaver->save(keypointVector, fileName, "pose_keypoints");
// Profiling speed
Profiler::timerEnd(profilerKey);
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, Profiler::DEFAULT_X);
// Debugging log
dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
}
}
catch (const std::exception& e)
{
this->stop();
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
COMPILE_TEMPLATE_DATUM(WPoseJsonSaver);
}
#endif // OPENPOSE_FILESTREAM_W_POSE_JSON_SAVER_HPP
......@@ -781,11 +781,7 @@ namespace op
if (!writeKeypointJsonCleaned.empty())
{
const auto keypointJsonSaver = std::make_shared<KeypointJsonSaver>(writeKeypointJsonCleaned);
mOutputWs.emplace_back(std::make_shared<WPoseJsonSaver<TDatumsPtr>>(keypointJsonSaver));
if (wrapperStructFace.enable)
mOutputWs.emplace_back(std::make_shared<WFaceJsonSaver<TDatumsPtr>>(keypointJsonSaver));
if (wrapperStructHand.enable)
mOutputWs.emplace_back(std::make_shared<WHandJsonSaver<TDatumsPtr>>(keypointJsonSaver));
mOutputWs.emplace_back(std::make_shared<WKeypointJsonSaver<TDatumsPtr>>(keypointJsonSaver));
}
// Write people pose data on disk (COCO validation json format)
if (!wrapperStructOutput.writeCocoJson.empty())
......
......@@ -3,13 +3,11 @@
namespace op
{
DEFINE_TEMPLATE_DATUM(WCocoJsonSaver);
DEFINE_TEMPLATE_DATUM(WFaceJsonSaver);
DEFINE_TEMPLATE_DATUM(WFaceSaver);
DEFINE_TEMPLATE_DATUM(WHandJsonSaver);
DEFINE_TEMPLATE_DATUM(WHandSaver);
DEFINE_TEMPLATE_DATUM(WHeatMapSaver);
DEFINE_TEMPLATE_DATUM(WImageSaver);
DEFINE_TEMPLATE_DATUM(WPoseJsonSaver);
DEFINE_TEMPLATE_DATUM(WKeypointJsonSaver);
DEFINE_TEMPLATE_DATUM(WPoseSaver);
DEFINE_TEMPLATE_DATUM(WVideoSaver);
}
......@@ -134,15 +134,26 @@ namespace op
}
}
void saveKeypointsJson(const Array<float>& pose, const std::string& fileName, const bool humanReadable, const std::string& keypointName)
void saveKeypointsJson(const Array<float>& keypoints, const std::string& keypointName, const std::string& fileName, const bool humanReadable)
{
try
{
if (!pose.empty() && pose.getNumberDimensions() != 3)
error("pose.getNumberDimensions() != 3.", __LINE__, __FUNCTION__, __FILE__);
saveKeypointsJson(std::vector<std::pair<Array<float>, std::string>>{std::make_pair(keypoints, keypointName)}, fileName, humanReadable);
}
catch (const std::exception& e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
const auto numberPeople = pose.getSize(0);
const auto numberBodyParts = pose.getSize(1);
void saveKeypointsJson(const std::vector<std::pair<Array<float>, std::string>>& keypointVector, const std::string& fileName, const bool humanReadable)
{
try
{
// Security checks
for (const auto& keypointPair : keypointVector)
if (!keypointPair.first.empty() && keypointPair.first.getNumberDimensions() != 3 )
error("keypointVector.getNumberDimensions() != 3.", __LINE__, __FUNCTION__, __FILE__);
// Record frame on desired path
JsonOfstream jsonOfstream{fileName, humanReadable};
......@@ -150,30 +161,40 @@ namespace op
// Version
jsonOfstream.key("version");
jsonOfstream.plainText("0.1");
jsonOfstream.plainText("1.0");
jsonOfstream.comma();
// Bodies
jsonOfstream.key("people");
jsonOfstream.arrayOpen();
const auto numberPeople = (keypointVector.size() > 0 ? keypointVector[0].first.getSize(0) : 0);
for (auto person = 0 ; person < numberPeople ; person++)
{
jsonOfstream.objectOpen();
jsonOfstream.key(keypointName);
jsonOfstream.arrayOpen();
// Body parts
for (auto bodyPart = 0 ; bodyPart < numberBodyParts ; bodyPart++)
for (auto vectorIndex = 0 ; vectorIndex < keypointVector.size() ; vectorIndex++)
{
const auto finalIndex = 3*(person*numberBodyParts + bodyPart);
jsonOfstream.plainText(pose[finalIndex]);
jsonOfstream.comma();
jsonOfstream.plainText(pose[finalIndex+1]);
jsonOfstream.comma();
jsonOfstream.plainText(pose[finalIndex+2]);
if (bodyPart < numberBodyParts-1)
const auto& keypoints = keypointVector[vectorIndex].first;
const auto& keypointName = keypointVector[vectorIndex].second;
const auto numberBodyParts = keypoints.getSize(1);
jsonOfstream.key(keypointName);
jsonOfstream.arrayOpen();
// Body parts
for (auto bodyPart = 0 ; bodyPart < numberBodyParts ; bodyPart++)
{
const auto finalIndex = 3*(person*numberBodyParts + bodyPart);
jsonOfstream.plainText(keypoints[finalIndex]);
jsonOfstream.comma();
jsonOfstream.plainText(keypoints[finalIndex+1]);
jsonOfstream.comma();
jsonOfstream.plainText(keypoints[finalIndex+2]);
if (bodyPart < numberBodyParts-1)
jsonOfstream.comma();
}
jsonOfstream.arrayClose();
if (vectorIndex < keypointVector.size()-1)
jsonOfstream.comma();
}
jsonOfstream.arrayClose();
jsonOfstream.objectClose();
if (person < numberPeople-1)
{
......
......@@ -9,23 +9,14 @@ namespace op
{
}
void KeypointJsonSaver::save(const std::vector<Array<float>>& keypointVector, const std::string& fileName, const std::string& keypointName) const
void KeypointJsonSaver::save(const std::vector<std::pair<Array<float>, std::string>>& keypointVector,
const std::string& fileName, const bool humanReadable) const
{
try
{
// Record json
if (!keypointVector.empty())
{
// File path (no extension)
const auto fileNameNoExtension = getNextFileName(fileName) + "_" + keypointName;
const bool humanReadable = true;
for (auto i = 0; i < keypointVector.size(); i++)
{
const auto finalFileName = fileNameNoExtension + (i != 0 ? "_" + std::to_string(i) : "") + ".json";
saveKeypointsJson(keypointVector[i], finalFileName, humanReadable, keypointName);
}
}
const auto finalFileName = getNextFileName(fileName) + ".json";
saveKeypointsJson(keypointVector, finalFileName, humanReadable);
}
catch (const std::exception& e)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册