提交 73093e90 编写于 作者: G gineshidalgo99

Added getKeypoitnsPerson and Array constructor

上级 3377d18c
......@@ -285,6 +285,7 @@ OpenPose Library - Release Notes
14. Added new keypoint-related auxiliary functions in `utilities/keypoints.hpp`.
15. Function `resizeFixedAspectRatio` can take already allocated memory (e.g., faster if target is an Array<T> object, no intermediate cv::Mat required).
16. Added compatibility for OpenCV 4.0, while preserving 2.4.X and 3.X compatibility.
17. Improved and added several functions to `utilities/keypoints.hpp` and Array to simplify keypoint post-processing.
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.
......
......@@ -73,6 +73,20 @@ namespace op
*/
Array(const std::vector<int>& sizes, T* const dataPtr);
/**
* Array constructor.
* @param array Array<T> with the original data array to slice.
* @param index indicates the index of the array to extract.
* @param noCopy indicates whether to perform a copy. Copy will never go to undefined behavior, however, if
* noCopy == true, then:
* 1. It is faster, as no data copy is involved, but...
* 2. If the Array array goes out of scope, then the resulting Array will provoke an undefined behavior.
* 3. If the returned Array is modified, the information in the Array array will also be.
* @return Array<T> with the same dimension than array expect the first dimension being 1. E.g., if array
* is {p,k,m}, the resulting Array<T> is {1,k,m}.
*/
Array(const Array<T>& array, const int index, const bool noCopy = false);
/**
* Copy constructor.
* It performs `fast copy`: For performance purpose, copying a Array<T> or Datum or cv::Mat just copies the
......@@ -225,10 +239,12 @@ namespace op
* Similar to getVolume(), but in this case it just returns the volume between the desired dimensions.
* E.g., for a Array<T> of size = {2,5,3}, the volume or total number of elements for getVolume(1,2) is
* 5x3 = 15.
* @param indexA Dimension where to start.
* @param indexB Dimension where to stop. If indexB == -1, then it will take up to the last dimension.
* @return The total volume of the allocated data between the desired dimensions. If the index are out of
* bounds, it throws an error.
*/
size_t getVolume(const int indexA, const int indexB) const;
size_t getVolume(const int indexA, const int indexB = -1) const;
/**
* Return the stride or step size of the array.
......
......@@ -47,6 +47,21 @@ namespace op
T getDistanceAverage(const Array<T>& keypointsA, const int personA, const Array<T>& keypointsB, const int personB,
const T threshold);
/**
* Creates and Array<T> with a specific person.
* @param keypoints Array<T> with the original data array to slice.
* @param person indicates the index of the array to extract.
* @param noCopy indicates whether to perform a copy. Copy will never go to undefined behavior, however, if
* noCopy == true, then:
* 1. It is faster, as no data copy is involved, but...
* 2. If the Array keypoints goes out of scope, then the resulting Array will provoke an undefined behavior.
* 3. If the returned Array is modified, the information in the Array keypoints will also be.
* @return Array<T> with the same dimension than keypoints expect the first dimension being 1. E.g., if keypoints
* is {p,k,m}, the resulting Array<T> is {1,k,m}.
*/
template <typename T>
Array<T> getKeypointsPerson(const Array<T>& keypoints, const int person, const bool noCopy = false);
template <typename T>
float getKeypointsRoi(const Array<T>& keypoints, const int personA, const int personB, const T threshold);
......
......@@ -160,6 +160,37 @@ namespace op
}
}
template<typename T>
Array<T>::Array(const Array<T>& array, const int index, const bool noCopy)
{
try
{
// Sanity check
if (array.getSize(0) <= index)
error("Index out of range.", __LINE__, __FUNCTION__, __FILE__);
// Define new size
auto sizes = array.getSize();
sizes[0] = 1;
// Move --> Temporary Array<T> as long as `array` is in scope
if (noCopy)
resetAuxiliary(sizes, array.getPseudoConstPtr() + index*array.getVolume(1));
// Copy --> Slower but it will always stay in scope
else
{
// Allocate memory
reset(sizes);
// Copy desired index
const auto arrayArea = array.getVolume(1);
const auto keypointsIndex = index*arrayArea;
std::copy(&array[keypointsIndex], &array[keypointsIndex]+arrayArea, pData);
}
}
catch (const std::exception& e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
template<typename T>
Array<T>::Array(const Array<T>& array) :
mSize{array.mSize},
......@@ -407,20 +438,22 @@ namespace op
{
try
{
if (indexA < indexB)
const auto indexBFinal = (indexB != -1 ? indexB : (int)mSize.size()-1);
if (indexA < indexBFinal)
{
if (0 <= indexA && (unsigned int)indexB < mSize.size()) // 0 <= indexA < indexB < mSize.size()
// 0 <= indexA < indexBFinal < mSize.size()
if (0 <= indexA && (unsigned int)indexBFinal < mSize.size())
return std::accumulate(
mSize.begin()+indexA, mSize.begin()+indexB+1, 1ull, std::multiplies<size_t>());
mSize.begin()+indexA, mSize.begin()+indexBFinal+1, 1ull, std::multiplies<size_t>());
else
{
error("Indexes out of dimension.", __LINE__, __FUNCTION__, __FILE__);
return 0;
}
}
else if (indexA == indexB)
else if (indexA == indexBFinal)
return mSize.at(indexA);
else // if (indexA > indexB)
else // if (indexA > indexBFinal)
{
error("indexA > indexB.", __LINE__, __FUNCTION__, __FILE__);
return 0;
......
......@@ -52,7 +52,7 @@ namespace op
// Naively, we could accidentally keep the first 2x 0.5 and remove the 1.0 threshold.
// Our method keeps the first 0.5 and 1.0.
Array<float> topPeopleArray({mNumberPeopleMax, peopleArray.getSize(1), peopleArray.getSize(2)});
const auto personArea = peopleArray.getSize(1) * peopleArray.getSize(2);
const auto personArea = peopleArray.getVolume(1, 2);
auto assignedPeopleOnThreshold = 0;
auto nextPersonIndex = 0;
const auto numberPeopleOnThresholdToBeAdded = mNumberPeopleMax - numberPeopleAboveThreshold;
......
......@@ -495,6 +495,24 @@ namespace op
const Array<double>& keypointsA, const int personA, const Array<double>& keypointsB, const int personB,
const double threshold);
template <typename T>
Array<T> getKeypointsPerson(const Array<T>& keypoints, const int person, const bool noCopy)
{
try
{
return Array<T>(keypoints, person, noCopy);
}
catch (const std::exception& e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
return Array<T>{};
}
}
template OP_API Array<float> getKeypointsPerson(
const Array<float>& keypoints, const int person, const bool noCopy);
template OP_API Array<double> getKeypointsPerson(
const Array<double>& keypoints, const int person, const bool noCopy);
template <typename T>
float getKeypointsRoi(const Array<T>& keypoints, const int personA, const int personB, const T threshold)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册