提交 29ea7e24 编写于 作者: G gineshidalgo99

Face/hand working with any output resolution

上级 a2032494
...@@ -215,7 +215,9 @@ OpenPose Library - Release Notes ...@@ -215,7 +215,9 @@ OpenPose Library - Release Notes
1. Main improvements: 1. Main improvements:
1. Flir cameras: Added software trigger and a dedicated thread to keep reading images to remove latency (analogously to webcamReader). 1. Flir cameras: Added software trigger and a dedicated thread to keep reading images to remove latency (analogously to webcamReader).
2. Functions or parameters renamed: 2. Functions or parameters renamed:
1. Removed scale parameter from hand and face rectangle extractor (causing wrong results if custom `--output_resolution`).
3. Main bugs fixed: 3. Main bugs fixed:
1. Hand and face work properly again with any `--output_resolution`.
......
...@@ -11,7 +11,7 @@ namespace op ...@@ -11,7 +11,7 @@ namespace op
public: public:
explicit FaceDetector(const PoseModel poseModel); explicit FaceDetector(const PoseModel poseModel);
std::vector<Rectangle<float>> detectFaces(const Array<float>& poseKeypoints, const double scaleInputToOutput) const; std::vector<Rectangle<float>> detectFaces(const Array<float>& poseKeypoints) const;
private: private:
const unsigned int mNeck; const unsigned int mNeck;
......
...@@ -56,7 +56,7 @@ namespace op ...@@ -56,7 +56,7 @@ namespace op
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
// Detect people face // Detect people face
for (auto& tDatum : *tDatums) for (auto& tDatum : *tDatums)
tDatum.faceRectangles = spFaceDetector->detectFaces(tDatum.poseKeypoints, tDatum.scaleInputToOutput); tDatum.faceRectangles = spFaceDetector->detectFaces(tDatum.poseKeypoints);
// Profiling speed // Profiling speed
Profiler::timerEnd(profilerKey); Profiler::timerEnd(profilerKey);
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__); Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
......
...@@ -14,9 +14,9 @@ namespace op ...@@ -14,9 +14,9 @@ namespace op
public: public:
explicit HandDetector(const PoseModel poseModel); explicit HandDetector(const PoseModel poseModel);
std::vector<std::array<Rectangle<float>, 2>> detectHands(const Array<float>& poseKeypoints, const double scaleInputToOutput) const; std::vector<std::array<Rectangle<float>, 2>> detectHands(const Array<float>& poseKeypoints) const;
std::vector<std::array<Rectangle<float>, 2>> trackHands(const Array<float>& poseKeypoints, const double scaleInputToOutput); std::vector<std::array<Rectangle<float>, 2>> trackHands(const Array<float>& poseKeypoints);
void updateTracker(const std::array<Array<float>, 2>& handKeypoints, const unsigned long long id); void updateTracker(const std::array<Array<float>, 2>& handKeypoints, const unsigned long long id);
......
...@@ -56,7 +56,7 @@ namespace op ...@@ -56,7 +56,7 @@ namespace op
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
// Detect people hand // Detect people hand
for (auto& tDatum : *tDatums) for (auto& tDatum : *tDatums)
tDatum.handRectangles = spHandDetector->detectHands(tDatum.poseKeypoints, tDatum.scaleInputToOutput); tDatum.handRectangles = spHandDetector->detectHands(tDatum.poseKeypoints);
// Profiling speed // Profiling speed
Profiler::timerEnd(profilerKey); Profiler::timerEnd(profilerKey);
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__); Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
......
...@@ -56,7 +56,7 @@ namespace op ...@@ -56,7 +56,7 @@ namespace op
const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__);
// Detect people hand // Detect people hand
for (auto& tDatum : *tDatums) for (auto& tDatum : *tDatums)
tDatum.handRectangles = spHandDetector->trackHands(tDatum.poseKeypoints, tDatum.scaleInputToOutput); tDatum.handRectangles = spHandDetector->trackHands(tDatum.poseKeypoints);
// Profiling speed // Profiling speed
Profiler::timerEnd(profilerKey); Profiler::timerEnd(profilerKey);
Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__); Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__);
......
...@@ -15,9 +15,11 @@ namespace op ...@@ -15,9 +15,11 @@ namespace op
{ {
} }
inline Rectangle<float> getFaceFromPoseKeypoints(const Array<float>& poseKeypoints, const unsigned int personIndex, const unsigned int neck, inline Rectangle<float> getFaceFromPoseKeypoints(const Array<float>& poseKeypoints, const unsigned int personIndex,
const unsigned int headNose, const unsigned int lEar, const unsigned int rEar, const unsigned int neck, const unsigned int headNose,
const unsigned int lEye, const unsigned int rEye, const float threshold) const unsigned int lEar, const unsigned int rEar,
const unsigned int lEye, const unsigned int rEye,
const float threshold)
{ {
try try
{ {
...@@ -58,13 +60,17 @@ namespace op ...@@ -58,13 +60,17 @@ namespace op
{ {
pointTopLeft.x += (posePtr[lEye*3] + posePtr[lEar*3] + posePtr[headNose*3]) / 3.f; pointTopLeft.x += (posePtr[lEye*3] + posePtr[lEar*3] + posePtr[headNose*3]) / 3.f;
pointTopLeft.y += (posePtr[lEye*3+1] + posePtr[lEar*3+1] + posePtr[headNose*3+1]) / 3.f; pointTopLeft.y += (posePtr[lEye*3+1] + posePtr[lEar*3+1] + posePtr[headNose*3+1]) / 3.f;
faceSize += 0.85f * (getDistance(poseKeypoints, personIndex, headNose, lEye) + getDistance(poseKeypoints, personIndex, headNose, lEar) + getDistance(poseKeypoints, personIndex, neck, headNose)); faceSize += 0.85f * (getDistance(poseKeypoints, personIndex, headNose, lEye)
+ getDistance(poseKeypoints, personIndex, headNose, lEar)
+ getDistance(poseKeypoints, personIndex, neck, headNose));
} }
else // if(lEyeScoreAbove) else // if(lEyeScoreAbove)
{ {
pointTopLeft.x += (posePtr[rEye*3] + posePtr[rEar*3] + posePtr[headNose*3]) / 3.f; pointTopLeft.x += (posePtr[rEye*3] + posePtr[rEar*3] + posePtr[headNose*3]) / 3.f;
pointTopLeft.y += (posePtr[rEye*3+1] + posePtr[rEar*3+1] + posePtr[headNose*3+1]) / 3.f; pointTopLeft.y += (posePtr[rEye*3+1] + posePtr[rEar*3+1] + posePtr[headNose*3+1]) / 3.f;
faceSize += 0.85f * (getDistance(poseKeypoints, personIndex, headNose, rEye) + getDistance(poseKeypoints, personIndex, headNose, rEar) + getDistance(poseKeypoints, personIndex, neck, headNose)); faceSize += 0.85f * (getDistance(poseKeypoints, personIndex, headNose, rEye)
+ getDistance(poseKeypoints, personIndex, headNose, rEar)
+ getDistance(poseKeypoints, personIndex, neck, headNose));
} }
} }
// else --> 2 * dist(neck, headNose) // else --> 2 * dist(neck, headNose)
...@@ -108,7 +114,7 @@ namespace op ...@@ -108,7 +114,7 @@ namespace op
} }
} }
std::vector<Rectangle<float>> FaceDetector::detectFaces(const Array<float>& poseKeypoints, const double scaleInputToOutput) const std::vector<Rectangle<float>> FaceDetector::detectFaces(const Array<float>& poseKeypoints) const
{ {
try try
{ {
...@@ -119,7 +125,8 @@ namespace op ...@@ -119,7 +125,8 @@ namespace op
// Otherwise, get face position(s) // Otherwise, get face position(s)
if (!poseKeypoints.empty()) if (!poseKeypoints.empty())
for (auto person = 0 ; person < numberPeople ; person++) for (auto person = 0 ; person < numberPeople ; person++)
faceRectangles.at(person) = getFaceFromPoseKeypoints(poseKeypoints, person, mNeck, mNose, mLEar, mREar, mLEye, mREye, threshold) / (float)scaleInputToOutput; faceRectangles.at(person) = getFaceFromPoseKeypoints(
poseKeypoints, person, mNeck, mNose, mLEar, mREar, mLEye, mREye, threshold);
return faceRectangles; return faceRectangles;
} }
catch (const std::exception& e) catch (const std::exception& e)
......
...@@ -130,7 +130,7 @@ namespace op ...@@ -130,7 +130,7 @@ namespace op
{ {
} }
std::vector<std::array<Rectangle<float>, 2>> HandDetector::detectHands(const Array<float>& poseKeypoints, const double scaleInputToOutput) const std::vector<std::array<Rectangle<float>, 2>> HandDetector::detectHands(const Array<float>& poseKeypoints) const
{ {
try try
{ {
...@@ -148,8 +148,6 @@ namespace op ...@@ -148,8 +148,6 @@ namespace op
mPoseIndexes[(int)PosePart::LShoulder], mPoseIndexes[(int)PosePart::RWrist], mPoseIndexes[(int)PosePart::LShoulder], mPoseIndexes[(int)PosePart::RWrist],
mPoseIndexes[(int)PosePart::RElbow], mPoseIndexes[(int)PosePart::RShoulder], threshold mPoseIndexes[(int)PosePart::RElbow], mPoseIndexes[(int)PosePart::RShoulder], threshold
); );
handRectangles.at(person).at(0) /= (float) scaleInputToOutput;
handRectangles.at(person).at(1) /= (float) scaleInputToOutput;
} }
} }
return handRectangles; return handRectangles;
...@@ -161,13 +159,13 @@ namespace op ...@@ -161,13 +159,13 @@ namespace op
} }
} }
std::vector<std::array<Rectangle<float>, 2>> HandDetector::trackHands(const Array<float>& poseKeypoints, const double scaleInputToOutput) std::vector<std::array<Rectangle<float>, 2>> HandDetector::trackHands(const Array<float>& poseKeypoints)
{ {
try try
{ {
std::lock_guard<std::mutex> lock{mMutex}; std::lock_guard<std::mutex> lock{mMutex};
// Baseline detectHands // Baseline detectHands
auto handRectangles = detectHands(poseKeypoints, scaleInputToOutput); auto handRectangles = detectHands(poseKeypoints);
// If previous hands saved // If previous hands saved
for (auto& handRectangle : handRectangles) for (auto& handRectangle : handRectangles)
{ {
......
...@@ -354,8 +354,10 @@ namespace op ...@@ -354,8 +354,10 @@ namespace op
} }
if (imagesExtracted) if (imagesExtracted)
{ {
const std::lock_guard<std::mutex> lock{mBufferMutex}; std::unique_lock<std::mutex> lock{mBufferMutex};
std::swap(mBuffer, imagePtrs); std::swap(mBuffer, imagePtrs);
lock.unlock();
std::this_thread::sleep_for(std::chrono::microseconds{1});
} }
} }
} }
...@@ -408,23 +410,9 @@ namespace op ...@@ -408,23 +410,9 @@ namespace op
std::this_thread::sleep_for(std::chrono::microseconds{5}); std::this_thread::sleep_for(std::chrono::microseconds{5});
} }
} }
// Commented code was supposed to clean buffer, but `NewestFirstOverwrite` does that
// Getting frames // Getting frames
// Retrieve next received image and ensure image completion // Retrieve next received image and ensure image completion
// Spinnaker::ImagePtr imagePtr = cameraPtrs.at(i)->GetNextImage(); // Spinnaker::ImagePtr imagePtr = cameraPtrs.at(i)->GetNextImage();
// Clean buffer + retrieve next received image + ensure image completion
// auto durationMs = 0.;
// // for (auto counter = 0 ; counter < 10 ; counter++)
// while (durationMs < 1.)
// {
// const auto begin = std::chrono::high_resolution_clock::now();
// for (auto i = 0u; i < cameraPtrs.size(); i++)
// imagePtrs.at(i) = cameraPtrs.at(i)->GetNextImage();
// durationMs = std::chrono::duration_cast<std::chrono::nanoseconds>(
// std::chrono::high_resolution_clock::now()-begin
// ).count() * 1e-6;
// // log("Time extraction (ms): " + std::to_string(durationMs), Priority::High);
// }
// All images completed // All images completed
bool imagesExtracted = true; bool imagesExtracted = true;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册