Main MRPT website > C++ reference for MRPT 1.9.9
CImageGrabber_OpenCV.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "hwdrivers-precomp.h" // Precompiled headers
11 
13 
14 #include <mrpt/otherlibs/do_opencv_includes.h>
15 
16 #include <thread>
17 
18 #define M_CAPTURE (static_cast<CvCapture*>(m_capture.get()))
19 
20 using namespace std;
21 using namespace mrpt;
22 using namespace mrpt::hwdrivers;
23 
24 /*-------------------------------------------------------------
25  Constructor
26  -------------------------------------------------------------*/
27 CImageGrabber_OpenCV::CImageGrabber_OpenCV(
28  int cameraIndex, TCameraType cameraType, const TCaptureCVOptions& options)
29 {
31  m_bInitialized = false;
32 
33 #if MRPT_HAS_OPENCV
34  int cv_cap_indx = 0;
35  switch (cameraType)
36  {
38  cv_cap_indx = CV_CAP_ANY;
39  break;
40  case CAMERA_CV_DC1394:
41  cv_cap_indx = CV_CAP_DC1394;
42  break;
43  case CAMERA_CV_VFL:
44  cv_cap_indx = CV_CAP_V4L;
45  break;
46  case CAMERA_CV_VFW:
47  cv_cap_indx = CV_CAP_VFW;
48  break;
49  case CAMERA_CV_MIL:
50  cv_cap_indx = CV_CAP_MIL;
51  break;
52 #if MRPT_OPENCV_VERSION_NUM >= 0x111
53  case CAMERA_CV_DSHOW:
54  cv_cap_indx = CV_CAP_DSHOW;
55  break;
56 // *** HAVE YOU HAD A COMPILER ERROR NEAR THIS LINE?? : You need OpenCV >=1.1.1,
57 // (2.0 final release) or a SVN version ***
58 #endif
59  default:
60  THROW_EXCEPTION_FMT("Invalid camera type: %i", cameraType);
61  }
62 
63  cv_cap_indx += cameraIndex;
64 
65  m_capture = cvCaptureFromCAM(cv_cap_indx);
66 
67 // If we have OPENCV>=1.1.1, we can determine the type of the capturer
68 // if it was CAMERA_CV_AUTODETECT
69 #if MRPT_OPENCV_VERSION_NUM >= 0x111
70  if (cameraType == CAMERA_CV_AUTODETECT)
71  {
72  cv_cap_indx = cvGetCaptureDomain(M_CAPTURE);
73  // *** HAVE YOU HAD A COMPILER ERROR NEAR THIS LINE?? : You need OpenCV
74  // >=1.1.0, (2.0 final release) or a SVN version ***
75  switch (cv_cap_indx)
76  {
77  case CV_CAP_ANY:
78  cameraType = CAMERA_CV_AUTODETECT;
79  break;
80  case CV_CAP_DC1394:
81  cameraType = CAMERA_CV_DC1394;
82  break;
83  // case CV_CAP_V4L:
84  case CV_CAP_VFW:
85  cameraType = CAMERA_CV_VFW;
86  break;
87  case CV_CAP_MIL:
88  cameraType = CAMERA_CV_MIL;
89  break;
90  case CV_CAP_DSHOW:
91  cameraType = CAMERA_CV_DSHOW;
92  break;
93  default:
94  THROW_EXCEPTION_FMT("Invalid camera type: %i", cameraType);
95  }
96  }
97 #endif
98 
99  if (!m_capture.get())
100  {
101  cerr << format(
102  "[CImageGrabber_OpenCV] ERROR: Can't open camera '%i'!!\n",
103  cameraIndex);
104  return;
105  }
106 
107  // Set properties:
108  // Based on code from Orocos project. Thanks!
109  // ----------------------------------------
110  // Global settings
111  if (options.gain != 0)
112  {
113  if (cvSetCaptureProperty(M_CAPTURE, CV_CAP_PROP_GAIN, options.gain) < 1)
114  cerr << "[CImageGrabber_OpenCV] Warning: Could not set the "
115  "capturing gain property!"
116  << endl;
117  }
118 
119  // Settings only for firewire
120  if (cameraType == CAMERA_CV_DC1394)
121  {
122  if (options.frame_height != 0 && options.frame_width != 0)
123  {
124  // MODE_320x240_YUV422 ****
125  //
126  enum
127  {
128  MY_MODE_160x120_YUV444 = 64,
129  MY_MODE_320x240_YUV422, // ***
130  MY_MODE_640x480_YUV411,
131  MY_MODE_640x480_YUV422, // ***
132  MY_MODE_640x480_RGB, // ?
133  MY_MODE_640x480_MONO, // ***
134  MY_MODE_640x480_MONO16
135  };
136 
137  int cvMode1394 = -1;
138  if (options.frame_height == 320 && options.frame_width == 240)
139  cvMode1394 = MY_MODE_320x240_YUV422;
140  else if (
141  options.frame_height == 640 && options.frame_width == 480 &&
142  !options.ieee1394_grayscale)
143  cvMode1394 = MY_MODE_640x480_YUV422;
144  else if (
145  options.frame_height == 640 && options.frame_width == 480 &&
146  options.ieee1394_grayscale)
147  cvMode1394 = MY_MODE_640x480_MONO;
148 
149  if (cvMode1394 > 0)
150  {
151  if (cvSetCaptureProperty(
152  M_CAPTURE, CV_CAP_PROP_MODE, cvMode1394) < 1)
153  cerr << "[CImageGrabber_OpenCV] Warning: Could not set the "
154  "capturing mode "
155  << cvMode1394 << " property!" << endl;
156  }
157  else
158  cerr << "[CImageGrabber_OpenCV] Warning: Not valid combination "
159  "of width x height x color mode for OpenCV/IEEE1394 "
160  "interface"
161  << endl;
162  }
163 
164  // Not needed: Default seems to be = 1
165  // if(cvSetCaptureProperty(M_CAPTURE,CV_CAP_PROP_CONVERT_RGB,_capture_convert.value())<1)
166  // cerr << "[CImageGrabber_OpenCV] Warning: Could not set the RGB
167  // conversion property!" << endl;
168 
169  if (cvSetCaptureProperty(
170  M_CAPTURE, CV_CAP_PROP_FPS, options.ieee1394_fps) < 1)
171  cerr << "[CImageGrabber_OpenCV] Warning: Could not set the fps "
172  "property!"
173  << endl;
174  }
175 
176  // Settings only for V4L
177  if (cameraType == CAMERA_CV_AUTODETECT || cameraType == CAMERA_CV_VFL ||
178  cameraType == CAMERA_CV_VFW || cameraType == CAMERA_CV_DSHOW)
179  {
180  if (options.frame_width != 0 && options.frame_height != 0)
181  {
182  // First set width then height. The first command always returns a
183  // error!
184  cvSetCaptureProperty(
185  M_CAPTURE, CV_CAP_PROP_FRAME_WIDTH, options.frame_width);
186  if (cvSetCaptureProperty(
187  M_CAPTURE, CV_CAP_PROP_FRAME_HEIGHT, options.frame_height) <
188  1)
189  cerr << "[CImageGrabber_OpenCV] Warning: Could not set the "
190  "frame width & height property!"
191  << endl;
192  }
193  }
194 
195  // remember that we successfully initialized everything
196  m_bInitialized = true;
197 #else
198  THROW_EXCEPTION("The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
199 #endif
200  MRPT_END
201 }
202 
203 /*-------------------------------------------------------------
204  Constructor
205  -------------------------------------------------------------*/
206 CImageGrabber_OpenCV::CImageGrabber_OpenCV(const std::string& AVI_fileName)
207 {
208  MRPT_START
209  m_bInitialized = false;
210 
211 #if MRPT_HAS_OPENCV
212  m_bInitialized = false;
213 
214  m_capture = cvCaptureFromAVI(AVI_fileName.c_str());
215 
216  if (!m_capture.get())
217  {
218  printf(
219  "[CImageGrabber_OpenCV] Warning! Can't open AVI file '%s'!!\n",
220  AVI_fileName.c_str());
221  return;
222  }
223 
224  // remember that we successfully initialized everything
225  m_bInitialized = true;
226 #else
227  THROW_EXCEPTION("The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
228 #endif
229  MRPT_END
230 }
231 
232 /*-------------------------------------------------------------
233  Destructor
234  -------------------------------------------------------------*/
235 CImageGrabber_OpenCV::~CImageGrabber_OpenCV()
236 {
237 #if MRPT_HAS_OPENCV
238  if (m_bInitialized)
239  {
240  CvCapture* cap = M_CAPTURE;
241  cvReleaseCapture(&cap);
242  m_capture = nullptr;
243  }
244 #endif
245 }
246 
247 /*-------------------------------------------------------------
248  get the image
249  -------------------------------------------------------------*/
251  mrpt::obs::CObservationImage& out_observation)
252 {
253  MRPT_START
254 
255  if (!m_bInitialized) return false;
256 
257 #if MRPT_HAS_OPENCV
258 
259  // Capture the image:
260  if (!cvGrabFrame(M_CAPTURE)) return false;
261 
262  IplImage* capImg = nullptr;
263 
264  // JL: Sometimes there're errors in some frames: try not to return an error
265  // unless it seems
266  // there's no way:
267  for (int nTries = 0; nTries < 10; nTries++)
268  {
269  capImg = cvRetrieveFrame(M_CAPTURE);
270  if (capImg) break;
271  cerr << "[CImageGrabber_OpenCV] WARNING: Ignoring error #" << nTries + 1
272  << " retrieving frame..." << endl;
273  std::this_thread::sleep_for(1ms);
274  }
275 
276  if (!capImg) return false;
277 
278  // Fill the output class:
279  out_observation.image.setFromIplImageReadOnly(capImg);
280  out_observation.timestamp = mrpt::system::now();
281 
282  return true;
283 #else
284  THROW_EXCEPTION("The MRPT has been compiled with MRPT_HAS_OPENCV=0 !");
285 #endif
286  MRPT_END
287 }
Declares a class derived from "CObservation" that encapsules an image from a camera, whose relative pose to robot is also stored.
#define MRPT_START
Definition: exceptions.h:262
TCameraType
These capture types are like their OpenCV equivalents.
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:41
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:75
Contains classes for various device interfaces.
STL namespace.
GLenum cap
Definition: glext.h:7309
bool ieee1394_grayscale
(IEEE1394 cameras) Whether to grab grayscale images (Default=false).
mrpt::img::CImage image
The image captured by the camera, that is, the main piece of information of this observation.
int frame_width
(All cameras) Capture resolution (0: Leave the default)
double ieee1394_fps
(IEEE1394 cameras) Frame rate for the capture (0: Leave the default).
GLsizei const GLchar ** string
Definition: glext.h:4101
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp.
Definition: CObservation.h:60
OBSERVATION_T::Ptr getObservation(mrpt::obs::CSensoryFrame::Ptr &observations, mrpt::obs::CObservation::Ptr &observation, bool priority_to_sf=true)
Given an mrpt::obs::CSensoryFrame and a mrpt::obs::CObservation pointer if a OBSERVATION_T type obser...
Definition: obs_utils.h:36
#define MRPT_END
Definition: exceptions.h:266
Valid only with OpenCV >= 1.1.0.
double gain
(All cameras) Camera gain (0: Leave the default)
GLenum GLsizei GLenum format
Definition: glext.h:3531
#define M_CAPTURE
Options used when creating an OpenCV capture object Some options apply to IEEE1394 cameras only...
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
Definition: exceptions.h:43
void setFromIplImageReadOnly(void *iplImage)
Reads the image from a OpenCV IplImage object (WITHOUT making a copy) and from now on the image canno...
Definition: CImage.cpp:340



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ad3a9d8ae Tue May 1 23:10:22 2018 -0700 at lun oct 28 00:14:14 CET 2019