Added face-hands hpp & render (no extraction code nor models)

This commit is contained in:
gineshidalgo99
2017-04-28 13:51:53 -04:00
parent a010676ccb
commit ac4607a893
89 changed files with 1642 additions and 711 deletions
-24
View File
@@ -1,24 +0,0 @@
#ifndef OPENPOSE__CORE__ARRAYS_SCALER_HPP
#define OPENPOSE__CORE__ARRAYS_SCALER_HPP
#include <vector>
#include "array.hpp"
#include "enumClasses.hpp"
namespace op
{
class ArrayScaler
{
public:
explicit ArrayScaler(const ScaleMode scalePose);
void scale(Array<float>& array, const double scaleInputToOutput, const double scaleNetToOutput, const cv::Size& producerSize) const;
void scale(std::vector<Array<float>>& arrays, const double scaleInputToOutput, const double scaleNetToOutput, const cv::Size& producerSize) const;
private:
const ScaleMode mScaleMode;
};
}
#endif // OPENPOSE__CORE__ARRAYS_SCALER_HPP
+13 -6
View File
@@ -52,15 +52,15 @@ namespace op
// -------------------------------------------------- Resulting Array<float> data parameters -------------------------------------------------- //
/**
* Pose (x,y,score) locations for each person in the image.
* Body pose (x,y,score) locations for each person in the image.
* It has been resized to the desired output resolution (e.g. `resolution` flag in the demo).
* If outputData is empty, then cvOutputData will also be empty.
* Size: #people x #body parts (e.g. 18 for COCO or 15 for MPI) x 3 ((x,y) coordinates + score)
*/
Array<float> poseKeyPoints;
Array<float> pose;
/**
* Pose heatmaps (body parts, background and PAFs) for the whole image.
* Body pose heatmaps (body parts, background and/or PAFs) for the whole image.
* This parameters is by default empty and disabled for performance. Each group (body parts, background and PAFs) can be individually enabled.
* #heatmaps = #body parts (if enabled) + 1 (if background enabled) + 2 x #PAFs (if enabled). Each PAF has 2 consecutive channels, one for x- and one for y-coordinates.
* Order heatmaps: body parts + background (as appears in POSE_BODY_PART_MAPPING) + (x,y) channel of each PAF (sorted as appears in POSE_BODY_PART_PAIRS). See `pose/poseParameters.hpp`.
@@ -71,10 +71,17 @@ namespace op
/**
* Experimental (NOT IMPLEMENTED YET)
* Hands code is in development phase. Not included in this version.
* Size: 2 (right and left hand) x #hand parts (21) x 3 ((x,y) coordinates + score)
* Face code is in development phase. Not included in this version.
* Size: #people's faces to render x #face parts (71) x 3 ((x,y) coordinates + score)
*/
Array<float> hands;
Array<float> faceKeyPoints;
/**
* Experimental (NOT IMPLEMENTED YET)
* Hands code is in development phase. Not included in this version.
* Size: #people's hands to render x 2 (right and left hand) x #hand parts (21) x 3 ((x,y) coordinates + score)
*/
Array<float> handKeyPoints;
// -------------------------------------------------- Other parameters -------------------------------------------------- //
double scaleInputToOutput; /**< Scale ratio between the input Datum::cvInputData and the output Datum::cvOutputData. */
+3 -3
View File
@@ -3,11 +3,11 @@
// core module
#include "array.hpp"
#include "arrayScaler.hpp"
#include "cvMatToOpInput.hpp"
#include "cvMatToOpOutput.hpp"
#include "datum.hpp"
#include "enumClasses.hpp"
#include "keyPointScaler.hpp"
#include "net.hpp"
#include "netCaffe.hpp"
#include "nmsBase.hpp"
@@ -16,10 +16,10 @@
#include "renderer.hpp"
#include "resizeAndMergeBase.hpp"
#include "resizeAndMergeCaffe.hpp"
#include "scalePose.hpp"
#include "wArrayScaler.hpp"
#include "scaleKeyPoints.hpp"
#include "wCvMatToOpInput.hpp"
#include "wCvMatToOpOutput.hpp"
#include "wKeyPointScaler.hpp"
#include "wOpOutputToCvMat.hpp"
#endif // OPENPOSE__CORE__HEADERS_HPP
+24
View File
@@ -0,0 +1,24 @@
#ifndef OPENPOSE__CORE__KEY_POINT_SCALER_HPP
#define OPENPOSE__CORE__KEY_POINT_SCALER_HPP
#include <vector>
#include "array.hpp"
#include "enumClasses.hpp"
namespace op
{
class KeyPointScaler
{
public:
explicit KeyPointScaler(const ScaleMode scaleMode);
void scale(Array<float>& arrayToScale, const double scaleInputToOutput, const double scaleNetToOutput, const cv::Size& producerSize) const;
void scale(std::vector<Array<float>>& arraysToScale, const double scaleInputToOutput, const double scaleNetToOutput, const cv::Size& producerSize) const;
private:
const ScaleMode mScaleMode;
};
}
#endif // OPENPOSE__CORE__KEY_POINT_SCALER_HPP
+15
View File
@@ -0,0 +1,15 @@
#ifndef OPENPOSE__CORE__SCALE_KEY_POINTS_HPP
#define OPENPOSE__CORE__SCALE_KEY_POINTS_HPP
#include "array.hpp"
namespace op
{
void scaleKeyPoints(Array<float>& keyPoints, const double scale);
void scaleKeyPoints(Array<float>& keyPoints, const double scaleX, const double scaleY);
void scaleKeyPoints(Array<float>& keyPoints, const double scaleX, const double scaleY, const double offsetX, const double offsetY);
}
#endif // OPENPOSE__CORE__SCALE_KEY_POINTS_HPP
-15
View File
@@ -1,15 +0,0 @@
#ifndef OPENPOSE__CORE__SCALE_POSE_HPP
#define OPENPOSE__CORE__SCALE_POSE_HPP
#include "array.hpp"
namespace op
{
void scalePose(Array<float>& pose, const double scale);
void scalePose(Array<float>& pose, const double scaleX, const double scaleY);
void scalePose(Array<float>& pose, const double scaleX, const double scaleY, const double offsetX, const double offsetY);
}
#endif // OPENPOSE__CORE__SCALE_POSE_HPP
@@ -1,24 +1,24 @@
#ifndef OPENPOSE__CORE__W_ARRAYS_SCALER_HPP
#define OPENPOSE__CORE__W_ARRAYS_SCALER_HPP
#ifndef OPENPOSE__CORE__W_KEY_POINT_SCALER_HPP
#define OPENPOSE__CORE__W_KEY_POINT_SCALER_HPP
#include "../thread/worker.hpp"
#include "arrayScaler.hpp"
#include "scalePose.hpp"
#include "keyPointScaler.hpp"
#include "scaleKeyPoints.hpp"
namespace op
{
template<typename TDatums>
class WArrayScaler : public Worker<TDatums>
class WKeyPointScaler : public Worker<TDatums>
{
public:
explicit WArrayScaler(const std::shared_ptr<ArrayScaler>& arrayScaler);
explicit WKeyPointScaler(const std::shared_ptr<KeyPointScaler>& keyPointScaler);
void initializationOnThread();
void work(TDatums& tDatums);
private:
std::shared_ptr<ArrayScaler> spArrayScaler;
std::shared_ptr<KeyPointScaler> spKeyPointScaler;
};
}
@@ -34,18 +34,18 @@ namespace op
namespace op
{
template<typename TDatums>
WArrayScaler<TDatums>::WArrayScaler(const std::shared_ptr<ArrayScaler>& arrayScaler) :
spArrayScaler{arrayScaler}
WKeyPointScaler<TDatums>::WKeyPointScaler(const std::shared_ptr<KeyPointScaler>& keyPointScaler) :
spKeyPointScaler{keyPointScaler}
{
}
template<typename TDatums>
void WArrayScaler<TDatums>::initializationOnThread()
void WKeyPointScaler<TDatums>::initializationOnThread()
{
}
template<typename TDatums>
void WArrayScaler<TDatums>::work(TDatums& tDatums)
void WKeyPointScaler<TDatums>::work(TDatums& tDatums)
{
try
{
@@ -58,8 +58,8 @@ namespace op
// Rescale pose data
for (auto& tDatum : *tDatums)
{
std::vector<Array<float>> arrays{tDatum.pose, tDatum.hands};
spArrayScaler->scale(arrays, tDatum.scaleInputToOutput, tDatum.scaleNetToOutput, tDatum.cvInputData.size());
std::vector<Array<float>> arraysToScale{tDatum.poseKeyPoints, tDatum.handKeyPoints, tDatum.faceKeyPoints};
spKeyPointScaler->scale(arraysToScale, tDatum.scaleInputToOutput, tDatum.scaleNetToOutput, tDatum.cvInputData.size());
}
// Profiling speed
Profiler::timerEnd(profilerKey);
@@ -76,7 +76,7 @@ namespace op
}
}
COMPILE_TEMPLATE_DATUM(WArrayScaler);
COMPILE_TEMPLATE_DATUM(WKeyPointScaler);
}
#endif // OPENPOSE__CORE__W_ARRAYS_SCALER_HPP
#endif // OPENPOSE__CORE__W_KEY_POINT_SCALER_HPP
@@ -0,0 +1,14 @@
#ifndef OPENPOSE__FACE__ENUM_CLASSES_HPP
#define OPENPOSE__FACE__ENUM_CLASSES_HPP
namespace op
{
enum class FaceProperty : bool
{
NMSThreshold = 0,
Size,
};
}
#endif // OPENPOSE__FACE__ENUM_CLASSES_HPP
@@ -0,0 +1,66 @@
#ifndef OPENPOSE__FACE__FACE_EXTRACTOR_HPP
#define OPENPOSE__FACE__FACE_EXTRACTOR_HPP
#include <array>
#include <atomic>
#include <memory> // std::shared_ptr
#include <thread>
#include <opencv2/core/core.hpp>
#include "../../core/array.hpp"
#include "../../core/net.hpp"
#include "../../core/nmsCaffe.hpp"
#include "../../core/resizeAndMergeCaffe.hpp"
#include "../../pose/enumClasses.hpp"
#include "enumClasses.hpp"
namespace op
{
namespace experimental
{
class FaceExtractor
{
public:
explicit FaceExtractor(const std::string& modelFolder, const int gpuId, const PoseModel poseModel);
void initializationOnThread();
void forwardPass(const Array<float>& poseKeyPoints, const cv::Mat& cvInputData);
Array<float> getFaceKeyPoints() const;
double get(const FaceProperty property) const;
void set(const FaceProperty property, const double value);
void increase(const FaceProperty property, const double value);
private:
const cv::Size mNetOutputSize;
const cv::Size mOutputSize;
const unsigned char mNeck;
const unsigned char mNose;
const unsigned char mLEar;
const unsigned char mREar;
const unsigned char mLEye;
const unsigned char mREye;
std::array<std::atomic<double>, (int)FaceProperty::Size> mProperties;
std::shared_ptr<Net> spNet;
std::shared_ptr<ResizeAndMergeCaffe<float>> spResizeAndMergeCaffe;
std::shared_ptr<NmsCaffe<float>> spNmsCaffe;
Array<float> mFaceImageCrop;
Array<float> mFaceKeyPoints;
float mScaleFace;
// Init with thread
boost::shared_ptr<caffe::Blob<float>> spCaffeNetOutputBlob;
std::shared_ptr<caffe::Blob<float>> spHeatMapsBlob;
std::shared_ptr<caffe::Blob<float>> spPeaksBlob;
std::thread::id mThreadId;
void checkThread() const;
DELETE_COPY(FaceExtractor);
};
}
}
#endif // OPENPOSE__FACE__FACE_EXTRACTOR_HPP
@@ -0,0 +1,35 @@
#ifndef OPENPOSE__FACE__FACE_PARAMETERS_HPP
#define OPENPOSE__FACE__FACE_PARAMETERS_HPP
#include "enumClasses.hpp"
#include "../../pose/poseParameters.hpp"
namespace op
{
const unsigned char FACE_MAX_NUMBER_FACE = 1;
const unsigned char FACE_NUMBER_PARTS = 71;
#define FACE_PAIRS_TO_RENDER {0,1, 1,2, 2,3, 3,4, 4,5, 5,6, 6,7, 7,8, 8,9, 9,10, 10,11, 11,12, 12,13, 13,14, 14,15, 15,16, 17,18, 18,19, 19,20, \
20,21, 22,23, 23,24, 24,25, 25,26, 27,28, 28,29, 29,30, 31,32, 32,33, 33,34, 34,35, 36,37, 37,38, 38,39, 39,40, 40,41, \
41,36, 42,43, 43,44, 44,45, 45,46, 46,47, 47,42, 48,49, 49,50, 50,51, 51,52, 52,53, 53,54, 54,55, 55,56, 56,57, 57,58, \
58,59, 59,48, 60,61, 61,62, 62,63, 63,64, 64,65, 65,66, 66,67, 67,60}
// Constant Global Parameters
// const unsigned char FACE_MAX_PEOPLE = 1;
// Constant parameters
const auto FACE_CCN_DECREASE_FACTOR = 8.f;
const unsigned int FACE_MAX_PEAKS = 64u;
const std::string FACE_PROTOTXT{"face/pose_deploy.prototxt"};
const std::string FACE_TRAINED_MODEL{"face/pose_iter_116000.caffemodel"};
// Default Model Parameters
// They might be modified on running time
const auto FACE_DEFAULT_NMS_THRESHOLD = 0.1f;
// Rendering default parameters
const auto FACE_DEFAULT_ALPHA_FACE = POSE_DEFAULT_ALPHA_POSE;
// const auto FACE_DEFAULT_ALPHA_HEATMAP = POSE_DEFAULT_ALPHA_HEATMAP;
}
#endif // OPENPOSE__FACE__FACE_PARAMETERS_HPP
@@ -0,0 +1,12 @@
#ifndef OPENPOSE__FACE__GPU_FACE_RENDER_HPP
#define OPENPOSE__FACE__GPU_FACE_RENDER_HPP
#include <opencv2/core/core.hpp>
#include "faceParameters.hpp"
namespace op
{
void renderFaceGpu(float* framePtr, const cv::Size& frameSize, const float* const facePtr, const int numberFace, const float alphaColorToAdd = FACE_DEFAULT_ALPHA_FACE);
}
#endif // OPENPOSE__FACE__GPU_FACE_RENDER_HPP
@@ -0,0 +1,33 @@
#ifndef OPENPOSE__FACE__FACE_RENDERER_HPP
#define OPENPOSE__FACE__FACE_RENDERER_HPP
#include <opencv2/core/core.hpp>
#include "../../core/array.hpp"
#include "../../core/renderer.hpp"
#include "../../thread/worker.hpp"
namespace op
{
namespace experimental
{
class FaceRenderer : public Renderer
{
public:
explicit FaceRenderer(const cv::Size& frameSize);
~FaceRenderer();
void initializationOnThread();
void renderFace(Array<float>& outputData, const Array<float>& faceKeyPoints);
private:
const cv::Size mFrameSize;
float* pGpuFace; // GPU aux memory
DELETE_COPY(FaceRenderer);
};
}
}
#endif // OPENPOSE__FACE__FACE_RENDERER_HPP
@@ -0,0 +1,13 @@
#ifndef OPENPOSE__FACE__HEADERS_HPP
#define OPENPOSE__FACE__HEADERS_HPP
// face module
#include "enumClasses.hpp"
#include "faceExtractor.hpp"
#include "faceParameters.hpp"
#include "faceRenderer.hpp"
#include "faceRenderGpu.hpp"
#include "wFaceExtractor.hpp"
#include "wFaceRenderer.hpp"
#endif // OPENPOSE__FACE__HEADERS_HPP
@@ -0,0 +1,91 @@
#ifndef OPENPOSE__FACE__W_FACE_EXTRACTOR_HPP
#define OPENPOSE__FACE__W_FACE_EXTRACTOR_HPP
#include <memory> // std::shared_ptr
#include "../../thread/worker.hpp"
#include "faceRenderer.hpp"
namespace op
{
namespace experimental
{
template<typename TDatums>
class WFaceExtractor : public Worker<TDatums>
{
public:
explicit WFaceExtractor(const std::shared_ptr<FaceExtractor>& faceExtractor);
void initializationOnThread();
void work(TDatums& tDatums);
private:
std::shared_ptr<FaceExtractor> spFaceExtractor;
DELETE_COPY(WFaceExtractor);
};
}
}
// Implementation
#include "../../utilities/errorAndLog.hpp"
#include "../../utilities/macros.hpp"
#include "../../utilities/pointerContainer.hpp"
#include "../../utilities/profiler.hpp"
namespace op
{
namespace experimental
{
template<typename TDatums>
WFaceExtractor<TDatums>::WFaceExtractor(const std::shared_ptr<FaceExtractor>& faceExtractor) :
spFaceExtractor{faceExtractor}
{
}
template<typename TDatums>
void WFaceExtractor<TDatums>::initializationOnThread()
{
spFaceExtractor->initializationOnThread();
}
template<typename TDatums>
void WFaceExtractor<TDatums>::work(TDatums& tDatums)
{
try
{
if (checkNoNullNorEmpty(tDatums))
{
// Debugging log
dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
// Profiling speed
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
// Extract people face
for (auto& tDatum : *tDatums)
{
spFaceExtractor->forwardPass(tDatum.poseKeyPoints, tDatum.cvInputData);
tDatum.faceKeyPoints = spFaceExtractor->getFaceKeyPoints();
}
// Profiling speed
Profiler::timerEnd(profilerKey);
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, 1000);
// Debugging log
dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
}
}
catch (const std::exception& e)
{
this->stop();
tDatums = nullptr;
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
COMPILE_TEMPLATE_DATUM(WFaceExtractor);
}
}
#endif // OPENPOSE__FACE__W_FACE_EXTRACTOR_HPP
@@ -0,0 +1,88 @@
#ifndef OPENPOSE__FACE__W_FACE_RENDERER_HPP
#define OPENPOSE__FACE__W_FACE_RENDERER_HPP
#include <memory> // std::shared_ptr
#include "../../thread/worker.hpp"
#include "faceRenderer.hpp"
namespace op
{
namespace experimental
{
template<typename TDatums>
class WFaceRenderer : public Worker<TDatums>
{
public:
explicit WFaceRenderer(const std::shared_ptr<FaceRenderer>& faceRenderer);
void initializationOnThread();
void work(TDatums& tDatums);
private:
std::shared_ptr<FaceRenderer> spFaceRenderer;
DELETE_COPY(WFaceRenderer);
};
}
}
// Implementation
#include "../../utilities/errorAndLog.hpp"
#include "../../utilities/macros.hpp"
#include "../../utilities/pointerContainer.hpp"
#include "../../utilities/profiler.hpp"
namespace op
{
namespace experimental
{
template<typename TDatums>
WFaceRenderer<TDatums>::WFaceRenderer(const std::shared_ptr<FaceRenderer>& faceRenderer) :
spFaceRenderer{faceRenderer}
{
}
template<typename TDatums>
void WFaceRenderer<TDatums>::initializationOnThread()
{
spFaceRenderer->initializationOnThread();
}
template<typename TDatums>
void WFaceRenderer<TDatums>::work(TDatums& tDatums)
{
try
{
if (checkNoNullNorEmpty(tDatums))
{
// Debugging log
dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
// Profiling speed
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
// Render people face
for (auto& tDatum : *tDatums)
spFaceRenderer->renderFace(tDatum.outputData, tDatum.faceKeyPoints);
// Profiling speed
Profiler::timerEnd(profilerKey);
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, 1000);
// Debugging log
dLog("", Priority::Low, __LINE__, __FUNCTION__, __FILE__);
}
}
catch (const std::exception& e)
{
this->stop();
tDatums = nullptr;
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
COMPILE_TEMPLATE_DATUM(WFaceRenderer);
}
}
#endif // OPENPOSE__FACE__W_FACE_RENDERER_HPP
@@ -78,7 +78,7 @@ namespace op
if (imageId <= 50006) // 3559 images ~ 4 min at 15fps // move this to producer as --frame_last 50006
{
// Record json in COCO format if file within desired range of images
spPoseJsonCocoSaver->record(tDatum.pose, imageId);
spPoseJsonCocoSaver->record(tDatum.poseKeyPoints, imageId);
// Profiling speed
Profiler::timerEnd(profilerKey);
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, 1000);
@@ -0,0 +1,14 @@
#ifndef OPENPOSE__HAND__ENUM_CLASSES_HPP
#define OPENPOSE__HAND__ENUM_CLASSES_HPP
namespace op
{
enum class HandsProperty : bool
{
NMSThreshold = 0,
Size,
};
}
#endif // OPENPOSE__HAND__ENUM_CLASSES_HPP
@@ -1,5 +1,5 @@
#ifndef OPENPOSE__HANDS__HANDS_EXTRACTOR_HPP
#define OPENPOSE__HANDS__HANDS_EXTRACTOR_HPP
#ifndef OPENPOSE__HAND__HAND_EXTRACTOR_HPP
#define OPENPOSE__HAND__HAND_EXTRACTOR_HPP
#include <array>
#include <atomic>
@@ -17,16 +17,16 @@ namespace op
{
namespace experimental
{
class HandsExtractor
class HandExtractor
{
public:
explicit HandsExtractor(const std::string& modelFolder, const int gpuId, const PoseModel poseModel);
explicit HandExtractor(const std::string& modelFolder, const int gpuId, const PoseModel poseModel);
void initializationOnThread();
void forwardPass(const Array<float>& pose, const cv::Mat& cvInputData);
void forwardPass(const Array<float>& poseKeyPoints, const cv::Mat& cvInputData);
Array<float> getHands() const;
Array<float> getHandKeyPoints() const;
double get(const HandsProperty property) const;
@@ -60,9 +60,9 @@ namespace op
void checkThread() const;
DELETE_COPY(HandsExtractor);
DELETE_COPY(HandExtractor);
};
}
}
#endif // OPENPOSE__HANDS__HANDS_EXTRACTOR_HPP
#endif // OPENPOSE__HAND__HAND_EXTRACTOR_HPP
@@ -0,0 +1,32 @@
#ifndef OPENPOSE__HAND__HAND_PARAMETERS_HPP
#define OPENPOSE__HAND__HAND_PARAMETERS_HPP
#include "enumClasses.hpp"
#include "../../pose/poseParameters.hpp"
namespace op
{
const unsigned char HAND_MAX_NUMBER_HANDS = 2;
const unsigned char HAND_NUMBER_PARTS = 21;
#define HAND_PAIRS_TO_RENDER {0,1, 1,2, 2,3, 3,4, 0,5, 5,6, 6,7, 7,8, 0,9, 9,10, 10,11, 11,12, 0,13, 13,14, 14,15, 15,16, 0,17, 17,18, 18,19, 19,20}
// Constant Global Parameters
// const unsigned char HAND_MAX_PEOPLE = 1;
// Constant parameters
const auto HAND_CCN_DECREASE_FACTOR = 8.f;
const unsigned int HAND_MAX_PEAKS = 64u;
const std::string HAND_PROTOTXT{"hand/pose_deploy.prototxt"};
const std::string HAND_TRAINED_MODEL{"hand/pose_iter_120000.caffemodel"};
// Default Model Parameters
// They might be modified on running time
const auto HAND_DEFAULT_NMS_THRESHOLD = 0.1f;
// Rendering default parameters
const auto HAND_DEFAULT_ALPHA_HANDS = POSE_DEFAULT_ALPHA_POSE;
// const auto HAND_DEFAULT_ALPHA_HEATMAP = POSE_DEFAULT_ALPHA_HEATMAP;
}
#endif // OPENPOSE__HAND__HAND_PARAMETERS_HPP
@@ -0,0 +1,12 @@
#ifndef OPENPOSE__HAND__GPU_HAND_RENDER_HPP
#define OPENPOSE__HAND__GPU_HAND_RENDER_HPP
#include <opencv2/core/core.hpp>
#include "handParameters.hpp"
namespace op
{
void renderHandsGpu(float* framePtr, const cv::Size& frameSize, const float* const handsPtr, const int numberHands, const float alphaColorToAdd = HAND_DEFAULT_ALPHA_HANDS);
}
#endif // OPENPOSE__HAND__GPU_HAND_RENDER_HPP
@@ -1,5 +1,5 @@
#ifndef OPENPOSE__HANDS__HANDS_RENDERER_HPP
#define OPENPOSE__HANDS__HANDS_RENDERER_HPP
#ifndef OPENPOSE__HAND__HAND_RENDERER_HPP
#define OPENPOSE__HAND__HAND_RENDERER_HPP
#include <opencv2/core/core.hpp>
#include "../../core/array.hpp"
@@ -10,24 +10,24 @@ namespace op
{
namespace experimental
{
class HandsRenderer : public Renderer
class HandRenderer : public Renderer
{
public:
explicit HandsRenderer(const cv::Size& frameSize);
explicit HandRenderer(const cv::Size& frameSize);
~HandsRenderer();
~HandRenderer();
void initializationOnThread();
void renderHands(Array<float>& outputData, const Array<float>& hands);
void renderHands(Array<float>& outputData, const Array<float>& handKeyPoints);
private:
const cv::Size mFrameSize;
float* pGpuHands; // GPU aux memory
DELETE_COPY(HandsRenderer);
DELETE_COPY(HandRenderer);
};
}
}
#endif // OPENPOSE__HANDS__HANDS_RENDERER_HPP
#endif // OPENPOSE__HAND__HAND_RENDERER_HPP
@@ -0,0 +1,13 @@
#ifndef OPENPOSE__HAND__HEADERS_HPP
#define OPENPOSE__HAND__HEADERS_HPP
// hand module
#include "enumClasses.hpp"
#include "handExtractor.hpp"
#include "handParameters.hpp"
#include "handRenderer.hpp"
#include "handRenderGpu.hpp"
#include "wHandExtractor.hpp"
#include "wHandRenderer.hpp"
#endif // OPENPOSE__HAND__HEADERS_HPP
@@ -1,28 +1,28 @@
#ifndef OPENPOSE__HANDS__W_HANDS_EXTRACTOR_HPP
#define OPENPOSE__HANDS__W_HANDS_EXTRACTOR_HPP
#ifndef OPENPOSE__HAND__W_HAND_EXTRACTOR_HPP
#define OPENPOSE__HAND__W_HAND_EXTRACTOR_HPP
#include <memory> // std::shared_ptr
#include "../../thread/worker.hpp"
#include "handsRenderer.hpp"
#include "handRenderer.hpp"
namespace op
{
namespace experimental
{
template<typename TDatums>
class WHandsExtractor : public Worker<TDatums>
class WHandExtractor : public Worker<TDatums>
{
public:
explicit WHandsExtractor(const std::shared_ptr<HandsExtractor>& handsExtractor);
explicit WHandExtractor(const std::shared_ptr<HandExtractor>& handExtractor);
void initializationOnThread();
void work(TDatums& tDatums);
private:
std::shared_ptr<HandsExtractor> spHandsExtractor;
std::shared_ptr<HandExtractor> spHandExtractor;
DELETE_COPY(WHandsExtractor);
DELETE_COPY(WHandExtractor);
};
}
}
@@ -41,19 +41,19 @@ namespace op
namespace experimental
{
template<typename TDatums>
WHandsExtractor<TDatums>::WHandsExtractor(const std::shared_ptr<HandsExtractor>& handsExtractor) :
spHandsExtractor{handsExtractor}
WHandExtractor<TDatums>::WHandExtractor(const std::shared_ptr<HandExtractor>& handExtractor) :
spHandExtractor{handExtractor}
{
}
template<typename TDatums>
void WHandsExtractor<TDatums>::initializationOnThread()
void WHandExtractor<TDatums>::initializationOnThread()
{
spHandsExtractor->initializationOnThread();
spHandExtractor->initializationOnThread();
}
template<typename TDatums>
void WHandsExtractor<TDatums>::work(TDatums& tDatums)
void WHandExtractor<TDatums>::work(TDatums& tDatums)
{
try
{
@@ -66,8 +66,8 @@ namespace op
// Extract people hands
for (auto& tDatum : *tDatums)
{
spHandsExtractor->forwardPass(tDatum.pose, tDatum.cvInputData);
tDatum.hands = spHandsExtractor->getHands();
spHandExtractor->forwardPass(tDatum.poseKeyPoints, tDatum.cvInputData);
tDatum.handKeyPoints = spHandExtractor->getHandKeyPoints();
}
// Profiling speed
Profiler::timerEnd(profilerKey);
@@ -84,8 +84,8 @@ namespace op
}
}
COMPILE_TEMPLATE_DATUM(WHandsExtractor);
COMPILE_TEMPLATE_DATUM(WHandExtractor);
}
}
#endif // OPENPOSE__HANDS__W_HANDS_EXTRACTOR_HPP
#endif // OPENPOSE__HAND__W_HAND_EXTRACTOR_HPP
@@ -1,28 +1,28 @@
#ifndef OPENPOSE__HANDS__W_HANDS_RENDERER_HPP
#define OPENPOSE__HANDS__W_HANDS_RENDERER_HPP
#ifndef OPENPOSE__HAND__W_HAND_RENDERER_HPP
#define OPENPOSE__HAND__W_HAND_RENDERER_HPP
#include <memory> // std::shared_ptr
#include "../../thread/worker.hpp"
#include "handsRenderer.hpp"
#include "handRenderer.hpp"
namespace op
{
namespace experimental
{
template<typename TDatums>
class WHandsRenderer : public Worker<TDatums>
class WHandRenderer : public Worker<TDatums>
{
public:
explicit WHandsRenderer(const std::shared_ptr<HandsRenderer>& handsRenderer);
explicit WHandRenderer(const std::shared_ptr<HandRenderer>& handRenderer);
void initializationOnThread();
void work(TDatums& tDatums);
private:
std::shared_ptr<HandsRenderer> spHandsRenderer;
std::shared_ptr<HandRenderer> spHandRenderer;
DELETE_COPY(WHandsRenderer);
DELETE_COPY(WHandRenderer);
};
}
}
@@ -41,19 +41,19 @@ namespace op
namespace experimental
{
template<typename TDatums>
WHandsRenderer<TDatums>::WHandsRenderer(const std::shared_ptr<HandsRenderer>& handsRenderer) :
spHandsRenderer{handsRenderer}
WHandRenderer<TDatums>::WHandRenderer(const std::shared_ptr<HandRenderer>& handRenderer) :
spHandRenderer{handRenderer}
{
}
template<typename TDatums>
void WHandsRenderer<TDatums>::initializationOnThread()
void WHandRenderer<TDatums>::initializationOnThread()
{
spHandsRenderer->initializationOnThread();
spHandRenderer->initializationOnThread();
}
template<typename TDatums>
void WHandsRenderer<TDatums>::work(TDatums& tDatums)
void WHandRenderer<TDatums>::work(TDatums& tDatums)
{
try
{
@@ -65,7 +65,7 @@ namespace op
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
// Render people hands
for (auto& tDatum : *tDatums)
spHandsRenderer->renderHands(tDatum.outputData, tDatum.hands);
spHandRenderer->renderHands(tDatum.outputData, tDatum.handKeyPoints);
// Profiling speed
Profiler::timerEnd(profilerKey);
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, 1000);
@@ -81,8 +81,8 @@ namespace op
}
}
COMPILE_TEMPLATE_DATUM(WHandsRenderer);
COMPILE_TEMPLATE_DATUM(WHandRenderer);
}
}
#endif // OPENPOSE__HANDS__W_HANDS_RENDERER_HPP
#endif // OPENPOSE__HAND__W_HAND_RENDERER_HPP
@@ -1,14 +0,0 @@
#ifndef OPENPOSE__HANDS__ENUM_CLASSES_HPP
#define OPENPOSE__HANDS__ENUM_CLASSES_HPP
namespace op
{
enum class HandsProperty : bool
{
NMSThreshold = 0,
Size,
};
}
#endif // OPENPOSE__HANDS__ENUM_CLASSES_HPP
@@ -1,32 +0,0 @@
#ifndef OPENPOSE__HANDS__HANDS_PARAMETERS_HPP
#define OPENPOSE__HANDS__HANDS_PARAMETERS_HPP
#include "enumClasses.hpp"
#include "../../pose/poseParameters.hpp"
namespace op
{
const unsigned char HANDS_MAX_NUMBER_HANDS = 2;
const unsigned char HANDS_NUMBER_PARTS = 21;
#define HANDS_PAIRS_TO_RENDER {0,1, 1,2, 2,3, 3,4, 0,5, 5,6, 6,7, 7,8, 0,9, 9,10, 10,11, 11,12, 0,13, 13,14, 14,15, 15,16, 0,17, 17,18, 18,19, 19,20}
// Constant Global Parameters
// const unsigned char HANDS_MAX_PEOPLE = 1;
// Constant parameters
const auto HANDS_CCN_DECREASE_FACTOR = 8.f;
const unsigned int HANDS_MAX_PEAKS = 64u;
const std::string HANDS_PROTOTXT{"hand/pose_deploy.prototxt"};
const std::string HANDS_TRAINED_MODEL{"hand/pose_iter_120000.caffemodel"};
// Default Model Parameters
// They might be modified on running time
const auto HANDS_DEFAULT_NMS_THRESHOLD = 0.1f;
// Rendering default parameters
const auto HANDS_DEFAULT_ALPHA_HANDS = POSE_DEFAULT_ALPHA_POSE;
// const auto HANDS_DEFAULT_ALPHA_HEATMAP = POSE_DEFAULT_ALPHA_HEATMAP;
}
#endif // OPENPOSE__HANDS__HANDS_PARAMETERS_HPP
@@ -1,12 +0,0 @@
#ifndef OPENPOSE__HANDS__GPU_HANDS_RENDER_HPP
#define OPENPOSE__HANDS__GPU_HANDS_RENDER_HPP
#include <opencv2/core/core.hpp>
#include "handsParameters.hpp"
namespace op
{
void renderHandsGpu(float* framePtr, const cv::Size& frameSize, const float* const handsPtr, const int numberHands, const float alphaColorToAdd = HANDS_DEFAULT_ALPHA_HANDS);
}
#endif // OPENPOSE__HANDS__GPU_HANDS_RENDER_HPP
@@ -1,13 +0,0 @@
#ifndef OPENPOSE__HANDS__HEADERS_HPP
#define OPENPOSE__HANDS__HEADERS_HPP
// hands module
#include "enumClasses.hpp"
#include "handsExtractor.hpp"
#include "handsParameters.hpp"
#include "handsRenderer.hpp"
#include "handsRenderGpu.hpp"
#include "wHandsExtractor.hpp"
#include "wHandsRenderer.hpp"
#endif // OPENPOSE__HANDS__HEADERS_HPP
+4 -1
View File
@@ -1,11 +1,14 @@
#ifndef OPENPOSE__EXPERIMENTAL__HEADERS_HPP
#define OPENPOSE__EXPERIMENTAL__HEADERS_HPP
// face module
#include "face/headers.hpp"
// filestream module
#include "filestream/headers.hpp"
// hands module
#include "hands/headers.hpp"
#include "hand/headers.hpp"
// producer module
// #include "producer/headers.hpp"
@@ -22,7 +22,7 @@ namespace op
~PoseJsonCocoSaver();
void record(const Array<float>& pose, const int imageId);
void record(const Array<float>& poseKeyPoints, const int imageId);
private:
JsonOfstream mJsonOfstream;
@@ -13,7 +13,7 @@ namespace op
public:
explicit PoseJsonSaver(const std::string& directoryPath);
void savePoseVector(const std::vector<Array<float>>& poseVector, const std::string& fileName) const;
void savePoseKeyPoints(const std::vector<Array<float>>& poseKeyPointsVector, const std::string& fileName) const;
};
}
+1 -1
View File
@@ -12,7 +12,7 @@ namespace op
public:
PoseSaver(const std::string& directoryPath, const DataFormat format);
void savePoseVector(const std::vector<Array<float>>& poseVector, const std::string& fileName) const;
void savePoseKeyPoints(const std::vector<Array<float>>& poseKeyPointsVector, const std::string& fileName) const;
private:
const DataFormat mFormat;
@@ -61,11 +61,11 @@ namespace op
// T* to T
auto& tDatumsNoPtr = *tDatums;
// Record people pose data in json format
std::vector<Array<float>> poseVector(tDatumsNoPtr.size());
std::vector<Array<float>> poseKeyPointsVector(tDatumsNoPtr.size());
for (auto i = 0; i < tDatumsNoPtr.size(); i++)
poseVector[i] = tDatumsNoPtr[i].pose;
poseKeyPointsVector[i] = tDatumsNoPtr[i].poseKeyPoints;
const auto fileName = (!tDatumsNoPtr[0].name.empty() ? tDatumsNoPtr[0].name : std::to_string(tDatumsNoPtr[0].id));
spPoseJsonSaver->savePoseVector(poseVector, fileName);
spPoseJsonSaver->savePoseKeyPoints(poseKeyPointsVector, fileName);
// Profiling speed
Profiler::timerEnd(profilerKey);
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, 1000);
+3 -3
View File
@@ -62,11 +62,11 @@ namespace op
// T* to T
auto& tDatumsNoPtr = *tDatums;
// Record people pose data
std::vector<Array<float>> poseVector(tDatumsNoPtr.size());
std::vector<Array<float>> poseKeyPointsVector(tDatumsNoPtr.size());
for (auto i = 0; i < tDatumsNoPtr.size(); i++)
poseVector[i] = tDatumsNoPtr[i].pose;
poseKeyPointsVector[i] = tDatumsNoPtr[i].poseKeyPoints;
const auto fileName = (!tDatumsNoPtr[0].name.empty() ? tDatumsNoPtr[0].name : std::to_string(tDatumsNoPtr[0].id));
spPoseSaver->savePoseVector(poseVector, fileName);
spPoseSaver->savePoseKeyPoints(poseKeyPointsVector, fileName);
// Profiling speed
Profiler::timerEnd(profilerKey);
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, 1000);
+1 -1
View File
@@ -12,7 +12,7 @@ namespace op
public:
GuiInfoAdder(const cv::Size& outputSize, const int numberGpus);
void addInfo(cv::Mat& cvOutputData, const Array<float>& pose, const unsigned long long id, const std::string& elementRenderedName);
void addInfo(cv::Mat& cvOutputData, const Array<float>& poseKeyPoints, const unsigned long long id, const std::string& elementRenderedName);
private:
// Const variables
+1 -1
View File
@@ -58,7 +58,7 @@ namespace op
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
// Add GUI components to frame
for (auto& tDatum : *tDatums)
spGuiInfoAdder->addInfo(tDatum.cvOutputData, tDatum.pose, tDatum.id, tDatum.elementRendered.second);
spGuiInfoAdder->addInfo(tDatum.cvOutputData, tDatum.poseKeyPoints, tDatum.id, tDatum.elementRendered.second);
// Profiling speed
Profiler::timerEnd(profilerKey);
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, 1000);
@@ -7,11 +7,11 @@
namespace op
{
template <typename T>
void connectBodyPartsCpu(Array<T>& pose, const T* const heatMapPtr, const T* const peaksPtr, const PoseModel poseModel, const cv::Size& heatMapSize, const int maxPeaks,
void connectBodyPartsCpu(Array<T>& poseKeyPoints, const T* const heatMapPtr, const T* const peaksPtr, const PoseModel poseModel, const cv::Size& heatMapSize, const int maxPeaks,
const int interMinAboveThreshold, const T interThreshold, const int minSubsetCnt, const T minSubsetScore, const T scaleFactor = 1.f);
template <typename T>
void connectBodyPartsGpu(Array<T>& pose, T* posePtr, const T* const heatMapPtr, const T* const peaksPtr, const PoseModel poseModel, const cv::Size& heatMapSize,
void connectBodyPartsGpu(Array<T>& poseKeyPoints, T* posePtr, const T* const heatMapPtr, const T* const peaksPtr, const PoseModel poseModel, const cv::Size& heatMapSize,
const int maxPeaks, const int interMinAboveThreshold, const T interThreshold, const int minSubsetCnt, const T minSubsetScore, const T scaleFactor = 1.f);
}
@@ -36,9 +36,9 @@ namespace op
void setScaleNetToOutput(const T scaleNetToOutput);
virtual void Forward_cpu(const std::vector<caffe::Blob<T>*>& bottom, Array<T>& pose);
virtual void Forward_cpu(const std::vector<caffe::Blob<T>*>& bottom, Array<T>& poseKeyPoints);
virtual void Forward_gpu(const std::vector<caffe::Blob<T>*>& bottom, const std::vector<caffe::Blob<T>*>& top, Array<T>& pose);
virtual void Forward_gpu(const std::vector<caffe::Blob<T>*>& bottom, const std::vector<caffe::Blob<T>*>& top, Array<T>& poseKeyPoints);
virtual void Backward_cpu(const std::vector<caffe::Blob<T>*>& top, const std::vector<bool>& propagate_down, const std::vector<caffe::Blob<T>*>& bottom);
+2 -2
View File
@@ -30,7 +30,7 @@ namespace op
virtual const float* getPoseGpuConstPtr() const = 0;
Array<float> getPose() const;
Array<float> getPoseKeyPoints() const;
double getScaleNetToOutput() const;
@@ -44,7 +44,7 @@ namespace op
const PoseModel mPoseModel;
const cv::Size mNetOutputSize;
const cv::Size mOutputSize;
Array<float> mPose;
Array<float> mPoseKeyPoints;
double mScaleNetToOutput;
void checkThread() const;
+4
View File
@@ -87,6 +87,10 @@ namespace op
// Rendering default parameters
const auto POSE_DEFAULT_ALPHA_POSE = 0.6f;
const auto POSE_DEFAULT_ALPHA_HEATMAP = 0.7f;
// Auxiliary functions
unsigned char poseBodyPartMapStringToKey(const PoseModel poseModel, const std::string& string);
unsigned char poseBodyPartMapStringToKey(const PoseModel poseModel, const std::vector<std::string>& strings);
}
#endif // OPENPOSE__POSE__POSE_PARAMETERS_HPP
+1 -1
View File
@@ -42,7 +42,7 @@ namespace op
void setShowGooglyEyes(const bool showGooglyEyes);
std::pair<int, std::string> renderPose(Array<float>& outputData, const Array<float>& pose, const double scaleNetToOutput = -1.);
std::pair<int, std::string> renderPose(Array<float>& outputData, const Array<float>& poseKeyPoints, const double scaleNetToOutput = -1.);
private:
const cv::Size mHeatMapsSize;
+1 -1
View File
@@ -63,7 +63,7 @@ namespace op
{
spPoseExtractor->forwardPass(tDatum.inputNetData, tDatum.cvInputData.size());
tDatum.poseHeatMaps = spPoseExtractor->getHeatMaps();
tDatum.pose = spPoseExtractor->getPose();
tDatum.poseKeyPoints = spPoseExtractor->getPoseKeyPoints();
tDatum.scaleNetToOutput = spPoseExtractor->getScaleNetToOutput();
}
// Profiling speed
+1 -1
View File
@@ -60,7 +60,7 @@ namespace op
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
// Render people pose
for (auto& tDatum : *tDatums)
tDatum.elementRendered = spPoseRenderer->renderPose(tDatum.outputData, tDatum.pose, tDatum.scaleNetToOutput);
tDatum.elementRendered = spPoseRenderer->renderPose(tDatum.outputData, tDatum.poseKeyPoints, tDatum.scaleNetToOutput);
// Profiling speed
Profiler::timerEnd(profilerKey);
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__, 1000);
+1 -1
View File
@@ -140,7 +140,7 @@ namespace op
colorR = addWeighted(colorR, colorToAdd[0], alphaColorToAdd);
colorG = addWeighted(colorG, colorToAdd[1], alphaColorToAdd);
colorB = addWeighted(colorB, colorToAdd[2], alphaColorToAdd);
}
}
}
#endif // OPENPOSE__UTILITIES_CUDA_HU
+120
View File
@@ -0,0 +1,120 @@
#ifndef OPENPOSE__UTILITIES_RENDER_HU
#define OPENPOSE__UTILITIES_RENDER_HU
namespace op
{
inline __device__ void renderKeyPoints(float* targetPtr, float2* sharedMaxs, float2* sharedMins, float* sharedScaleF,
const int globalIdx, const int x, const int y, const int targetWidth, const int targetHeight,
const float* const facePtr, const unsigned char* const partPairsPtr,
const int numberFaces, const int numberParts, const int numberPartPairs,
const float* const rgbColorsPtr, const int numberColors,
const float radius, const float stickwidth, const float threshold, const float alphaColorToAdd)
{
// Fill shared parameters
if (globalIdx < numberFaces)
{
sharedMins[globalIdx].x = targetWidth;
sharedMins[globalIdx].y = targetHeight;
sharedMaxs[globalIdx].x = 0.f;
sharedMaxs[globalIdx].y = 0.f;
for (auto part = 0 ; part < numberParts ; part++)
{
const auto index = 3 * (globalIdx*numberParts + part);
const auto x = facePtr[index];
const auto y = facePtr[index+1];
const auto score = facePtr[index+2];
if (score > threshold)
{
if (x < sharedMins[globalIdx].x)
sharedMins[globalIdx].x = x;
if (x > sharedMaxs[globalIdx].x)
sharedMaxs[globalIdx].x = x;
if (y < sharedMins[globalIdx].y)
sharedMins[globalIdx].y = y;
if (y > sharedMaxs[globalIdx].y)
sharedMaxs[globalIdx].y = y;
}
}
const auto averageX = sharedMaxs[globalIdx].x-sharedMins[globalIdx].x;
const auto averageY = sharedMaxs[globalIdx].y-sharedMins[globalIdx].y;
sharedScaleF[globalIdx] = fastTruncate((averageX + averageY) / 400.f, 0.33f, 1.f); // (averageX + averageY) / 2.f / 400.f
const auto constantToAdd = 50.f;
sharedMaxs[globalIdx].x += constantToAdd;
sharedMaxs[globalIdx].y += constantToAdd;
sharedMins[globalIdx].x -= constantToAdd;
sharedMins[globalIdx].y -= constantToAdd;
}
__syncthreads();
// Fill each (x,y) target pixel
if (x < targetWidth && y < targetHeight)
{
const auto baseIndex = y * targetWidth + x;
auto& b = targetPtr[ baseIndex];
auto& g = targetPtr[ targetWidth * targetHeight + baseIndex];
auto& r = targetPtr[2 * targetWidth * targetHeight + baseIndex];
for (auto person = 0; person < numberFaces; person++)
{
if (x <= sharedMaxs[person].x && x >= sharedMins[person].x && y <= sharedMaxs[person].y && y >= sharedMins[person].y)
{
// Hand part connections
for (auto facePart = 0; facePart < numberPartPairs; facePart++)
{
const auto bSqrt = sharedScaleF[person] * sharedScaleF[person] * stickwidth * stickwidth;
const auto partA = partPairsPtr[2*facePart];
const auto partB = partPairsPtr[2*facePart+1];
const auto indexA = person*numberParts*3 + partA*3;
const auto xA = facePtr[indexA];
const auto yA = facePtr[indexA + 1];
const auto scoreA = facePtr[indexA + 2];
const auto indexB = person*numberParts*3 + partB*3;
const auto xB = facePtr[indexB];
const auto yB = facePtr[indexB + 1];
const auto scoreB = facePtr[indexB + 2];
if (scoreA > threshold && scoreB > threshold)
{
const auto xP = (xA + xB) / 2.f;
const auto yP = (yA + yB) / 2.f;
const auto aSqrt = (xA - xP) * (xA - xP) + (yA - yP) * (yA - yP);
const auto angle = atan2f(yB - yA, xB - xA);
const auto sine = sinf(angle);
const auto cosine = cosf(angle);
const auto A = cosine * (x - xP) + sine * (y - yP);
const auto B = sine * (x - xP) - cosine * (y - yP);
const auto judge = A * A / aSqrt + B * B / bSqrt;
const auto minV = 0.f;
const auto maxV = 1.f;
if (minV <= judge && judge <= maxV)
addColorWeighted(r, g, b, &rgbColorsPtr[(facePart%numberColors)*3], alphaColorToAdd);
}
}
// Hand part circles
for (unsigned char i = 0; i < numberParts; i++)
{
const auto index = 3 * (person*numberParts + i);
const auto localX = facePtr[index];
const auto localY = facePtr[index + 1];
const auto score = facePtr[index + 2];
if (score > threshold)
{
const auto dist2 = (x - localX) * (x - localX) + (y - localY) * (y - localY);
const auto minr2 = 0.f;
const auto maxr2 = sharedScaleF[person]*sharedScaleF[person]*radius * radius;
if (minr2 <= dist2 && dist2 <= maxr2)
addColorWeighted(r, g, b, &rgbColorsPtr[(i%numberColors)*3], alphaColorToAdd);
}
}
}
}
}
}
}
#endif // OPENPOSE__UTILITIES_RENDER_HU
+2 -1
View File
@@ -3,7 +3,8 @@
// wrapper module
#include "wrapper.hpp"
#include "wrapperStructHands.hpp"
#include "wrapperStructFace.hpp"
#include "wrapperStructHand.hpp"
#include "wrapperStructInput.hpp"
#include "wrapperStructOutput.hpp"
#include "wrapperStructPose.hpp"
+100 -18
View File
@@ -2,10 +2,11 @@
#define OPENPOSE__WRAPPER__WRAPPER_HPP
#include "../thread/headers.hpp"
#include "wrapperStructPose.hpp"
#include "wrapperStructHands.hpp"
#include "wrapperStructFace.hpp"
#include "wrapperStructHand.hpp"
#include "wrapperStructInput.hpp"
#include "wrapperStructOutput.hpp"
#include "wrapperStructPose.hpp"
namespace op
{
@@ -72,18 +73,40 @@ namespace op
*/
void setWorkerOutput(const TWorker& worker, const bool workerOnNewThread = true);
// If output is not required, just use this function until the renderOutput argument. Keep the default values for the other parameters
// in order not to display/save any output.
// If output is not required, just use this function until the renderOutput argument. Keep the default values for the other parameters in order not to display/save any output.
void configure(const WrapperStructPose& wrapperStructPose,
// Producer (set producerSharedPtr = nullptr or use the default WrapperStructInput{} to disable any input)
const WrapperStructInput& wrapperStructInput = WrapperStructInput{},
const WrapperStructInput& wrapperStructInput,
// Consumer (keep default values to disable any output)
const WrapperStructOutput& wrapperStructOutput = WrapperStructOutput{});
// THIS FUNCTION IS NOT IMPLEMENTED YET -> COMING SOON
// Similar to the previos configure, but it includes hand extraction and rendering
void configure(const WrapperStructPose& wrapperStructPose,
// Hand (use the default WrapperStructHand{} to disable any hand detector)
const experimental::WrapperStructHand& wrapperHandStruct,
// Producer (set producerSharedPtr = nullptr or use the default WrapperStructInput{} to disable any input)
const WrapperStructInput& wrapperStructInput,
// Consumer (keep default values to disable any output)
const WrapperStructOutput& wrapperStructOutput = WrapperStructOutput{});
// THIS FUNCTION IS NOT IMPLEMENTED YET -> COMING SOON
// Similar to the previos configure, but it includes hand extraction and rendering
void configure(const WrapperStructPose& wrapperStructPose,
// Face (use the default WrapperStructFace{} to disable any face detector)
const experimental::WrapperStructFace& wrapperStructFace,
// Producer (set producerSharedPtr = nullptr or use the default WrapperStructInput{} to disable any input)
const WrapperStructInput& wrapperStructInput,
// Consumer (keep default values to disable any output)
const WrapperStructOutput& wrapperStructOutput = WrapperStructOutput{});
// THIS FUNCTION IS NOT IMPLEMENTED YET -> COMING SOON
// Similar to the previos configure, but it includes hand extraction and rendering
void configure(const WrapperStructPose& wrapperStructPose = WrapperStructPose{},
// Hand (use the default WrapperStructHands{} to disable any hand detector)
const experimental::WrapperStructHands& wrapperHandStruct = experimental::WrapperStructHands{},
// Face (use the default WrapperStructFace{} to disable any face detector)
const experimental::WrapperStructFace& wrapperStructFace = experimental::WrapperStructFace{},
// Hand (use the default WrapperStructHand{} to disable any hand detector)
const experimental::WrapperStructHand& wrapperHandStruct = experimental::WrapperStructHand{},
// Producer (set producerSharedPtr = nullptr or use the default WrapperStructInput{} to disable any input)
const WrapperStructInput& wrapperStructInput = WrapperStructInput{},
// Consumer (keep default values to disable any output)
@@ -349,7 +372,7 @@ namespace op
{
try
{
configure(wrapperStructPose, experimental::WrapperStructHands{}, wrapperStructInput, wrapperStructOutput);
configure(wrapperStructPose, experimental::WrapperStructFace{}, experimental::WrapperStructHand{}, wrapperStructInput, wrapperStructOutput);
}
catch (const std::exception& e)
{
@@ -358,8 +381,37 @@ namespace op
}
template<typename TDatums, typename TWorker, typename TQueue>
void Wrapper<TDatums, TWorker, TQueue>::configure(const WrapperStructPose& wrapperStructPose, const experimental::WrapperStructHands& wrapperHandStruct,
void Wrapper<TDatums, TWorker, TQueue>::configure(const WrapperStructPose& wrapperStructPose, const experimental::WrapperStructFace& wrapperStructFace,
const WrapperStructInput& wrapperStructInput, const WrapperStructOutput& wrapperStructOutput)
{
try
{
configure(wrapperStructPose, wrapperStructFace, experimental::WrapperStructHand{}, wrapperStructInput, wrapperStructOutput);
}
catch (const std::exception& e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
template<typename TDatums, typename TWorker, typename TQueue>
void Wrapper<TDatums, TWorker, TQueue>::configure(const WrapperStructPose& wrapperStructPose, const experimental::WrapperStructHand& wrapperHandStruct,
const WrapperStructInput& wrapperStructInput, const WrapperStructOutput& wrapperStructOutput)
{
try
{
configure(wrapperStructPose, experimental::WrapperStructFace{}, wrapperHandStruct, wrapperStructInput, wrapperStructOutput);
}
catch (const std::exception& e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
template<typename TDatums, typename TWorker, typename TQueue>
void Wrapper<TDatums, TWorker, TQueue>::configure(const WrapperStructPose& wrapperStructPose, const experimental::WrapperStructFace& wrapperStructFace,
const experimental::WrapperStructHand& wrapperHandStruct, const WrapperStructInput& wrapperStructInput,
const WrapperStructOutput& wrapperStructOutput)
{
try
{
@@ -393,8 +445,8 @@ namespace op
}
if (mUserOutputWs.empty() && mThreadManagerMode != ThreadManagerMode::Asynchronous && mThreadManagerMode != ThreadManagerMode::AsynchronousOut)
{
const std::string additionalMessage = " You could also set mThreadManagerMode = mThreadManagerMode::Asynchronous(Out) and/or add your own output worker"
" class before calling this function.";
const std::string additionalMessage = " You could also set mThreadManagerMode = mThreadManagerMode::Asynchronous(Out) and/or add your own"
" output worker class before calling this function.";
const auto savingSomething = (!wrapperStructOutput.writeImages.empty() || !wrapperStructOutput.writeVideo.empty()
|| !wrapperStructOutput.writePose.empty() || !wrapperStructOutput.writePoseJson.empty()
|| !wrapperStructOutput.writeCocoJson.empty() || !wrapperStructOutput.writeHeatMaps.empty());
@@ -516,15 +568,27 @@ namespace op
for (auto i = 0; i < spWPoses.size(); i++)
spWPoses.at(i) = {std::make_shared<WPoseExtractor<TDatumsPtr>>(poseExtractors.at(i))};
// Face extractor(s)
if (wrapperStructFace.extractAndRenderFace)
{
for (auto gpuId = 0; gpuId < spWPoses.size(); gpuId++)
{
const auto faceExtractor = std::make_shared<experimental::FaceExtractor>(
wrapperStructPose.modelFolder, gpuId + wrapperStructPose.gpuNumberStart, wrapperStructPose.poseModel
);
spWPoses.at(gpuId).emplace_back(std::make_shared<experimental::WFaceExtractor<TDatumsPtr>>(faceExtractor));
}
}
// Hand extractor(s)
if (wrapperHandStruct.extractAndRenderHands)
{
for (auto gpuId = 0; gpuId < spWPoses.size(); gpuId++)
{
const auto handsExtractor = std::make_shared<experimental::HandsExtractor>(
const auto handExtractor = std::make_shared<experimental::HandExtractor>(
wrapperStructPose.modelFolder, gpuId + wrapperStructPose.gpuNumberStart, wrapperStructPose.poseModel
);
spWPoses.at(gpuId).emplace_back(std::make_shared<experimental::WHandsExtractor<TDatumsPtr>>(handsExtractor));
spWPoses.at(gpuId).emplace_back(std::make_shared<experimental::WHandExtractor<TDatumsPtr>>(handExtractor));
}
}
@@ -539,15 +603,33 @@ namespace op
for (auto i = 0; i < spWPoses.size(); i++)
{
// Construct hands renderer
const auto handsRenderer = std::make_shared<experimental::HandsRenderer>(finalOutputSize);
const auto handRenderer = std::make_shared<experimental::HandRenderer>(finalOutputSize);
// Performance boost -> share spGpuMemoryPtr for all renderers
if (!poseRenderers.empty())
{
const bool isLastRenderer = (!wrapperStructFace.extractAndRenderFace);
handRenderer->setGpuMemoryAndSetIfLast(poseRenderers.at(i)->getGpuMemoryAndSetAsFirst(), isLastRenderer);
}
// Add worker
spWPoses.at(i).emplace_back(std::make_shared<experimental::WHandRenderer<TDatumsPtr>>(handRenderer));
}
}
// Face renderer(s)
if (wrapperStructFace.extractAndRenderFace)
{
for (auto i = 0; i < spWPoses.size(); i++)
{
// Construct face renderer
const auto faceRenderer = std::make_shared<experimental::FaceRenderer>(finalOutputSize);
// Performance boost -> share spGpuMemoryPtr for all renderers
if (!poseRenderers.empty())
{
const bool isLastRenderer = true;
handsRenderer->setGpuMemoryAndSetIfLast(poseRenderers.at(i)->getGpuMemoryAndSetAsFirst(), isLastRenderer);
faceRenderer->setGpuMemoryAndSetIfLast(poseRenderers.at(i)->getGpuMemoryAndSetAsFirst(), isLastRenderer);
}
// Add worker
spWPoses.at(i).emplace_back(std::make_shared<experimental::WHandsRenderer<TDatumsPtr>>(handsRenderer));
spWPoses.at(i).emplace_back(std::make_shared<experimental::WFaceRenderer<TDatumsPtr>>(faceRenderer));
}
}
@@ -567,8 +649,8 @@ namespace op
&& (wrapperStructPose.poseScaleMode != ScaleMode::InputResolution || (finalOutputSize != producerSize))
&& (wrapperStructPose.poseScaleMode != ScaleMode::NetOutputResolution || (finalOutputSize != netOutputSize)))
{
auto arrayScaler = std::make_shared<ArrayScaler>(wrapperStructPose.poseScaleMode);
mPostProcessingWs.emplace_back(std::make_shared<WArrayScaler<TDatumsPtr>>(arrayScaler));
auto keyPointScaler = std::make_shared<KeyPointScaler>(wrapperStructPose.poseScaleMode);
mPostProcessingWs.emplace_back(std::make_shared<WKeyPointScaler<TDatumsPtr>>(keyPointScaler));
}
mOutputWs.clear();
@@ -0,0 +1,32 @@
#ifndef OPENPOSE__WRAPPER__WRAPPER_STRUCT_FACE_HPP
#define OPENPOSE__WRAPPER__WRAPPER_STRUCT_FACE_HPP
namespace op
{
namespace experimental
{
/**
* WrapperStructFace: Face estimation and rendering configuration struct.
* DO NOT USE. CODE TO BE FINISHED.
* WrapperStructFace allows the user to set up the face estimation and rendering parameters that will be used for the OpenPose Wrapper
* class.
*/
struct WrapperStructFace
{
/**
* PROVISIONAL PARAMETER. IT WILL BE CHANGED.
* Whether to extract and render face.
*/
bool extractAndRenderFace;
/**
* Constructor of the struct.
* It has the recommended and default values we recommend for each element of the struct.
* Since all the elements of the struct are public, they can also be manually filled.
*/
WrapperStructFace(const bool extractAndRenderFace = false);
};
}
}
#endif // OPENPOSE__WRAPPER__WRAPPER_STRUCT_FACE_HPP
@@ -1,17 +1,17 @@
#ifndef OPENPOSE__WRAPPER__WRAPPER_STRUCT_HANDS_HPP
#define OPENPOSE__WRAPPER__WRAPPER_STRUCT_HANDS_HPP
#ifndef OPENPOSE__WRAPPER__WRAPPER_STRUCT_HAND_HPP
#define OPENPOSE__WRAPPER__WRAPPER_STRUCT_HAND_HPP
namespace op
{
namespace experimental
{
/**
* WrapperStructHands: Hands estimation and rendering configuration struct.
* WrapperStructHand: Hands estimation and rendering configuration struct.
* DO NOT USE. CODE TO BE FINISHED.
* WrapperStructHands allows the user to set up the hands estimation and rendering parameters that will be used for the OpenPose Wrapper
* WrapperStructHand allows the user to set up the hands estimation and rendering parameters that will be used for the OpenPose Wrapper
* class.
*/
struct WrapperStructHands
struct WrapperStructHand
{
/**
* PROVISIONAL PARAMETER. IT WILL BE CHANGED.
@@ -24,9 +24,9 @@ namespace op
* It has the recommended and default values we recommend for each element of the struct.
* Since all the elements of the struct are public, they can also be manually filled.
*/
WrapperStructHands(const bool extractAndRenderHands = false);
WrapperStructHand(const bool extractAndRenderHands = false);
};
}
}
#endif // OPENPOSE__WRAPPER__WRAPPER_STRUCT_HANDS_HPP
#endif // OPENPOSE__WRAPPER__WRAPPER_STRUCT_HAND_HPP
@@ -25,14 +25,14 @@ namespace op
/**
* Output size of the final rendered image.
* It barely affects performance compared to netInputSize.
* The final Datum.pose can be scaled with respect to outputSize if `poseScaleMode` is set to ScaleMode::OutputResolution, even if the
* The final Datum.poseKeyPoints can be scaled with respect to outputSize if `poseScaleMode` is set to ScaleMode::OutputResolution, even if the
* rendering is disabled.
*/
cv::Size outputSize;
/**
* Final scale of the Array<float> Datum.pose and the writen pose data.
* The final Datum.pose can be scaled with respect to input size (ScaleMode::InputResolution), net output size (ScaleMode::NetOutputResolution),
* Final scale of the Array<float> Datum.poseKeyPoints and the writen pose data.
* The final Datum.poseKeyPoints can be scaled with respect to input size (ScaleMode::InputResolution), net output size (ScaleMode::NetOutputResolution),
* output rendering size (ScaleMode::OutputResolution), from 0 to 1 (ScaleMode::ZeroToOne), and -1 to 1 (ScaleMode::PlusMinusOne).
*/
ScaleMode poseScaleMode;