All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
datumProducer.hpp
Go to the documentation of this file.
#ifndef OPENPOSE_PRODUCER_DATUM_PRODUCER_HPP
#define OPENPOSE_PRODUCER_DATUM_PRODUCER_HPP
#include <atomic>
#include <limits> // std::numeric_limits
#include <tuple>
#include <openpose/core/common.hpp>
#include <openpose/core/datum.hpp>
#include <openpose/utilities/fastMath.hpp>
#include <openpose/producer/producer.hpp>
namespace op
{
template<typename TDatumsNoPtr>
class DatumProducer
{
public:
explicit DatumProducer(const std::shared_ptr<Producer>& producerSharedPtr,
const unsigned long long frameFirst = 0, const unsigned long long frameStep = 1,
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);
virtual ~DatumProducer();
std::pair<bool, std::shared_ptr<TDatumsNoPtr>> checkIfRunningAndGetDatum();
private:
const unsigned long long mNumberFramesToProcess;
std::shared_ptr<Producer> spProducer;
unsigned long long mGlobalCounter;
unsigned long long mFrameStep;
unsigned int mNumberConsecutiveEmptyFrames;
std::shared_ptr<std::pair<std::atomic<bool>, std::atomic<int>>> spVideoSeek;
void checkIfTooManyConsecutiveEmptyFrames(unsigned int& numberConsecutiveEmptyFrames,
const bool emptyFrame) const;
DELETE_COPY(DatumProducer);
};
}
// Implementation
#include <opencv2/imgproc/imgproc.hpp> // cv::cvtColor
#include <openpose/producer/datumProducer.hpp>
namespace op
{
template<typename TDatumsNoPtr>
DatumProducer<TDatumsNoPtr>::DatumProducer(const std::shared_ptr<Producer>& producerSharedPtr,
const unsigned long long frameFirst, const unsigned long long frameStep,
const unsigned long long frameLast,
const std::shared_ptr<std::pair<std::atomic<bool>,
std::atomic<int>>>& videoSeekSharedPtr) :
mNumberFramesToProcess{(frameLast != std::numeric_limits<unsigned long long>::max()
? frameLast - frameFirst : frameLast)},
spProducer{producerSharedPtr},
mGlobalCounter{0ll},
mFrameStep{frameStep},
mNumberConsecutiveEmptyFrames{0u},
spVideoSeek{videoSeekSharedPtr}
{
try
{
// Sanity check
if (frameLast < frameFirst)
error("The desired initial frame must be lower than the last one (flags `--frame_first` vs."
" `--frame_last`). Current: " + std::to_string(frameFirst) + " vs. " + std::to_string(frameLast)
+ ".", __LINE__, __FUNCTION__, __FILE__);
if (frameLast != std::numeric_limits<unsigned long long>::max()
&& frameLast > spProducer->get(CV_CAP_PROP_FRAME_COUNT)-1)
error("The desired last frame must be lower than the length of the video or the number of images."
" Current: " + std::to_string(frameLast) + " vs. "
+ std::to_string(intRound(spProducer->get(CV_CAP_PROP_FRAME_COUNT))-1) + ".",
__LINE__, __FUNCTION__, __FILE__);
// Set frame first and step
if (spProducer->getType() != ProducerType::FlirCamera && spProducer->getType() != ProducerType::IPCamera
&& spProducer->getType() != ProducerType::Webcam)
{
// Frame first
spProducer->set(CV_CAP_PROP_POS_FRAMES, (double)frameFirst);
// Frame step
spProducer->set(ProducerProperty::FrameStep, (double)frameStep);
}
}
catch (const std::exception& e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
}
}
template<typename TDatumsNoPtr>
DatumProducer<TDatumsNoPtr>::~DatumProducer()
{
}
template<typename TDatumsNoPtr>
std::pair<bool, std::shared_ptr<TDatumsNoPtr>> DatumProducer<TDatumsNoPtr>::checkIfRunningAndGetDatum()
{
try
{
auto datums = std::make_shared<TDatumsNoPtr>();
// Check last desired frame has not been reached
if (mNumberFramesToProcess != std::numeric_limits<unsigned long long>::max()
&& mGlobalCounter > mNumberFramesToProcess)
{
spProducer->release();
}
// If producer released -> it sends an empty cv::Mat + a datumProducerRunning signal
const bool datumProducerRunning = spProducer->isOpened();
// If 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);
// It must be always reset or bug in fake pause
spVideoSeek->second = 0;
}
auto nextFrameName = spProducer->getNextFrameName();
const auto nextFrameNumber = (unsigned long long)spProducer->get(CV_CAP_PROP_POS_FRAMES);
const auto cvMats = spProducer->getFrames();
const auto cameraMatrices = spProducer->getCameraMatrices();
auto cameraExtrinsics = spProducer->getCameraExtrinsics();
auto cameraIntrinsics = spProducer->getCameraIntrinsics();
// Check frames are not empty
checkIfTooManyConsecutiveEmptyFrames(mNumberConsecutiveEmptyFrames, cvMats.empty() || cvMats[0].empty());
if (!cvMats.empty())
{
datums->resize(cvMats.size());
// Datum cannot be assigned before resize()
auto& datum = (*datums)[0];
// Filling first element
std::swap(datum.name, nextFrameName);
datum.frameNumber = nextFrameNumber;
datum.cvInputData = cvMats[0];
if (!cameraMatrices.empty())
{
datum.cameraMatrix = cameraMatrices[0];
datum.cameraExtrinsics = cameraExtrinsics[0];
datum.cameraIntrinsics = cameraIntrinsics[0];
}
// Image integrity
if (datum.cvInputData.channels() != 3)
{
const std::string commonMessage{"Input images must be 3-channel BGR."};
// Grey to RGB if required
if (datum.cvInputData.channels() == 1)
{
log(commonMessage + " Converting grey image into BGR.", Priority::High);
cv::cvtColor(datum.cvInputData, datum.cvInputData, CV_GRAY2BGR);
}
else
error(commonMessage, __LINE__, __FUNCTION__, __FILE__);
}
datum.cvOutputData = datum.cvInputData;
// Resize if it's stereo-system
if (datums->size() > 1)
{
// Stereo-system: Assign all cv::Mat
for (auto i = 1u ; i < datums->size() ; i++)
{
auto& datumI = (*datums)[i];
datumI.name = datum.name;
datumI.frameNumber = datum.frameNumber;
datumI.cvInputData = cvMats[i];
datumI.cvOutputData = datumI.cvInputData;
if (cameraMatrices.size() > i)
{
datumI.cameraMatrix = cameraMatrices[i];
datumI.cameraExtrinsics = cameraExtrinsics[i];
datumI.cameraIntrinsics = cameraIntrinsics[i];
}
}
}
// Check producer is running
if (!datumProducerRunning || (*datums)[0].cvInputData.empty())
datums = nullptr;
// Increase counter if successful image
if (datums != nullptr)
mGlobalCounter += mFrameStep;
}
}
// 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>
void DatumProducer<TDatumsNoPtr>::checkIfTooManyConsecutiveEmptyFrames(unsigned int& numberConsecutiveEmptyFrames,
const bool emptyFrame) const
{
numberConsecutiveEmptyFrames = (emptyFrame ? numberConsecutiveEmptyFrames+1 : 0);
const auto threshold = 500u;
if (numberConsecutiveEmptyFrames >= threshold)
error("Detected too many (" + std::to_string(numberConsecutiveEmptyFrames) + ") empty frames in a row.",
__LINE__, __FUNCTION__, __FILE__);
}
extern template class DatumProducer<DATUM_BASE_NO_PTR>;
}
#endif // OPENPOSE_PRODUCER_DATUM_PRODUCER_HPP
fastMath.hpp
datumProducer.hpp
op::DatumProducer::checkIfRunningAndGetDatum
std::pair< bool, std::shared_ptr< TDatumsNoPtr > > checkIfRunningAndGetDatum()
Definition: datumProducer.hpp:101
op::ProducerType::Webcam
common.hpp
op::error
OP_API void error(const std::string &message, const int line=-1, const std::string &function="", const std::string &file="")
op::ProducerType::IPCamera
op::DatumProducer::~DatumProducer
virtual ~DatumProducer()
Definition: datumProducer.hpp:96
datum.hpp
op::ProducerType::FlirCamera
op::log
OP_API void log(const std::string &message, const Priority priority=Priority::Max, const int line=-1, const std::string &function="", const std::string &file="")
op::DatumProducer
Definition: datumProducer.hpp:15
op::ProducerProperty::FrameStep
op::intRound
int intRound(const T a)
Definition: fastMath.hpp:26
op::DatumProducer::DatumProducer
DatumProducer(const std::shared_ptr< Producer > &producerSharedPtr, const unsigned long long frameFirst=0, const unsigned long long frameStep=1, 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)
Definition: datumProducer.hpp:53
producer.hpp
op::Priority::High
cl::string
std::string string
Definition: cl2.hpp:574