scaleAndSizeExtractor.cpp 4.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#include <openpose/utilities/fastMath.hpp>
#include <openpose/utilities/openCv.hpp> // resizeGetScaleFactor
#include <openpose/core/scaleAndSizeExtractor.hpp>

namespace op
{
    ScaleAndSizeExtractor::ScaleAndSizeExtractor(const Point<int>& netInputResolution,
                                                 const Point<int>& outputResolution, const int scaleNumber,
                                                 const double scaleGap) :
        mNetInputResolution{netInputResolution},
        mOutputSize{outputResolution},
        mScaleNumber{scaleNumber},
        mScaleGap{scaleGap}
    {
        try
        {
17
            // Sanity checks
18 19 20 21 22 23 24 25 26 27 28 29 30 31
            if ((netInputResolution.x > 0 && netInputResolution.x % 16 != 0)
                || (netInputResolution.y > 0 && netInputResolution.y % 16 != 0))
                error("Net input resolution must be multiples of 16.", __LINE__, __FUNCTION__, __FILE__);
            if (scaleNumber < 1)
                error("There must be at least 1 scale.", __LINE__, __FUNCTION__, __FILE__);
            if (scaleGap <= 0.)
                error("The gap between scales must be strictly positive.", __LINE__, __FUNCTION__, __FILE__);
        }
        catch (const std::exception& e)
        {
            error(e.what(), __LINE__, __FUNCTION__, __FILE__);
        }
    }

32 33 34 35
    ScaleAndSizeExtractor::~ScaleAndSizeExtractor()
    {
    }

36 37 38 39 40
    std::tuple<std::vector<double>, std::vector<Point<int>>, double, Point<int>> ScaleAndSizeExtractor::extract(
        const Point<int>& inputResolution) const
    {
        try
        {
41
            // Sanity check
42 43
            if (inputResolution.area() <= 0)
                error("Wrong input element (empty cvInputData).", __LINE__, __FUNCTION__, __FILE__);
44 45 46 47
            // Set poseNetInputSize
            auto poseNetInputSize = mNetInputResolution;
            if (poseNetInputSize.x <= 0 || poseNetInputSize.y <= 0)
            {
48
                // Sanity check
49 50 51 52 53 54 55 56 57 58 59 60
                if (poseNetInputSize.x <= 0 && poseNetInputSize.y <= 0)
                    error("Only 1 of the dimensions of net input resolution can be <= 0.",
                          __LINE__, __FUNCTION__, __FILE__);
                if (poseNetInputSize.x <= 0)
                    poseNetInputSize.x = 16 * intRound(
                        poseNetInputSize.y * inputResolution.x / (float) inputResolution.y / 16.f
                    );
                else // if (poseNetInputSize.y <= 0)
                    poseNetInputSize.y = 16 * intRound(
                        poseNetInputSize.x * inputResolution.y / (float) inputResolution.x / 16.f
                    );
            }
61
            // scaleInputToNetInputs & netInputSizes - Reescale keeping aspect ratio
62
            std::vector<double> scaleInputToNetInputs(mScaleNumber, 1.f);
63
            std::vector<Point<int>> netInputSizes(mScaleNumber);
64 65 66 67
            for (auto i = 0; i < mScaleNumber; i++)
            {
                const auto currentScale = 1. - i*mScaleGap;
                if (currentScale < 0. || 1. < currentScale)
G
gineshidalgo99 已提交
68
                    error("All scales must be in the range [0, 1], i.e., 0 <= 1-scale_number*scale_gap <= 1",
69 70
                          __LINE__, __FUNCTION__, __FILE__);

71 72 73 74
                const auto targetWidth = fastTruncate(intRound(poseNetInputSize.x * currentScale) / 16 * 16, 1,
                                                      poseNetInputSize.x);
                const auto targetHeight = fastTruncate(intRound(poseNetInputSize.y * currentScale) / 16 * 16, 1,
                                                       poseNetInputSize.y);
75
                const Point<int> targetSize{targetWidth, targetHeight};
76
                scaleInputToNetInputs[i] = resizeGetScaleFactor(inputResolution, targetSize);
77
                netInputSizes[i] = targetSize;
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
            }
            // scaleInputToOutput - Scale between input and desired output size
            Point<int> outputResolution;
            double scaleInputToOutput;
            // Output = mOutputSize3D size
            if (mOutputSize.x > 0 && mOutputSize.y > 0)
            {
                outputResolution = mOutputSize;
                scaleInputToOutput = resizeGetScaleFactor(inputResolution, outputResolution);
            }
            // Output = input size
            else
            {
                outputResolution = inputResolution;
                scaleInputToOutput = 1.;
            }
            // Return result
95
            return std::make_tuple(scaleInputToNetInputs, netInputSizes, scaleInputToOutput, outputResolution);
96 97 98 99 100 101 102 103
        }
        catch (const std::exception& e)
        {
            error(e.what(), __LINE__, __FUNCTION__, __FILE__);
            return std::make_tuple(std::vector<double>{}, std::vector<Point<int>>{}, 1., Point<int>{});
        }
    }
}