Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
tutorial-grabber-opencv-threaded.cpp
1
3#include <iostream>
4
5#include <visp3/core/vpImageConvert.h>
6#include <visp3/core/vpMutex.h>
7#include <visp3/core/vpThread.h>
8#include <visp3/core/vpTime.h>
9#include <visp3/gui/vpDisplayGDI.h>
10#include <visp3/gui/vpDisplayX.h>
11
12#if defined(HAVE_OPENCV_VIDEOIO) && (defined(VISP_HAVE_PTHREAD) || defined(_WIN32))
13
14#include <opencv2/highgui.hpp>
15#include <opencv2/videoio.hpp>
16
17// Shared vars
18typedef enum { capture_waiting, capture_started, capture_stopped } t_CaptureState;
19t_CaptureState s_capture_state = capture_waiting;
20cv::Mat s_frame;
21vpMutex s_mutex_capture;
23
25vpThread::Return captureFunction(vpThread::Args args)
26{
27 cv::VideoCapture cap = *((cv::VideoCapture *)args);
28
29 if (!cap.isOpened()) { // check if we succeeded
30 std::cout << "Unable to start capture" << std::endl;
31 return 0;
32 }
33
34 cv::Mat frame_;
35 int i = 0;
36 while ((i++ < 100) && !cap.read(frame_)) {
37 }; // warm up camera by skiping unread frames
38
39 bool stop_capture_ = false;
40
41 double start_time = vpTime::measureTimeSecond();
42 while ((vpTime::measureTimeSecond() - start_time) < 30 && !stop_capture_) {
43 // Capture in progress
44 cap >> frame_; // get a new frame from camera
45
46 // Update shared data
47 {
48 vpMutex::vpScopedLock lock(s_mutex_capture);
49 if (s_capture_state == capture_stopped)
50 stop_capture_ = true;
51 else
52 s_capture_state = capture_started;
53 s_frame = frame_;
54 }
55 }
56
57 {
58 vpMutex::vpScopedLock lock(s_mutex_capture);
59 s_capture_state = capture_stopped;
60 }
61
62 std::cout << "End of capture thread" << std::endl;
63 return 0;
64}
66
68vpThread::Return displayFunction(vpThread::Args args)
69{
70 (void)args; // Avoid warning: unused parameter args
72
73 t_CaptureState capture_state_;
74 bool display_initialized_ = false;
75#if defined(VISP_HAVE_X11)
76 vpDisplayX *d_ = NULL;
77#elif defined(VISP_HAVE_GDI)
78 vpDisplayGDI *d_ = NULL;
79#endif
80
81 do {
82 s_mutex_capture.lock();
83 capture_state_ = s_capture_state;
84 s_mutex_capture.unlock();
85
86 // Check if a frame is available
87 if (capture_state_ == capture_started) {
88 // Get the frame and convert it to a ViSP image used by the display
89 // class
90 {
91 vpMutex::vpScopedLock lock(s_mutex_capture);
92 vpImageConvert::convert(s_frame, I_);
93 }
94
95 // Check if we need to initialize the display with the first frame
96 if (!display_initialized_) {
97 // Initialize the display
98#if defined(VISP_HAVE_X11)
99 d_ = new vpDisplayX(I_);
100 display_initialized_ = true;
101#elif defined(VISP_HAVE_GDI)
102 d_ = new vpDisplayGDI(I_);
103 display_initialized_ = true;
104#endif
105 }
106
107 // Display the image
109
110 // Trigger end of acquisition with a mouse click
111 vpDisplay::displayText(I_, 10, 10, "Click to exit...", vpColor::red);
112 if (vpDisplay::getClick(I_, false)) {
113 vpMutex::vpScopedLock lock(s_mutex_capture);
114 s_capture_state = capture_stopped;
115 }
116
117 // Update the display
119 }
120 else {
121 vpTime::wait(2); // Sleep 2ms
122 }
123 } while (capture_state_ != capture_stopped);
124
125#if defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI)
126 delete d_;
127#endif
128
129 std::cout << "End of display thread" << std::endl;
130 return 0;
131}
133
135int main(int argc, const char *argv [])
136{
137 int opt_device = 0;
138
139 // Command line options
140 for (int i = 0; i < argc; i++) {
141 if (std::string(argv[i]) == "--camera_device")
142 opt_device = atoi(argv[i + 1]);
143 else if (std::string(argv[i]) == "--help") {
144 std::cout << "Usage: " << argv[0] << " [--camera_device <camera device (default: 0)>] [--help]" << std::endl;
145 return EXIT_SUCCESS;
146 }
147 }
148
149 // Instantiate the capture
150 cv::VideoCapture cap;
151 cap.open(opt_device);
152
153 // Start the threads
154 vpThread thread_capture((vpThread::Fn)captureFunction, (vpThread::Args)&cap);
155 vpThread thread_display((vpThread::Fn)displayFunction);
156
157 // Wait until thread ends up
158 thread_capture.join();
159 thread_display.join();
160
161 return EXIT_SUCCESS;
162}
164
165#else
166int main()
167{
168#ifndef VISP_HAVE_OPENCV
169 std::cout << "You should install OpenCV videoio module to make this example working..." << std::endl;
170#elif !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
171 std::cout << "You should enable pthread usage and rebuild ViSP..." << std::endl;
172#else
173 std::cout << "Multi-threading seems not supported on this platform" << std::endl;
174#endif
175 return EXIT_SUCCESS;
176}
177
178#endif
static const vpColor red
Definition vpColor.h:211
Display for windows using GDI (available on any windows 32 platform).
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition vpDisplayX.h:132
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:135
Class that allows protection by mutex.
Definition vpMutex.h:166
void unlock()
Definition vpMutex.h:106
void lock()
Definition vpMutex.h:90
void *(*) Fn(Args)
Definition vpThread.h:74
void * Args
Definition vpThread.h:72
void * Return
Definition vpThread.h:73
VISP_EXPORT int wait(double t0, double t)
VISP_EXPORT double measureTimeSecond()