CameraStereoVideo.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the Universite de Sherbrooke nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
29 #include <rtabmap/utilite/UTimer.h>
31 #include <opencv2/imgproc/types_c.h>
32 #if CV_MAJOR_VERSION > 3
33 #include <opencv2/videoio/videoio_c.h>
34 #if CV_MAJOR_VERSION > 4
35 #include <opencv2/videoio/legacy/constants_c.h>
36 #endif
37 #endif
38 
39 namespace rtabmap
40 {
41 
43 {
44  return true;
45 }
46 
48  const std::string & path,
49  bool rectifyImages,
50  float imageRate,
51  const Transform & localTransform) :
52  Camera(imageRate, localTransform),
53  path_(path),
54  rectifyImages_(rectifyImages),
55  src_(CameraVideo::kVideoFile),
56  usbDevice_(0),
57  usbDevice2_(-1),
58  _width(0),
59  _height(0)
60 {
61 }
62 
64  const std::string & pathLeft,
65  const std::string & pathRight,
66  bool rectifyImages,
67  float imageRate,
68  const Transform & localTransform) :
69  Camera(imageRate, localTransform),
70  path_(pathLeft),
71  path2_(pathRight),
72  rectifyImages_(rectifyImages),
73  src_(CameraVideo::kVideoFile),
74  usbDevice_(0),
75  usbDevice2_(-1),
76  _width(0),
77  _height(0)
78 {
79 }
80 
82  int device,
83  bool rectifyImages,
84  float imageRate,
85  const Transform & localTransform) :
86  Camera(imageRate, localTransform),
87  rectifyImages_(rectifyImages),
88  src_(CameraVideo::kUsbDevice),
89  usbDevice_(device),
90  usbDevice2_(-1),
91  _width(0),
92  _height(0)
93 {
94 }
95 
97  int deviceLeft,
98  int deviceRight,
99  bool rectifyImages,
100  float imageRate,
101  const Transform & localTransform) :
102  Camera(imageRate, localTransform),
103  rectifyImages_(rectifyImages),
104  src_(CameraVideo::kUsbDevice),
105  usbDevice_(deviceLeft),
106  usbDevice2_(deviceRight),
107  _width(0),
108  _height(0)
109 {
110 }
111 
113 {
114  capture_.release();
115  capture2_.release();
116 }
117 
118 bool CameraStereoVideo::init(const std::string & calibrationFolder, const std::string & cameraName)
119 {
120  cameraName_ = cameraName;
121  if(capture_.isOpened())
122  {
123  capture_.release();
124  }
125  if(capture2_.isOpened())
126  {
127  capture2_.release();
128  }
129 
131  {
132  capture_.open(usbDevice_);
133  if(usbDevice2_ < 0)
134  {
135  ULOGGER_DEBUG("CameraStereoVideo: Usb device initialization on device %d", usbDevice_);
136  }
137  else
138  {
139  ULOGGER_DEBUG("CameraStereoVideo: Usb device initialization on devices %d and %d", usbDevice_, usbDevice2_);
140  capture2_.open(usbDevice2_);
141  }
142  }
143  else if (src_ == CameraVideo::kVideoFile)
144  {
145  capture_.open(path_.c_str());
146  if(path2_.empty())
147  {
148  ULOGGER_DEBUG("CameraStereoVideo: filename=\"%s\"", path_.c_str());
149  }
150  else
151  {
152  ULOGGER_DEBUG("CameraStereoVideo: filenames=\"%s\" and \"%s\"", path_.c_str(), path2_.c_str());
153  capture2_.open(path2_.c_str());
154  }
155  }
156  else
157  {
158  ULOGGER_ERROR("CameraStereoVideo: Unknown source...");
159  }
160 
161  if(!capture_.isOpened() || ((!path2_.empty() || usbDevice2_>=0) && !capture2_.isOpened()))
162  {
163  ULOGGER_ERROR("CameraStereoVideo: Failed to create a capture object!");
164  capture_.release();
165  capture2_.release();
166  return false;
167  }
168 
169  if (cameraName_.empty())
170  {
171  unsigned int guid = (unsigned int)capture_.get(CV_CAP_PROP_GUID);
172  if (guid != 0 && guid != 0xffffffff)
173  {
174  cameraName_ = uFormat("%08x", guid);
175  }
176  }
177 
178  // look for calibration files
179  if(!calibrationFolder.empty() && !cameraName_.empty())
180  {
181  if(!stereoModel_.load(calibrationFolder, cameraName_, false))
182  {
183  UWARN("Missing calibration files for camera \"%s\" in \"%s\" folder, you should calibrate the camera!",
184  cameraName_.c_str(), calibrationFolder.c_str());
185  }
186  else
187  {
188  UINFO("Stereo parameters: fx=%f cx=%f cy=%f baseline=%f",
189  stereoModel_.left().fx(),
190  stereoModel_.left().cx(),
191  stereoModel_.left().cy(),
193  }
194  }
195 
197 
199  {
201  {
203  {
204  UWARN("Desired resolution of %dx%d is set but calibration has "
205  "been loaded with resolution %dx%d, using calibration resolution.",
206  _width, _height,
208  }
209 
210  if(capture_.isOpened())
211  {
212  bool resolutionSet = false;
213  resolutionSet = capture_.set(CV_CAP_PROP_FRAME_WIDTH, stereoModel_.left().imageWidth()*(capture2_.isOpened()?1:2));
214  resolutionSet = resolutionSet && capture_.set(CV_CAP_PROP_FRAME_HEIGHT, stereoModel_.left().imageHeight());
215  if(capture2_.isOpened())
216  {
217  resolutionSet = resolutionSet && capture2_.set(CV_CAP_PROP_FRAME_WIDTH, stereoModel_.right().imageWidth());
218  resolutionSet = resolutionSet && capture2_.set(CV_CAP_PROP_FRAME_HEIGHT, stereoModel_.right().imageHeight());
219  }
220 
221  // Check if the resolution was set successfully
222  int actualWidth = int(capture_.get(CV_CAP_PROP_FRAME_WIDTH));
223  int actualHeight = int(capture_.get(CV_CAP_PROP_FRAME_HEIGHT));
224  if(!resolutionSet ||
225  actualWidth != stereoModel_.left().imageWidth()*(capture2_.isOpened()?1:2) ||
226  actualHeight != stereoModel_.left().imageHeight())
227  {
228  UERROR("Calibration resolution (%dx%d) cannot be set to camera driver, "
229  "actual resolution is %dx%d. You would have to re-calibrate with one "
230  "supported format by your camera. "
231  "Do \"v4l2-ctl --list-formats-ext\" to list all supported "
232  "formats by your camera. For side-by-side format, you should set listed width/2.",
234  actualWidth/(capture2_.isOpened()?1:2), actualHeight);
235  }
236  }
237  }
238  else if(_width > 0 && _height > 0)
239  {
240  if(capture_.isOpened())
241  {
242  bool resolutionSet = false;
243  resolutionSet = capture_.set(CV_CAP_PROP_FRAME_WIDTH, _width*(capture2_.isOpened()?1:2));
244  resolutionSet = resolutionSet && capture_.set(CV_CAP_PROP_FRAME_HEIGHT, _height);
245  if(capture2_.isOpened())
246  {
247  resolutionSet = resolutionSet && capture2_.set(CV_CAP_PROP_FRAME_WIDTH, _width);
248  resolutionSet = resolutionSet && capture2_.set(CV_CAP_PROP_FRAME_HEIGHT, _height);
249  }
250 
251  // Check if the resolution was set successfully
252  int actualWidth = int(capture_.get(CV_CAP_PROP_FRAME_WIDTH));
253  int actualHeight = int(capture_.get(CV_CAP_PROP_FRAME_HEIGHT));
254  if(!resolutionSet ||
255  actualWidth != _width*(capture2_.isOpened()?1:2) ||
256  actualHeight != _height)
257  {
258  UWARN("Desired resolution (%dx%d) cannot be set to camera driver, "
259  "actual resolution is %dx%d. "
260  "Do \"v4l2-ctl --list-formats-ext\" to list all supported "
261  "formats by your camera. For side-by-side format, you should set listed width/2.",
262  _width, _height,
263  actualWidth/(capture2_.isOpened()?1:2), actualHeight);
264  }
265  }
266  }
267 
268  // Set FPS
269  if (this->getFrameRate() > 0)
270  {
271  bool fpsSupported = false;
272  fpsSupported = capture_.set(CV_CAP_PROP_FPS, this->getFrameRate());
273  if (capture2_.isOpened())
274  {
275  fpsSupported = fpsSupported && capture2_.set(CV_CAP_PROP_FPS, this->getFrameRate());
276  }
277  if(fpsSupported)
278  {
279  // Check if the FPS was set successfully
280  double actualFPS = capture_.get(cv::CAP_PROP_FPS);
281 
282  if(fabs(actualFPS - this->getFrameRate()) < 0.01)
283  {
284  this->setFrameRate(0);
285  }
286  else
287  {
288  UWARN("Desired FPS (%f Hz) cannot be set to camera driver, "
289  "actual FPS is %f Hz. We will throttle to lowest FPS. "
290  "Do \"v4l2-ctl --list-formats-ext\" to list all supported "
291  "formats by your camera.",
292  this->getFrameRate(), actualFPS);
293  if(this->getFrameRate() > actualFPS)
294  {
295  this->setFrameRate(0);
296  }
297  }
298  }
299  }
300 
301  // Set FOURCC
302  if (!_fourcc.empty())
303  {
304  if(_fourcc.size() == 4)
305  {
306  std::string fourccUpperCase = uToUpperCase(_fourcc);
307  int fourcc = cv::VideoWriter::fourcc(fourccUpperCase.at(0), fourccUpperCase.at(1), fourccUpperCase.at(2), fourccUpperCase.at(3));
308  bool fourccSupported = false;
309  fourccSupported = capture_.set(CV_CAP_PROP_FOURCC, fourcc);
310  if (capture2_.isOpened())
311  {
312  fourccSupported = fourccSupported && capture2_.set(CV_CAP_PROP_FOURCC, fourcc);
313  }
314 
315  // Check if the FOURCC was set successfully
316  int actualFourcc = int(capture_.get(CV_CAP_PROP_FOURCC));
317 
318  if(!fourccSupported || actualFourcc != fourcc)
319  {
320  UWARN("Camera doesn't support provided FOURCC \"%s\". "
321  "Do \"v4l2-ctl --list-formats-ext\" to list all supported "
322  "formats by your camera.", fourccUpperCase.c_str());
323  }
324  }
325  else
326  {
327  UERROR("FOURCC parameter should be 4 characters, current value is \"%s\"", _fourcc.c_str());
328  }
329  }
330  }
331 
333  {
334  UERROR("Parameter \"rectifyImages\" is set, but no stereo model is loaded or valid.");
335  return false;
336  }
337  return true;
338 }
339 
341 {
343 }
344 
345 std::string CameraStereoVideo::getSerial() const
346 {
347  return cameraName_;
348 }
349 
351 {
353 
354  cv::Mat img;
355  if(capture_.isOpened() && ((path2_.empty() && usbDevice2_ < 0) || capture2_.isOpened()))
356  {
357  cv::Mat leftImage;
358  cv::Mat rightImage;
359  if(path2_.empty() && usbDevice2_ < 0)
360  {
361  if(!capture_.read(img))
362  {
363  return data;
364  }
365  // Side by side stream
366  leftImage = cv::Mat(img, cv::Rect( 0, 0, img.size().width/2, img.size().height ));
367  rightImage = cv::Mat(img, cv::Rect( img.size().width/2, 0, img.size().width/2, img.size().height ));
368  }
369  else if(!capture_.read(leftImage) || !capture2_.read(rightImage))
370  {
371  return data;
372  }
373  else if(leftImage.cols != rightImage.cols || leftImage.rows != rightImage.rows)
374  {
375  UERROR("Left and right streams don't have image of the same size: left=%dx%d right=%dx%d",
376  leftImage.cols, leftImage.rows, rightImage.cols, rightImage.rows);
377  return data;
378  }
379 
380  // Rectification
381  bool rightCvt = false;
382  if(rightImage.type() != CV_8UC1)
383  {
384  cv::Mat tmp;
385  cv::cvtColor(rightImage, tmp, CV_BGR2GRAY);
386  rightImage = tmp;
387  rightCvt = true;
388  }
389 
391  {
392  leftImage = stereoModel_.left().rectifyImage(leftImage);
393  rightImage = stereoModel_.right().rectifyImage(rightImage);
394  }
395  else
396  {
397  leftImage = leftImage.clone();
398  if(!rightCvt)
399  {
400  rightImage = rightImage.clone();
401  }
402  }
403 
404  if(stereoModel_.left().imageHeight() == 0 || stereoModel_.left().imageWidth() == 0)
405  {
406  stereoModel_.setImageSize(leftImage.size());
407  }
408 
409  data = SensorData(leftImage, rightImage, stereoModel_, this->getNextSeqID(), UTimer::now());
410  }
411  else
412  {
413  ULOGGER_WARN("The camera must be initialized before requesting an image.");
414  }
415 
416  return data;
417 }
418 
419 
420 } // namespace rtabmap
rtabmap::SensorData
Definition: SensorData.h:51
int
int
rtabmap::CameraModel::fx
double fx() const
Definition: CameraModel.h:102
rtabmap::CameraModel::cx
double cx() const
Definition: CameraModel.h:104
rtabmap::CameraStereoVideo::getSerial
virtual std::string getSerial() const
Definition: CameraStereoVideo.cpp:345
rtabmap::CameraModel::imageWidth
int imageWidth() const
Definition: CameraModel.h:120
UINFO
#define UINFO(...)
rtabmap::CameraStereoVideo::~CameraStereoVideo
virtual ~CameraStereoVideo()
Definition: CameraStereoVideo.cpp:112
UTimer::now
static double now()
Definition: UTimer.cpp:80
rtabmap::CameraStereoVideo::usbDevice_
int usbDevice_
Definition: CameraStereoVideo.h:86
rtabmap::CameraStereoVideo::rectifyImages_
bool rectifyImages_
Definition: CameraStereoVideo.h:82
rtabmap::CameraStereoVideo::stereoModel_
StereoCameraModel stereoModel_
Definition: CameraStereoVideo.h:83
rtabmap::StereoCameraModel::load
bool load(const std::string &directory, const std::string &cameraName, bool ignoreStereoTransform=true)
Definition: StereoCameraModel.cpp:223
rtabmap::CameraVideo::kVideoFile
@ kVideoFile
Definition: CameraVideo.h:40
rtabmap::CameraModel::cy
double cy() const
Definition: CameraModel.h:105
rtabmap::StereoCameraModel::setImageSize
void setImageSize(const cv::Size &size)
Definition: StereoCameraModel.h:95
rtabmap::CameraStereoVideo::cameraName_
std::string cameraName_
Definition: CameraStereoVideo.h:84
rtabmap_netvlad.img
img
Definition: rtabmap_netvlad.py:78
rtabmap::StereoCameraModel::baseline
double baseline() const
Definition: StereoCameraModel.h:104
rtabmap::SensorCapture::setFrameRate
void setFrameRate(float frameRate)
Definition: SensorCapture.h:65
rtabmap::SensorCapture::getLocalTransform
const Transform & getLocalTransform() const
Definition: SensorCapture.h:62
rtabmap::CameraStereoVideo::_fourcc
std::string _fourcc
Definition: CameraStereoVideo.h:90
rtabmap::CameraStereoVideo::available
static bool available()
Definition: CameraStereoVideo.cpp:42
UTimer.h
rtabmap::StereoCameraModel::setLocalTransform
void setLocalTransform(const Transform &transform)
Definition: StereoCameraModel.h:118
ULOGGER_DEBUG
#define ULOGGER_DEBUG(...)
Definition: ULogger.h:53
rtabmap::CameraVideo::kUsbDevice
@ kUsbDevice
Definition: CameraVideo.h:40
fabs
Real fabs(const Real &a)
rtabmap::CameraStereoVideo::path_
std::string path_
Definition: CameraStereoVideo.h:80
rtabmap::SensorCaptureInfo
Definition: SensorCaptureInfo.h:36
CameraStereoVideo.h
rtabmap::CameraStereoVideo::_width
int _width
Definition: CameraStereoVideo.h:88
rtabmap::StereoCameraModel::right
const CameraModel & right() const
Definition: StereoCameraModel.h:123
data
int data[]
UConversion.h
Some conversion functions.
rtabmap_superglue.device
string device
Definition: rtabmap_superglue.py:21
rtabmap::CameraModel::rectifyImage
cv::Mat rectifyImage(const cv::Mat &raw, int interpolation=cv::INTER_LINEAR) const
Definition: CameraModel.cpp:695
rtabmap::CameraStereoVideo::capture2_
cv::VideoCapture capture2_
Definition: CameraStereoVideo.h:79
rtabmap::CameraStereoVideo::capture_
cv::VideoCapture capture_
Definition: CameraStereoVideo.h:78
rtabmap::StereoCameraModel::left
const CameraModel & left() const
Definition: StereoCameraModel.h:122
rtabmap::StereoCameraModel::isValidForProjection
bool isValidForProjection() const
Definition: StereoCameraModel.h:85
rtabmap::Camera
Definition: Camera.h:43
rtabmap::CameraModel::isValidForRectification
bool isValidForRectification() const
Definition: CameraModel.h:89
path
path
UWARN
#define UWARN(...)
uFormat
std::string UTILITE_EXPORT uFormat(const char *fmt,...)
Definition: UConversion.cpp:365
rtabmap::StereoCameraModel::isValidForRectification
bool isValidForRectification() const
Definition: StereoCameraModel.h:86
rtabmap::Transform
Definition: Transform.h:41
rtabmap::CameraStereoVideo::captureImage
virtual SensorData captureImage(SensorCaptureInfo *info=0)
Definition: CameraStereoVideo.cpp:350
rtabmap::CameraStereoVideo::isCalibrated
virtual bool isCalibrated() const
Definition: CameraStereoVideo.cpp:340
ULOGGER_ERROR
#define ULOGGER_ERROR(...)
Definition: ULogger.h:56
uToUpperCase
std::string UTILITE_EXPORT uToUpperCase(const std::string &str)
Definition: UConversion.cpp:63
rtabmap::CameraModel::imageHeight
int imageHeight() const
Definition: CameraModel.h:121
rtabmap::CameraStereoVideo::src_
CameraVideo::Source src_
Definition: CameraStereoVideo.h:85
rtabmap::CameraStereoVideo::init
virtual bool init(const std::string &calibrationFolder=".", const std::string &cameraName="")
Definition: CameraStereoVideo.cpp:118
rtabmap::CameraStereoVideo::_height
int _height
Definition: CameraStereoVideo.h:89
rtabmap::CameraStereoVideo::path2_
std::string path2_
Definition: CameraStereoVideo.h:81
rtabmap::SensorCapture::getFrameRate
float getFrameRate() const
Definition: SensorCapture.h:61
rtabmap::CameraStereoVideo::usbDevice2_
int usbDevice2_
Definition: CameraStereoVideo.h:87
rtabmap
Definition: CameraARCore.cpp:35
UERROR
#define UERROR(...)
ULOGGER_WARN
#define ULOGGER_WARN(...)
Definition: ULogger.h:55
rtabmap::SensorCapture::getNextSeqID
int getNextSeqID()
Definition: SensorCapture.h:83
rtabmap::CameraStereoVideo::CameraStereoVideo
CameraStereoVideo(const std::string &pathSideBySide, bool rectifyImages=false, float imageRate=0.0f, const Transform &localTransform=Transform::getIdentity())
Definition: CameraStereoVideo.cpp:47
rtabmap::CameraVideo
Definition: CameraVideo.h:36


rtabmap
Author(s): Mathieu Labbe
autogenerated on Sun Dec 1 2024 03:42:42