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  spProducer->set(CV_CAP_PROP_POS_FRAMES, spProducer->get(CV_CAP_PROP_POS_FRAMES) + increment);
96  // It must be always reset or bug in fake pause
97  spVideoSeek->second = 0;
98  }
99  auto nextFrameName = spProducer->getNextFrameName();
100  const auto nextFrameNumber = (unsigned long long)spProducer->get(CV_CAP_PROP_POS_FRAMES);
101  const auto cvMats = spProducer->getFrames();
102  const auto cameraMatrices = spProducer->getCameraMatrices();
103  auto cameraExtrinsics = spProducer->getCameraExtrinsics();
104  auto cameraIntrinsics = spProducer->getCameraIntrinsics();
105  // Check frames are not empty
106  checkIfTooManyConsecutiveEmptyFrames(mNumberConsecutiveEmptyFrames, cvMats.empty() || cvMats[0].empty());
107  if (!cvMats.empty())
108  {
109  datums->resize(cvMats.size());
110  // Datum cannot be assigned before resize()
111  auto& datum = (*datums)[0];
112  // Filling first element
113  std::swap(datum.name, nextFrameName);
114  datum.frameNumber = nextFrameNumber;
115  datum.cvInputData = cvMats[0];
116  if (!cameraMatrices.empty())
117  {
118  datum.cameraMatrix = cameraMatrices[0];
119  datum.cameraExtrinsics = cameraExtrinsics[0];
120  datum.cameraIntrinsics = cameraIntrinsics[0];
121  }
122  // Image integrity
123  if (datum.cvInputData.channels() != 3)
124  {
125  const std::string commonMessage{"Input images must be 3-channel BGR."};
126  // Grey to RGB if required
127  if (datum.cvInputData.channels() == 1)
128  {
129  log(commonMessage + " Converting grey image into BGR.", Priority::High);
130  cv::cvtColor(datum.cvInputData, datum.cvInputData, CV_GRAY2BGR);
131  }
132  else
133  error(commonMessage, __LINE__, __FUNCTION__, __FILE__);
134  }
135  datum.cvOutputData = datum.cvInputData;
136  // Resize if it's stereo-system
137  if (datums->size() > 1)
138  {
139  // Stereo-system: Assign all cv::Mat
140  for (auto i = 1u ; i < datums->size() ; i++)
141  {
142  auto& datumI = (*datums)[i];
143  datumI.name = datum.name;
144  datumI.frameNumber = datum.frameNumber;
145  datumI.cvInputData = cvMats[i];
146  datumI.cvOutputData = datumI.cvInputData;
147  if (cameraMatrices.size() > i)
148  {
149  datumI.cameraMatrix = cameraMatrices[i];
150  datumI.cameraExtrinsics = cameraExtrinsics[i];
151  datumI.cameraIntrinsics = cameraIntrinsics[i];
152  }
153  }
154  }
155  // Check producer is running
156  if (!datumProducerRunning || (*datums)[0].cvInputData.empty())
157  datums = nullptr;
158  // Increase counter if successful image
159  if (datums != nullptr)
160  mGlobalCounter++;
161  }
162  }
163  // Return result
164  return std::make_pair(datumProducerRunning, datums);
165  }
166  catch (const std::exception& e)
167  {
168  error(e.what(), __LINE__, __FUNCTION__, __FILE__);
169  return std::make_pair(false, std::make_shared<TDatumsNoPtr>());
170  }
171  }
172 
173  template<typename TDatumsNoPtr>
174  void DatumProducer<TDatumsNoPtr>::checkIfTooManyConsecutiveEmptyFrames(unsigned int& numberConsecutiveEmptyFrames,
175  const bool emptyFrame) const
176  {
177  numberConsecutiveEmptyFrames = (emptyFrame ? numberConsecutiveEmptyFrames+1 : 0);
178  const auto threshold = 500u;
179  if (numberConsecutiveEmptyFrames >= threshold)
180  error("Detected too many (" + std::to_string(numberConsecutiveEmptyFrames) + ") empty frames in a row.",
181  __LINE__, __FUNCTION__, __FILE__);
182  }
183 
184  extern template class DatumProducer<DATUM_BASE_NO_PTR>;
185 }
186 
187 
188 #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