Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpImageQueue.h
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 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 VP_IMAGE_QUEUE_H
35#define VP_IMAGE_QUEUE_H
36
37#include <visp3/core/vpConfig.h>
38
39#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) && defined(VISP_HAVE_THREADS)
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
51
52#ifndef DOXYGEN_SHOULD_SKIP_THIS
64template <class Type> class vpImageQueue
65{
66public:
67 struct vpCancelled_t
68 { };
69
77 vpImageQueue(const std::string &seqname, int record_mode)
78 : m_cancelled(false), m_cond(), m_queue_image(), m_queue_data(), m_maxQueueSize(1024 * 8), m_mutex(),
79 m_seqname(seqname), m_recording_mode(record_mode), m_start_recording(false), m_directory_to_create(false),
80 m_recording_trigger(false)
81 {
82 m_directory = vpIoTools::getParent(seqname);
83 if (!m_directory.empty()) {
84 if (!vpIoTools::checkDirectory(m_directory)) {
85 m_directory_to_create = true;
86 }
87 }
88 m_text_record_mode =
89 std::string("Record mode: ") + (m_recording_mode ? std::string("single") : std::string("continuous"));
90 }
91
95 void cancel()
96 {
97 std::lock_guard<std::mutex> lock(m_mutex);
98 std::cout << "Wait to finish saving images..." << std::endl;
99 m_cancelled = true;
100 m_cond.notify_all();
101 }
102
106 int getRecordingMode() const { return m_recording_mode; }
107
111 bool getRecordingTrigger() const { return m_recording_trigger; }
112
116 std::string getSeqName() const { return m_seqname; }
117
125 void pop(vpImage<Type> &I, std::string &data)
126 {
127 std::unique_lock<std::mutex> lock(m_mutex);
128
129 while (m_queue_image.empty()) {
130 if (m_cancelled) {
131 throw vpCancelled_t();
132 }
133
134 m_cond.wait(lock);
135
136 if (m_cancelled) {
137 throw vpCancelled_t();
138 }
139 }
140
141 I = m_queue_image.front();
142
143 m_queue_image.pop();
144
145 if (!m_queue_data.empty()) {
146 data = m_queue_data.front();
147 m_queue_data.pop();
148 }
149 }
150
157 void push(const vpImage<Type> &I, std::string *data)
158 {
159 std::lock_guard<std::mutex> lock(m_mutex);
160
161 m_queue_image.push(I);
162
163 if (data != nullptr) {
164 m_queue_data.push(*data);
165 }
166
167 // Pop extra data in the queue
168 while (m_queue_image.size() > m_maxQueueSize) {
169 m_queue_image.pop();
170 }
171
172 if (data != nullptr) {
173 while (m_queue_data.size() > m_maxQueueSize) {
174 m_queue_data.pop();
175 }
176 }
177
178 m_cond.notify_one();
179 }
180
190 bool record(const vpImage<Type> &I, std::string *data = nullptr, bool trigger_recording = false,
191 bool disable_left_click = false)
192 {
193 if (I.display) {
194 if (!m_seqname.empty()) {
195 if (!disable_left_click) {
196 if (!m_recording_mode) { // continuous
197 if (m_start_recording) {
199 10 * vpDisplay::getDownScalingFactor(I), "Left click: stop recording",
201 }
202 else {
204 10 * vpDisplay::getDownScalingFactor(I), "Left click: start recording",
206 }
207 }
208 else {
210 "Left click: record image", vpColor::red);
211 }
212 }
214 "Right click: quit", vpColor::red);
215 }
216 else {
218 "Click to quit", vpColor::red);
219 }
220
221 if (!m_seqname.empty()) {
223 m_text_record_mode, vpColor::red);
224 }
226 if (vpDisplay::getClick(I, button, false)) {
227 if (!m_seqname.empty()) { // Recording requested
228 if (button == vpMouseButton::button1 && !disable_left_click) { // enable/disable recording
229 m_start_recording = !m_start_recording;
230 }
231 else if (button == vpMouseButton::button3) { // quit
232 return true;
233 }
234 }
235 else { // any button to quit
236 return true;
237 }
238 }
239 }
240 else if (!m_seqname.empty()) {
241 m_start_recording = true;
242 }
243
244 if (trigger_recording) {
245 m_start_recording = true;
246 }
247
248 m_recording_trigger = m_start_recording;
249
250 if (m_start_recording) {
251
252 if (m_directory_to_create) {
253 std::cout << "Create directory \"" << m_directory << "\"" << std::endl;
254 vpIoTools::makeDirectory(m_directory);
255 m_directory_to_create = false;
256 }
257
258 push(I, data);
259
260 if (m_recording_mode == 1) { // single shot mode
261 m_start_recording = false;
262 }
263 }
264 return false;
265 }
266
271 void setMaxQueueSize(const size_t max_queue_size) { m_maxQueueSize = max_queue_size; }
272
273private:
274 bool m_cancelled;
275 std::condition_variable m_cond;
276 std::queue<vpImage<Type> > m_queue_image;
277 std::queue<std::string> m_queue_data;
278 size_t m_maxQueueSize;
279 std::mutex m_mutex;
280 std::string m_seqname;
281 std::string m_directory;
282 int m_recording_mode;
283 bool m_start_recording;
284 std::string m_text_record_mode;
285 bool m_directory_to_create;
286 bool m_recording_trigger;
287};
288
289#endif // DOXYGEN_SHOULD_SKIP_THIS
290END_VISP_NAMESPACE
291#endif
292#endif
static const vpColor red
Definition vpColor.h:198
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
unsigned int getDownScalingFactor()
Definition vpDisplay.h:218
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
vpDisplay * display
Definition vpImage.h:136
static bool checkDirectory(const std::string &dirname)
static void makeDirectory(const std::string &dirname)
static std::string getParent(const std::string &pathname)