OpenPose  1.0.0rc2
OpenPose: A Real-Time Multi-Person Key-Point Detection And Multi-Threading C++ Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
datumProducer.hpp
Go to the documentation of this file.
1 #ifndef OPENPOSE_PRODUCER_DATUM_PRODUCER_HPP
2 #define OPENPOSE_PRODUCER_DATUM_PRODUCER_HPP
3 
4 #include <atomic>
5 #include <limits> // std::numeric_limits
6 #include <tuple>
10 
11 namespace op
12 {
13  template<typename TDatumsNoPtr>
15  {
16  public:
17  explicit DatumProducer(const std::shared_ptr<Producer>& producerSharedPtr,
18  const unsigned long long frameFirst = 0,
19  const unsigned long long frameLast = std::numeric_limits<unsigned long long>::max(),
20  const std::shared_ptr<std::pair<std::atomic<bool>,
21  std::atomic<int>>>& videoSeekSharedPtr = nullptr);
22 
23  std::pair<bool, std::shared_ptr<TDatumsNoPtr>> checkIfRunningAndGetDatum();
24 
25  private:
26  const unsigned long long mNumberFramesToProcess;
27  std::shared_ptr<Producer> spProducer;
28  unsigned long long mGlobalCounter;
29  unsigned int mNumberConsecutiveEmptyFrames;
30  std::shared_ptr<std::pair<std::atomic<bool>, std::atomic<int>>> spVideoSeek;
31 
32  void checkIfTooManyConsecutiveEmptyFrames(unsigned int& numberConsecutiveEmptyFrames,
33  const bool emptyFrame) const;
34 
35  DELETE_COPY(DatumProducer);
36  };
37 }
38 
39 
40 
41 
42 
43 // Implementation
44 #include <opencv2/imgproc/imgproc.hpp> // cv::cvtColor
46 namespace op
47 {
48  template<typename TDatumsNoPtr>
49  DatumProducer<TDatumsNoPtr>::DatumProducer(const std::shared_ptr<Producer>& producerSharedPtr,
50  const unsigned long long frameFirst, const unsigned long long frameLast,
51  const std::shared_ptr<std::pair<std::atomic<bool>,
52  std::atomic<int>>>& videoSeekSharedPtr) :
53  mNumberFramesToProcess{(frameLast != std::numeric_limits<unsigned long long>::max()
54  ? frameLast - frameFirst : frameLast)},
55  spProducer{producerSharedPtr},
56  mGlobalCounter{0ll},
57  mNumberConsecutiveEmptyFrames{0u},
58  spVideoSeek{videoSeekSharedPtr}
59  {
60  try
61  {
62  if (spProducer->getType() != ProducerType::Webcam)
63  spProducer->set(CV_CAP_PROP_POS_FRAMES, (double)frameFirst);
64  }
65  catch (const std::exception& e)
66  {
67  error(e.what(), __LINE__, __FUNCTION__, __FILE__);
68  }
69  }
70 
71  template<typename TDatumsNoPtr>
72  std::pair<bool, std::shared_ptr<TDatumsNoPtr>> DatumProducer<TDatumsNoPtr>::checkIfRunningAndGetDatum()
73  {
74  try
75  {
76  auto datums = std::make_shared<TDatumsNoPtr>();
77  // Check last desired frame has not been reached
78  if (mNumberFramesToProcess != std::numeric_limits<unsigned long long>::max()
79  && mGlobalCounter > mNumberFramesToProcess)
80  {
81  spProducer->release();
82  }
83  // If producer released -> it sends an empty cv::Mat + a datumProducerRunning signal
84  const bool datumProducerRunning = spProducer->isOpened();
85  // If device is open
86  if (datumProducerRunning)
87  {
88  // Fast forward/backward - Seek to specific frame index desired
89  if (spVideoSeek != nullptr)
90  {
91  // Fake pause vs. normal mode
92  const auto increment = spVideoSeek->second + (spVideoSeek->first ? 1 : 0);
93  // Normal mode
94  if (increment != 0)
95  {
96  spProducer->set(CV_CAP_PROP_POS_FRAMES, spProducer->get(CV_CAP_PROP_POS_FRAMES) + increment);
97  spVideoSeek->second = 0;
98  }
99  }
100  auto nextFrameName = spProducer->getNextFrameName();
101  auto cvMats = spProducer->getFrames();
102  auto cameraMatrices = spProducer->getCameraMatrices();
103  // Check frames are not empty
104  checkIfTooManyConsecutiveEmptyFrames(mNumberConsecutiveEmptyFrames, cvMats.empty() || cvMats[0].empty());
105  if (!cvMats.empty())
106  {
107  datums->resize(cvMats.size());
108  // Datum cannot be assigned before resize()
109  auto& datum = (*datums)[0];
110  // Filling first element
111  std::swap(datum.name, nextFrameName);
112  datum.cvInputData = cvMats[0];
113  if (!cameraMatrices.empty())
114  datum.cameraMatrix = cameraMatrices[0];
115  // Image integrity
116  if (datum.cvInputData.channels() != 3)
117  {
118  const std::string commonMessage{"Input images must be 3-channel BGR."};
119  // Grey to RGB if required
120  if (datum.cvInputData.channels() == 1)
121  {
122  log(commonMessage + " Converting grey image into BGR.", Priority::High);
123  cv::cvtColor(datum.cvInputData, datum.cvInputData, CV_GRAY2BGR);
124  }
125  else
126  error(commonMessage, __LINE__, __FUNCTION__, __FILE__);
127  }
128  datum.cvOutputData = datum.cvInputData;
129  // Resize if it's stereo-system
130  if (datums->size() > 1)
131  {
132  // Stereo-system: Assign all cv::Mat
133  for (auto i = 1u ; i < datums->size() ; i++)
134  {
135  auto& datumI = (*datums)[i];
136  datumI.name = datum.name;
137  datumI.cvInputData = cvMats[i];
138  datumI.cvOutputData = datumI.cvInputData;
139  if (cameraMatrices.size() > i)
140  datumI.cameraMatrix = cameraMatrices[i];
141  }
142  }
143  // Check producer is running
144  if (!datumProducerRunning || (*datums)[0].cvInputData.empty())
145  datums = nullptr;
146  // Increase counter if successful image
147  if (datums != nullptr)
148  mGlobalCounter++;
149  }
150  }
151  // Return result
152  return std::make_pair(datumProducerRunning, datums);
153  }
154  catch (const std::exception& e)
155  {
156  error(e.what(), __LINE__, __FUNCTION__, __FILE__);
157  return std::make_pair(false, std::make_shared<TDatumsNoPtr>());
158  }
159  }
160 
161  template<typename TDatumsNoPtr>
162  void DatumProducer<TDatumsNoPtr>::checkIfTooManyConsecutiveEmptyFrames(unsigned int& numberConsecutiveEmptyFrames,
163  const bool emptyFrame) const
164  {
165  numberConsecutiveEmptyFrames = (emptyFrame ? numberConsecutiveEmptyFrames+1 : 0);
166  const auto threshold = 500u;
167  if (numberConsecutiveEmptyFrames >= threshold)
168  error("Detected too many (" + std::to_string(numberConsecutiveEmptyFrames) + ") empty frames in a row.",
169  __LINE__, __FUNCTION__, __FILE__);
170  }
171 
172  extern template class DatumProducer<DATUM_BASE_NO_PTR>;
173 }
174 
175 
176 #endif // OPENPOSE_PRODUCER_DATUM_PRODUCER_HPP
std::pair< bool, std::shared_ptr< TDatumsNoPtr > > checkIfRunningAndGetDatum()
Definition: datumProducer.hpp:72
OP_API void error(const std::string &message, const int line=-1, const std::string &function="", const std::string &file="")
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="")
Definition: datumProducer.hpp:14
DatumProducer(const std::shared_ptr< Producer > &producerSharedPtr, const unsigned long long frameFirst=0, 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:49
std::string string
Definition: cl2.hpp:574