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