Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
tutorial-grabber-opencv-threaded.cpp
1
3#include <iostream>
4
5#include <visp3/core/vpConfig.h>
6
7#if defined(VISP_HAVE_OPENCV) && defined(VISP_HAVE_THREADS) && \
8 (((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)) || ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)))
9
10#include <thread>
11#include <mutex>
12
13#if (VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI)
14#include <opencv2/highgui/highgui.hpp> // for cv::VideoCapture
15#elif (VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_VIDEOIO)
16#include <opencv2/videoio/videoio.hpp> // for cv::VideoCapture
17#endif
18
19#include <visp3/core/vpImageConvert.h>
20#include <visp3/core/vpTime.h>
21#include <visp3/gui/vpDisplayFactory.h>
22
23#ifdef ENABLE_VISP_NAMESPACE
24using namespace VISP_NAMESPACE_NAME;
25#endif
26
27// Possible capture states
28typedef enum { capture_waiting, capture_started, capture_stopped } t_CaptureState;
30
32void captureFunction(cv::VideoCapture &cap, std::mutex &mutex_capture, cv::Mat &frame, t_CaptureState &capture_state)
33{
34 if (!cap.isOpened()) { // check if we succeeded
35 std::cout << "Unable to start capture" << std::endl;
36 return;
37 }
38
39 cv::Mat frame_;
40 int i = 0;
41 while ((i++ < 100) && !cap.read(frame_)) {
42 }; // warm up camera by skipping unread frames
43
44 bool stop_capture_ = false;
45
47 while ((vpTime::measureTimeSecond() - start_time) < 30 && !stop_capture_) {
48 // Capture in progress
49 cap >> frame_; // get a new frame from camera
50
51 // Update shared data
52 {
53 std::lock_guard<std::mutex> lock(mutex_capture);
54 if (capture_state == capture_stopped)
55 stop_capture_ = true;
56 else
57 capture_state = capture_started;
58 frame = frame_;
59 }
60 }
61
62 {
63 std::lock_guard<std::mutex> lock(mutex_capture);
64 capture_state = capture_stopped;
65 }
66
67 std::cout << "End of capture thread" << std::endl;
68}
70
72void displayFunction(std::mutex &mutex_capture, cv::Mat &frame, t_CaptureState &capture_state)
73{
75
76 t_CaptureState capture_state_;
77 bool display_initialized_ = false;
78#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
79 std::shared_ptr<vpDisplay> display;
80#else
81 vpDisplay *display = nullptr;
82#endif
83
84 do {
85 mutex_capture.lock();
86 capture_state_ = capture_state;
87 mutex_capture.unlock();
88
89 // Check if a frame is available
90 if (capture_state_ == capture_started) {
91 // Get the frame and convert it to a ViSP image used by the display
92 // class
93 {
94 std::lock_guard<std::mutex> lock(mutex_capture);
95 vpImageConvert::convert(frame, I_);
96 }
97
98 // Check if we need to initialize the display with the first frame
99 if (!display_initialized_) {
100 // Initialize the display
101#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
103 display_initialized_ = true;
104#else
106 display_initialized_ = true;
107#endif
108 }
109
110 // Display the image
112
113 // Trigger end of acquisition with a mouse click
114 vpDisplay::displayText(I_, 10, 10, "Click to exit...", vpColor::red);
115 if (vpDisplay::getClick(I_, false)) {
116 std::lock_guard<std::mutex> lock(mutex_capture);
117 capture_state = capture_stopped;
118 }
119
120 // Update the display
122 }
123 else {
124 vpTime::wait(2); // Sleep 2ms
125 }
126 } while (capture_state_ != capture_stopped);
127
128#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
129 if (display != nullptr) {
130 delete display;
131 }
132#endif
133
134 std::cout << "End of display thread" << std::endl;
135}
137
139int main(int argc, const char *argv[])
140{
141 int opt_device = 0;
142
143 // Command line options
144 for (int i = 1; i < argc; i++) {
145 if (std::string(argv[i]) == "--camera-device" && i + 1 < argc) {
146 opt_device = atoi(argv[++i]);
147 }
148 else if (std::string(argv[i]) == "--help") {
149 std::cout << "Usage: " << argv[0] << " [--camera-device <camera device (default: 0)>] [--help]" << std::endl;
150 return EXIT_SUCCESS;
151 }
152 }
153
154 // Instantiate the capture
155 cv::VideoCapture cap;
156 cap.open(opt_device);
157
158 cv::Mat frame;
159 t_CaptureState capture_state = capture_waiting;
160 // Create a mutex for capture
161 std::mutex mutex_capture;
162 // Start the threads
163 std::thread thread_capture(&captureFunction, std::ref(cap), std::ref(mutex_capture), std::ref(frame), std::ref(capture_state));
164 std::thread thread_display(&displayFunction, std::ref(mutex_capture), std::ref(frame), std::ref(capture_state));
165
166 // Wait until thread ends up
167 thread_capture.join();
168 thread_display.join();
169
170 return EXIT_SUCCESS;
171}
173
174#else
175int main()
176{
177#if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x030000) && !defined(HAVE_OPENCV_HIGHGUI)
178 std::cout << "Install OpenCV highgui module, configure and build ViSP again to use this tutorial." << std::endl;
179#endif
180#if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x030000) && !defined(HAVE_OPENCV_VIDEOIO)
181 std::cout << "Install OpenCV videoio module, configure and build ViSP again to use this tutorial." << std::endl;
182#endif
183#if !defined(HAVE_OPENCV_HIGHGUI)
184 std::cout << "Install OpenCV highgui module, configure and build ViSP again to use this tutorial." << std::endl;
185#endif
186#if !defined(VISP_HAVE_THREADS) // UNIX
187 std::cout << "This tutorial cannot run without std::thread usage." << std::endl;
188 std::cout << "Multi-threading seems not supported on this platform" << std::endl;
189#endif
190 return EXIT_SUCCESS;
191}
192
193#endif
static const vpColor red
Definition vpColor.h:198
Class that defines generic functionalities for display.
Definition vpDisplay.h:171
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void flush(const vpImage< unsigned char > &I)
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Definition of the vpImage class member functions.
Definition vpImage.h:131
std::shared_ptr< vpDisplay > createDisplay()
Return a smart pointer vpDisplay specialization if a GUI library is available or nullptr otherwise.
vpDisplay * allocateDisplay()
Return a newly allocated vpDisplay specialization if a GUI library is available or nullptr otherwise.
VISP_EXPORT int wait(double t0, double t)
VISP_EXPORT double measureTimeSecond()