Visual Servoing Platform  version 3.4.1 under development (2021-09-19)
vpImageQueue.h
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Image queue for storage helper.
33  *
34  *****************************************************************************/
35 
36 #ifndef vpImageQueue_h
37 #define vpImageQueue_h
38 
39 #include <visp3/core/vpConfig.h>
40 
41 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
42 
43 #include <string>
44 #include <queue>
45 #include <mutex>
46 #include <thread>
47 #include <condition_variable>
48 
49 #include <visp3/core/vpIoTools.h>
50 #include <visp3/core/vpDisplay.h>
51 
62 template <class Type>
63 class vpImageQueue {
64 public:
65  struct cancelled {
66  };
67 
74  vpImageQueue(const std::string &seqname, int record_mode)
75  : m_cancelled(false), m_cond(), m_queue_image(), m_queue_data(), m_maxQueueSize(1024*8), m_mutex(),
76  m_seqname(seqname), m_recording_mode(record_mode), m_start_recording(false), m_directory_to_create(false),
77  m_recording_trigger(false)
78  {
79  m_directory = vpIoTools::getParent(seqname);
80  if (! m_directory.empty()) {
81  if (! vpIoTools::checkDirectory(m_directory)) {
82  m_directory_to_create = true;
83  }
84  }
85  m_text_record_mode = std::string("Record mode: ") + (m_recording_mode ? std::string("single") : std::string("continuous"));
86  }
87 
91  void cancel() {
92  std::lock_guard<std::mutex> lock(m_mutex);
93  std::cout << "Wait to finish saving images..." << std::endl;
94  m_cancelled = true;
95  m_cond.notify_all();
96  }
97 
101  int getRecordingMode() const
102  {
103  return m_recording_mode;
104  }
105 
109  bool getRecordingTrigger() const
110  {
111  return m_recording_trigger;
112  }
113 
117  std::string getSeqName() const
118  {
119  return m_seqname;
120  }
121 
129  void pop(vpImage<Type> &I, std::string &data) {
130  std::unique_lock<std::mutex> lock(m_mutex);
131 
132  while (m_queue_image.empty()) {
133  if (m_cancelled) {
134  throw cancelled();
135  }
136 
137  m_cond.wait(lock);
138 
139  if (m_cancelled) {
140  throw cancelled();
141  }
142  }
143 
144  I = m_queue_image.front();
145 
146  m_queue_image.pop();
147 
148  if (! m_queue_data.empty()) {
149  data = m_queue_data.front();
150  m_queue_data.pop();
151  }
152  }
153 
160  void push(const vpImage<Type> &I, std::string *data) {
161  std::lock_guard<std::mutex> lock(m_mutex);
162 
163  m_queue_image.push(I);
164 
165  if (data != NULL) {
166  m_queue_data.push(*data);
167  }
168 
169  //Pop extra data in the queue
170  while (m_queue_image.size() > m_maxQueueSize) {
171  m_queue_image.pop();
172  }
173 
174  if (data != NULL) {
175  while(m_queue_data.size() > m_maxQueueSize) {
176  m_queue_data.pop();
177  }
178  }
179 
180  m_cond.notify_one();
181  }
182 
191  bool record(const vpImage<Type> &I, std::string *data = NULL, bool trigger_recording = false, bool disable_left_click = false)
192  {
193  if (! m_seqname.empty()) {
194  if (! disable_left_click) {
195  if (! m_recording_mode) { // continuous
196  if (m_start_recording) {
198  }
199  else {
201  }
202  }
203  else {
205  }
206  }
208  }
209  else {
211  }
212 
213  if (! m_seqname.empty()) {
215  }
217  if (vpDisplay::getClick(I, button, false)) {
218  if (! m_seqname.empty()) { // Recording requested
219  if (button == vpMouseButton::button1 && ! disable_left_click) { // enable/disable recording
220  m_start_recording = !m_start_recording;
221  }
222  else if (button == vpMouseButton::button3) { // quit
223  return true;
224  }
225  }
226  else { // any button to quit
227  return true;
228  }
229  }
230 
231  if (trigger_recording) {
232  m_start_recording = true;
233  }
234 
235  m_recording_trigger = m_start_recording;
236 
237  if (m_start_recording) {
238 
239  if (m_directory_to_create) {
240  std::cout << "Create directory \"" << m_directory << "\"" << std::endl;
241  vpIoTools::makeDirectory(m_directory);
242  m_directory_to_create = false;
243  }
244 
245  push(I, data);
246 
247  if (m_recording_mode == 1) { // single shot mode
248  m_start_recording = false;
249  }
250  }
251  return false;
252  }
253 
258  void setMaxQueueSize(const size_t max_queue_size) {
259  m_maxQueueSize = max_queue_size;
260  }
261 
262 private:
263  bool m_cancelled;
264  std::condition_variable m_cond;
265  std::queue<vpImage<Type> > m_queue_image;
266  std::queue<std::string > m_queue_data;
267  size_t m_maxQueueSize;
268  std::mutex m_mutex;
269  std::string m_seqname;
270  std::string m_directory;
271  int m_recording_mode;
272  bool m_start_recording;
273  std::string m_text_record_mode;
274  bool m_directory_to_create;
275  bool m_recording_trigger;
276 };
277 
278 #endif
279 #endif
static void makeDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:482
void pop(vpImage< Type > &I, std::string &data)
Definition: vpImageQueue.h:129
bool getRecordingTrigger() const
Definition: vpImageQueue.h:109
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
void push(const vpImage< Type > &I, std::string *data)
Definition: vpImageQueue.h:160
int getRecordingMode() const
Definition: vpImageQueue.h:101
bool record(const vpImage< Type > &I, std::string *data=NULL, bool trigger_recording=false, bool disable_left_click=false)
Definition: vpImageQueue.h:191
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
void setMaxQueueSize(const size_t max_queue_size)
Definition: vpImageQueue.h:258
vpImageQueue(const std::string &seqname, int record_mode)
Definition: vpImageQueue.h:74
static std::string getParent(const std::string &pathname)
Definition: vpIoTools.cpp:1382
void cancel()
Definition: vpImageQueue.h:91
static const vpColor red
Definition: vpColor.h:217
static bool checkDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:332
std::string getSeqName() const
Definition: vpImageQueue.h:117
unsigned int getDownScalingFactor()
Definition: vpDisplay.h:235
Definition of the vpImage class member functions.
Definition: vpImage.h:126