datumProducer.hpp 6.1 KB
Newer Older
1 2
#ifndef OPENPOSE_PRODUCER_DATUM_PRODUCER_HPP
#define OPENPOSE_PRODUCER_DATUM_PRODUCER_HPP
G
gineshidalgo99 已提交
3 4 5 6

#include <atomic>
#include <limits> // std::numeric_limits
#include <tuple>
7
#include <openpose/core/common.hpp>
G
Gines Hidalgo 已提交
8 9
#include <openpose/core/datum.hpp>
#include <openpose/producer/producer.hpp>
G
gineshidalgo99 已提交
10 11 12 13 14 15 16

namespace op
{
    template<typename TDatumsNoPtr>
    class DatumProducer
    {
    public:
17 18
        explicit DatumProducer(const std::shared_ptr<Producer>& producerSharedPtr,
                               const unsigned long long frameFirst = 0,
G
gineshidalgo99 已提交
19 20 21 22 23 24 25 26 27 28 29 30
                               const unsigned long long frameLast = std::numeric_limits<unsigned long long>::max(),
                               const std::shared_ptr<std::pair<std::atomic<bool>, std::atomic<int>>>& videoSeekSharedPtr = nullptr);

        std::pair<bool, std::shared_ptr<TDatumsNoPtr>> checkIfRunningAndGetDatum();

    private:
        const unsigned long long mNumberFramesToProcess;
        std::shared_ptr<Producer> spProducer;
        unsigned long long mGlobalCounter;
        unsigned int mNumberConsecutiveEmptyFrames;
        std::shared_ptr<std::pair<std::atomic<bool>, std::atomic<int>>> spVideoSeek;

31 32
        void checkIfTooManyConsecutiveEmptyFrames(unsigned int& numberConsecutiveEmptyFrames,
                                                  const bool emptyFrame) const;
G
gineshidalgo99 已提交
33 34 35 36 37 38 39 40 41

        DELETE_COPY(DatumProducer);
    };
}





G
Gines 已提交
42
// Implementation
43
#include <opencv2/imgproc/imgproc.hpp> // cv::cvtColor
44
#include <openpose/producer/datumProducer.hpp>
G
gineshidalgo99 已提交
45 46 47
namespace op
{
    template<typename TDatumsNoPtr>
48 49
    DatumProducer<TDatumsNoPtr>::DatumProducer(const std::shared_ptr<Producer>& producerSharedPtr,
                                               const unsigned long long frameFirst, const unsigned long long frameLast,
G
gineshidalgo99 已提交
50
                                               const std::shared_ptr<std::pair<std::atomic<bool>, std::atomic<int>>>& videoSeekSharedPtr) :
51 52
        mNumberFramesToProcess{(frameLast != std::numeric_limits<unsigned long long>::max()
                                ? frameLast - frameFirst : frameLast)},
G
gineshidalgo99 已提交
53 54 55 56 57 58 59 60
        spProducer{producerSharedPtr},
        mGlobalCounter{0ll},
        mNumberConsecutiveEmptyFrames{0u},
        spVideoSeek{videoSeekSharedPtr}
    {
        try
        {
            if (spProducer->getType() != ProducerType::Webcam)
G
Gines Hidalgo 已提交
61
                spProducer->set(CV_CAP_PROP_POS_FRAMES, (double)frameFirst);
G
gineshidalgo99 已提交
62 63 64 65 66 67 68 69 70 71 72 73 74
        }
        catch (const std::exception& e)
        {
            error(e.what(), __LINE__, __FUNCTION__, __FILE__);
        }
    }

    template<typename TDatumsNoPtr>
    std::pair<bool, std::shared_ptr<TDatumsNoPtr>> DatumProducer<TDatumsNoPtr>::checkIfRunningAndGetDatum()
    {
        try
        {
            // Check last desired frame has not been reached
75 76 77
            if (mNumberFramesToProcess != std::numeric_limits<unsigned long long>::max()
                && mGlobalCounter > mNumberFramesToProcess)
            {
G
gineshidalgo99 已提交
78
                spProducer->release();
79
            }
G
gineshidalgo99 已提交
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
            // If producer released -> it sends an empty cv::Mat + a datumProducerRunning signal
            const bool datumProducerRunning = spProducer->isOpened();
            auto datums = std::make_shared<TDatumsNoPtr>(1);
            auto& datum = (*datums)[0];
            // Check producer device is open
            if (datumProducerRunning)
            {
                // Fast forward/backward - Seek to specific frame index desired
                if (spVideoSeek != nullptr)
                {
                    // Fake pause vs. normal mode
                    const auto increment = spVideoSeek->second  + (spVideoSeek->first ? 1 : 0);
                    // Normal mode
                    if (increment != 0)
                    {
                        spProducer->set(CV_CAP_PROP_POS_FRAMES, spProducer->get(CV_CAP_PROP_POS_FRAMES) + increment);
                        spVideoSeek->second = 0;
                    }
                }
                // Get cv::Mat
                datum.name = spProducer->getFrameName();
                datum.cvInputData = spProducer->getFrame();
102 103 104 105 106
                if (datum.cvInputData.channels() != 3)
                {
                    const std::string commonMessage{"Input images must be 3-channel BGR."};
                    if (datum.cvInputData.channels() == 1)
                    {
D
Donglai Xiang 已提交
107
                        log(commonMessage + " Converting grey image into BGR.", Priority::High);
108 109 110 111 112
                        cv::cvtColor(datum.cvInputData, datum.cvInputData, CV_GRAY2BGR);
                    }
                    else
                        error(commonMessage, __LINE__, __FUNCTION__, __FILE__);
                }
G
gineshidalgo99 已提交
113 114 115 116 117
                datum.cvOutputData = datum.cvInputData;
                // Check frames are not empty
                checkIfTooManyConsecutiveEmptyFrames(mNumberConsecutiveEmptyFrames, datum.cvInputData.empty());
            }
            // Check producer is running
118
            if (!datumProducerRunning || datum.cvInputData.empty())
G
gineshidalgo99 已提交
119
                datums = nullptr;
120 121 122
            // Increase counter if successful image
            if (datums != nullptr)
                mGlobalCounter++;
G
gineshidalgo99 已提交
123 124 125 126 127 128 129 130 131 132 133
            // Return result
            return std::make_pair(datumProducerRunning, datums);
        }
        catch (const std::exception& e)
        {
            error(e.what(), __LINE__, __FUNCTION__, __FILE__);
            return std::make_pair(false, std::make_shared<TDatumsNoPtr>());
        }
    }

    template<typename TDatumsNoPtr>
134 135
    void DatumProducer<TDatumsNoPtr>::checkIfTooManyConsecutiveEmptyFrames(unsigned int& numberConsecutiveEmptyFrames,
                                                                           const bool emptyFrame) const
G
gineshidalgo99 已提交
136 137 138 139
    {
        numberConsecutiveEmptyFrames = (emptyFrame ? numberConsecutiveEmptyFrames+1 : 0);
        const auto threshold = 500u;
        if (numberConsecutiveEmptyFrames >= threshold)
140 141
            error("Detected too many (" + std::to_string(numberConsecutiveEmptyFrames) + ") empty frames in a row.",
                  __LINE__, __FUNCTION__, __FILE__);
G
gineshidalgo99 已提交
142 143 144 145 146 147
    }

    extern template class DatumProducer<DATUM_BASE_NO_PTR>;
}


148
#endif // OPENPOSE_PRODUCER_DATUM_PRODUCER_HPP