Refactoring CameraRGBD class (now including OpenNI, OpenNI2, OpenNI from OpenCV and Freenect)

Added tool to test RGB-D camera: rtabmap-rgbd_camera
Fixed Freenect corrupted depth image (after some time)

git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@1366 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
matlabbe
2014-06-15 03:31:35 +00:00
parent 81b3b49f97
commit c18f1501d4
25 changed files with 1248 additions and 1579 deletions

View File

@@ -6,7 +6,7 @@
# Freenect_INCLUDE_DIRS - The Freenect include directory. # Freenect_INCLUDE_DIRS - The Freenect include directory.
# Freenect_LIBRARIES - The Freenect library to link against. # Freenect_LIBRARIES - The Freenect library to link against.
FIND_PATH(Freenect_INCLUDE_DIRS libfreenect.h PATH_SUFFIXES libfreenect) FIND_PATH(Freenect_INCLUDE_DIRS libfreenect-registration.h PATH_SUFFIXES libfreenect)
FIND_LIBRARY(Freenect_LIBRARY NAMES freenect) FIND_LIBRARY(Freenect_LIBRARY NAMES freenect)
FIND_LIBRARY(Freenect_sync_LIBRARY NAMES freenect_sync) FIND_LIBRARY(Freenect_sync_LIBRARY NAMES freenect_sync)

View File

@@ -31,12 +31,6 @@
class UDirectory; class UDirectory;
class UTimer; class UTimer;
namespace openni
{
class Device;
class VideoStream;
}
namespace rtabmap namespace rtabmap
{ {
@@ -48,20 +42,16 @@ class RTABMAP_EXP Camera
{ {
public: public:
virtual ~Camera(); virtual ~Camera();
cv::Mat takeImage(); // backward compatibility cv::Mat takeImage();
void takeImage(cv::Mat & rgb);
void takeImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant);
virtual bool init() = 0; virtual bool init() = 0;
//getters //getters
void getImageSize(unsigned int & width, unsigned int & height); void getImageSize(unsigned int & width, unsigned int & height);
float getImageRate() const {return _imageRate;} float getImageRate() const {return _imageRate;}
const Transform & getLocalTransform() const {return _localTransform;}
//setters //setters
void setImageRate(float imageRate) {_imageRate = imageRate;} void setImageRate(float imageRate) {_imageRate = imageRate;}
void setImageSize(unsigned int width, unsigned int height); void setImageSize(unsigned int width, unsigned int height);
void setLocalTransform(const Transform & localTransform) {_localTransform= localTransform;}
protected: protected:
/** /**
@@ -71,17 +61,14 @@ protected:
*/ */
Camera(float imageRate = 0, Camera(float imageRate = 0,
unsigned int imageWidth = 0, unsigned int imageWidth = 0,
unsigned int imageHeight = 0, unsigned int imageHeight = 0);
unsigned int framesDropped = 0);
virtual void captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant) = 0; virtual cv::Mat captureImage() = 0;
private: private:
float _imageRate; float _imageRate;
unsigned int _imageWidth; unsigned int _imageWidth;
unsigned int _imageHeight; unsigned int _imageHeight;
unsigned int _framesDropped;
Transform _localTransform;
UTimer * _frameRateTimer; UTimer * _frameRateTimer;
}; };
@@ -98,15 +85,14 @@ public:
bool refreshDir = false, bool refreshDir = false,
float imageRate = 0, float imageRate = 0,
unsigned int imageWidth = 0, unsigned int imageWidth = 0,
unsigned int imageHeight = 0, unsigned int imageHeight = 0);
unsigned int framesDropped = 0);
virtual ~CameraImages(); virtual ~CameraImages();
virtual bool init(); virtual bool init();
std::string getPath() const {return _path;} std::string getPath() const {return _path;}
protected: protected:
virtual void captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant); virtual cv::Mat captureImage();
private: private:
std::string _path; std::string _path;
@@ -135,13 +121,11 @@ public:
CameraVideo(int usbDevice = 0, CameraVideo(int usbDevice = 0,
float imageRate = 0, float imageRate = 0,
unsigned int imageWidth = 0, unsigned int imageWidth = 0,
unsigned int imageHeight = 0, unsigned int imageHeight = 0);
unsigned int framesDropped = 0);
CameraVideo(const std::string & filePath, CameraVideo(const std::string & filePath,
float imageRate = 0, float imageRate = 0,
unsigned int imageWidth = 0, unsigned int imageWidth = 0,
unsigned int imageHeight = 0, unsigned int imageHeight = 0);
unsigned int framesDropped = 0);
virtual ~CameraVideo(); virtual ~CameraVideo();
virtual bool init(); virtual bool init();
@@ -149,7 +133,7 @@ public:
const std::string & getFilePath() const {return _filePath;} const std::string & getFilePath() const {return _filePath;}
protected: protected:
virtual void captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant); virtual cv::Mat captureImage();
private: private:
// File type // File type
@@ -163,58 +147,4 @@ private:
}; };
/////////////////////////
// CameraRGBD
/////////////////////////
class RTABMAP_EXP CameraRGBD :
public Camera
{
public:
static bool available();
public:
CameraRGBD(float imageRate = 0,
bool asus = false);
virtual ~CameraRGBD();
virtual bool init();
protected:
virtual void captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant);
private:
bool _asus;
cv::VideoCapture _capture;
float _depthFocal;
};
/////////////////////////
// CameraOpenNI2
/////////////////////////
class RTABMAP_EXP CameraOpenNI2 :
public Camera
{
public:
static bool available();
public:
CameraOpenNI2(float imageRate = 0);
virtual ~CameraOpenNI2();
virtual bool init();
protected:
virtual void captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant);
private:
openni::Device * _device;
openni::VideoStream * _color;
openni::VideoStream * _depth;
float _depthFocal;
};
} // namespace rtabmap } // namespace rtabmap

View File

@@ -1,98 +0,0 @@
/*
* CameraFreenect.h
*
* Created on: 2014-06-02
* Author: Mathieu
*/
#ifndef CAMERAFREENECT_H_
#define CAMERAFREENECT_H_
#include <rtabmap/core/RtabmapExp.h>
#include <rtabmap/core/Transform.h>
#include <rtabmap/utilite/UEventsSender.h>
#include <rtabmap/utilite/UThread.h>
#include <opencv2/opencv.hpp>
#include <stdint.h>
class UTimer;
typedef struct _freenect_context freenect_context;
typedef struct _freenect_device freenect_device;
namespace rtabmap {
class RTABMAP_EXP FreenectDevice {
public:
FreenectDevice(freenect_context *ctx, int index);
virtual ~FreenectDevice();
void startVideo();
void stopVideo();
void startDepth();
void stopDepth();
bool init();
cv::Mat getRgb();
cv::Mat getDepth();
float getDepthFocal() const {return depthFocal_;}
// Do not call directly even in child
void VideoCallback(void *video, uint32_t timestamp);
// Do not call directly even in child
void DepthCallback(void *depth, uint32_t timestamp);
private:
static void freenect_depth_callback(freenect_device *dev, void *depth, uint32_t timestamp);
static void freenect_video_callback(freenect_device *dev, void *video, uint32_t timestamp);
//noncopyable
FreenectDevice( const FreenectDevice& );
const FreenectDevice& operator=( const FreenectDevice& );
private:
int index_;
freenect_context * ctx_;
freenect_device * device_;
cv::Mat depthMat_;
cv::Mat rgbMat_;
UMutex depthMutex_;
UMutex rgbMutex_;
bool depthReady_;
bool rgbReady_;
float depthFocal_;
};
class RTABMAP_EXP CameraFreenect : public UEventsSender, public UThread
{
public:
static bool available();
public:
// default local transform z in, x right, y down));
CameraFreenect(int deviceId= 0,
float rate=0,
const Transform & localTransform = Transform::getIdentity());
virtual ~CameraFreenect();
bool init();
void setFrameRate(float rate);
private:
virtual void mainLoopBegin();
virtual void mainLoop();
virtual void mainLoopEnd();
private:
int deviceId_;
float rate_;
UTimer * frameRateTimer_;
Transform localTransform_; // transform from camera_optical_link to base_link
int seq_;
freenect_context * ctx_;
FreenectDevice * freenectDevice_;
};
} /* namespace rtabmap */
#endif /* CAMERAFREENECT_H_ */

View File

@@ -1,63 +0,0 @@
/*
* CameraOpenni.h
*
* Created on: 2013-08-22
* Author: Mathieu
*/
#ifndef CAMERAOPENNI_H_
#define CAMERAOPENNI_H_
#include <rtabmap/core/RtabmapExp.h>
#include <pcl/io/openni_camera/openni_depth_image.h>
#include <pcl/io/openni_camera/openni_image.h>
#include <boost/signals2/connection.hpp>
#include <rtabmap/core/Transform.h>
#include <rtabmap/utilite/UEventsSender.h>
class UTimer;
namespace pcl
{
class Grabber;
}
namespace rtabmap {
class RTABMAP_EXP CameraOpenni : public UEventsSender
{
public:
// default local transform z in, x right, y down));
CameraOpenni(const std::string & deviceId="",
float rate=0,
const Transform & localTRansform = Transform::getIdentity());
virtual ~CameraOpenni();
void image_cb (
const boost::shared_ptr<openni_wrapper::Image>& rgb,
const boost::shared_ptr<openni_wrapper::DepthImage>& depth,
float constant);
bool init();
void start();
void pause();
void kill();
bool isRunning();
void setFrameRate(float rate);
private:
pcl::Grabber* interface_;
std::string deviceId_;
float rate_;
UTimer * frameRateTimer_;
Transform localTransform_; // transform from camera_optical_link to base_link
int seq_;
boost::signals2::connection connection_;
};
} /* namespace rtabmap */
#endif /* CAMERAOPENNI_H_ */

View File

@@ -0,0 +1,215 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
#include <opencv2/highgui/highgui.hpp>
#include "rtabmap/core/Image.h"
#include "rtabmap/utilite/UMutex.h"
#include "rtabmap/utilite/USemaphore.h"
#include <set>
#include <stack>
#include <list>
#include <vector>
#include <pcl/io/openni_camera/openni_depth_image.h>
#include <pcl/io/openni_camera/openni_image.h>
#include <boost/signals2/connection.hpp>
class UDirectory;
class UTimer;
namespace openni
{
class Device;
class VideoStream;
}
namespace pcl
{
class Grabber;
}
typedef struct _freenect_context freenect_context;
typedef struct _freenect_device freenect_device;
namespace rtabmap
{
/**
* Class CameraRGBD
*
*/
class RTABMAP_EXP CameraRGBD
{
public:
virtual ~CameraRGBD();
void takeImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant);
virtual bool init() = 0;
//getters
float getImageRate() const {return _imageRate;}
const Transform & getLocalTransform() const {return _localTransform;}
//setters
void setImageRate(float imageRate) {_imageRate = imageRate;}
void setLocalTransform(const Transform & localTransform) {_localTransform= localTransform;}
protected:
/**
* Constructor
*
* @param imageRate : image/second , 0 for fast as the camera can
*/
CameraRGBD(float imageRate = 0,
const Transform & localTransform = Transform::getIdentity());
virtual void captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant) = 0;
private:
float _imageRate;
Transform _localTransform;
UTimer * _frameRateTimer;
};
/////////////////////////
// CameraOpenNIPCL
/////////////////////////
class RTABMAP_EXP CameraOpenni :
public CameraRGBD
{
public:
static bool available() {return true;}
public:
// default local transform z in, x right, y down));
CameraOpenni(const std::string & deviceId="",
float imageRate = 0,
const Transform & localTransform = Transform::getIdentity());
virtual ~CameraOpenni();
void image_cb (
const boost::shared_ptr<openni_wrapper::Image>& rgb,
const boost::shared_ptr<openni_wrapper::DepthImage>& depth,
float constant);
bool init();
protected:
virtual void captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant);
private:
pcl::Grabber* interface_;
std::string deviceId_;
boost::signals2::connection connection_;
cv::Mat depth_;
cv::Mat rgb_;
float depthConstant_;
UMutex dataMutex_;
USemaphore dataReady_;
};
/////////////////////////
// CameraOpenNICV
/////////////////////////
class RTABMAP_EXP CameraOpenNICV :
public CameraRGBD
{
public:
static bool available();
public:
CameraOpenNICV(bool asus = false,
float imageRate = 0,
const Transform & localTransform = Transform::getIdentity());
virtual ~CameraOpenNICV();
virtual bool init();
protected:
virtual void captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant);
private:
bool _asus;
cv::VideoCapture _capture;
float _depthFocal;
};
/////////////////////////
// CameraOpenNI2
/////////////////////////
class RTABMAP_EXP CameraOpenNI2 :
public CameraRGBD
{
public:
static bool available();
public:
CameraOpenNI2(float imageRate = 0,
const Transform & localTransform = Transform::getIdentity());
virtual ~CameraOpenNI2();
virtual bool init();
protected:
virtual void captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant);
private:
openni::Device * _device;
openni::VideoStream * _color;
openni::VideoStream * _depth;
float _depthFocal;
};
/////////////////////////
// CameraFreenect
/////////////////////////
class FreenectDevice;
class RTABMAP_EXP CameraFreenect :
public CameraRGBD
{
public:
static bool available();
public:
// default local transform z in, x right, y down));
CameraFreenect(int deviceId= 0,
float imageRate=0.0f,
const Transform & localTransform = Transform::getIdentity());
virtual ~CameraFreenect();
bool init();
protected:
virtual void captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant);
private:
int deviceId_;
freenect_context * ctx_;
FreenectDevice * freenectDevice_;
};
} // namespace rtabmap

View File

@@ -21,29 +21,27 @@
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines #include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
#include <rtabmap/utilite/UThreadNode.h> #include <rtabmap/utilite/UThread.h>
#include <rtabmap/utilite/UEventsHandler.h> #include <rtabmap/utilite/UEventsSender.h>
#include "rtabmap/core/Parameters.h"
#include <stack>
namespace rtabmap namespace rtabmap
{ {
class Camera; class Camera;
class CameraRGBD;
/** /**
* Class CameraThread * Class CameraThread
* *
*/ */
class RTABMAP_EXP CameraThread : class RTABMAP_EXP CameraThread :
public UThreadNode, public UThread,
public UEventsSender public UEventsSender
{ {
public: public:
// ownership transferred // ownership transferred
CameraThread(Camera * camera, bool autoRestart = false); CameraThread(Camera * camera);
CameraThread(CameraRGBD * camera);
virtual ~CameraThread(); virtual ~CameraThread();
bool init(); // call camera->init() bool init(); // call camera->init()
@@ -51,15 +49,14 @@ public:
//getters //getters
bool isPaused() const {return !this->isRunning();} bool isPaused() const {return !this->isRunning();}
bool isCapturing() const {return this->isRunning();} bool isCapturing() const {return this->isRunning();}
void setAutoRestart(bool autoRestart) {_autoRestart = autoRestart;} void setImageRate(float imageRate);
Camera * getCamera() {return _camera;}
private: private:
virtual void mainLoop(); virtual void mainLoop();
private: private:
Camera * _camera; Camera * _camera;
bool _autoRestart; CameraRGBD * _cameraRGBD;
int _seq; int _seq;
}; };

View File

@@ -13,8 +13,7 @@ SET(SRC_FILES
Camera.cpp Camera.cpp
CameraThread.cpp CameraThread.cpp
CameraOpenni.cpp CameraRGBD.cpp
CameraFreenect.cpp
EpipolarGeometry.cpp EpipolarGeometry.cpp
VisualWord.cpp VisualWord.cpp

View File

@@ -33,23 +33,15 @@
#include <iostream> #include <iostream>
#include <cmath> #include <cmath>
#ifdef WITH_OPENNI2
#endif
#include <OpenNI.h>
namespace rtabmap namespace rtabmap
{ {
Camera::Camera(float imageRate, Camera::Camera(float imageRate,
unsigned int imageWidth, unsigned int imageWidth,
unsigned int imageHeight, unsigned int imageHeight) :
unsigned int framesDropped) :
_imageRate(imageRate), _imageRate(imageRate),
_imageWidth(imageWidth), _imageWidth(imageWidth),
_imageHeight(imageHeight), _imageHeight(imageHeight),
_framesDropped(framesDropped),
_localTransform(Transform::getIdentity()),
_frameRateTimer(new UTimer()) _frameRateTimer(new UTimer())
{ {
} }
@@ -76,21 +68,7 @@ void Camera::getImageSize(unsigned int & width, unsigned int & height)
cv::Mat Camera::takeImage() cv::Mat Camera::takeImage()
{ {
cv::Mat rgb, depth; cv::Mat img;
float depthConstant = 0.0f;
takeImage(rgb, depth, depthConstant);
return rgb;
}
void Camera::takeImage(cv::Mat & rgb)
{
cv::Mat depth;
float depthConstant = 0.0f;
takeImage(rgb, depth, depthConstant);
}
void Camera::takeImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant)
{
float imageRate = _imageRate==0.0f?33.0f:_imageRate; // limit to 33Hz if infinity float imageRate = _imageRate==0.0f?33.0f:_imageRate; // limit to 33Hz if infinity
if(imageRate>0) if(imageRate>0)
{ {
@@ -112,33 +90,9 @@ void Camera::takeImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant)
} }
UTimer timer; UTimer timer;
this->captureImage(rgb, depth, depthConstant); img = this->captureImage();
UDEBUG("Time capturing image = %fs", timer.ticks()); UDEBUG("Time capturing image = %fs", timer.ticks());
return img;
if(!rgb.empty())
{
UASSERT(rgb.depth() == CV_8U);
if(_framesDropped)
{
unsigned int count = 0;
while(count++ < _framesDropped)
{
cv::Mat tmp,tmp2;
float tmpf;
this->captureImage(tmp, tmp2, tmpf);
if(!tmp.empty())
{
UDEBUG("frame dropped (%d/%d)", (int)count, (int)_framesDropped);
}
else
{
break;
}
}
UDEBUG("Frames dropped time = %fs", timer.ticks());
}
}
} }
///////////////////////// /////////////////////////
@@ -149,9 +103,8 @@ CameraImages::CameraImages(const std::string & path,
bool refreshDir, bool refreshDir,
float imageRate, float imageRate,
unsigned int imageWidth, unsigned int imageWidth,
unsigned int imageHeight, unsigned int imageHeight) :
unsigned int framesDropped) : Camera(imageRate, imageWidth, imageHeight),
Camera(imageRate, imageWidth, imageHeight, framesDropped),
_path(path), _path(path),
_startAt(startAt), _startAt(startAt),
_refreshDir(refreshDir), _refreshDir(refreshDir),
@@ -196,8 +149,9 @@ bool CameraImages::init()
return _dir->isValid(); return _dir->isValid();
} }
void CameraImages::captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant) cv::Mat CameraImages::captureImage()
{ {
cv::Mat img;
UDEBUG(""); UDEBUG("");
if(_dir->isValid()) if(_dir->isValid())
{ {
@@ -214,7 +168,7 @@ void CameraImages::captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthCon
{ {
_lastFileName = *fileNames.rbegin(); _lastFileName = *fileNames.rbegin();
std::string fullPath = _path + _lastFileName; std::string fullPath = _path + _lastFileName;
rgb = cv::imread(fullPath.c_str()); img = cv::imread(fullPath.c_str());
} }
} }
} }
@@ -234,19 +188,20 @@ void CameraImages::captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthCon
{ {
ULOGGER_DEBUG("Loading image : %s", fullPath.c_str()); ULOGGER_DEBUG("Loading image : %s", fullPath.c_str());
#if CV_MAJOR_VERSION >=2 and CV_MINOR_VERSION >=4 #if CV_MAJOR_VERSION >=2 and CV_MINOR_VERSION >=4
rgb = cv::imread(fullPath.c_str(), cv::IMREAD_UNCHANGED); img = cv::imread(fullPath.c_str(), cv::IMREAD_UNCHANGED);
#else #else
rgb = cv::imread(fullPath.c_str(), -1); img = cv::imread(fullPath.c_str(), -1);
#endif #endif
UDEBUG("width=%d, height=%d, channels=%d, elementSize=%d, total=%d", rgb.cols, rgb.rows, rgb.channels(), rgb.elemSize(), rgb.total()); UDEBUG("width=%d, height=%d, channels=%d, elementSize=%d, total=%d",
img.cols, img.rows, img.channels(), img.elemSize(), img.total());
// FIXME : it seems that some png are incorrectly loaded with opencv c++ interface, where c interface works... // FIXME : it seems that some png are incorrectly loaded with opencv c++ interface, where c interface works...
if(rgb.depth() != CV_8U) if(img.depth() != CV_8U)
{ {
// The depth should be 8U // The depth should be 8U
UWARN("Cannot read the image correctly, falling back to old OpenCV C interface..."); UWARN("Cannot read the image correctly, falling back to old OpenCV C interface...");
IplImage * i = cvLoadImage(fullPath.c_str()); IplImage * i = cvLoadImage(fullPath.c_str());
rgb = cv::Mat(i, true); img = cv::Mat(i, true);
cvReleaseImage(&i); cvReleaseImage(&i);
} }
} }
@@ -262,16 +217,17 @@ void CameraImages::captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthCon
unsigned int h; unsigned int h;
this->getImageSize(w, h); this->getImageSize(w, h);
if(!rgb.empty() && if(!img.empty() &&
w && w &&
h && h &&
w != (unsigned int)rgb.cols && w != (unsigned int)img.cols &&
h != (unsigned int)rgb.rows) h != (unsigned int)img.rows)
{ {
cv::Mat resampled; cv::Mat resampled;
cv::resize(rgb, resampled, cv::Size(w, h)); cv::resize(img, resampled, cv::Size(w, h));
rgb = resampled; img = resampled;
} }
return img;
} }
@@ -282,9 +238,8 @@ void CameraImages::captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthCon
CameraVideo::CameraVideo(int usbDevice, CameraVideo::CameraVideo(int usbDevice,
float imageRate, float imageRate,
unsigned int imageWidth, unsigned int imageWidth,
unsigned int imageHeight, unsigned int imageHeight) :
unsigned int framesDropped) : Camera(imageRate, imageWidth, imageHeight),
Camera(imageRate, imageWidth, imageHeight, framesDropped),
_src(kUsbDevice), _src(kUsbDevice),
_usbDevice(usbDevice) _usbDevice(usbDevice)
{ {
@@ -294,9 +249,8 @@ CameraVideo::CameraVideo(int usbDevice,
CameraVideo::CameraVideo(const std::string & filePath, CameraVideo::CameraVideo(const std::string & filePath,
float imageRate, float imageRate,
unsigned int imageWidth, unsigned int imageWidth,
unsigned int imageHeight, unsigned int imageHeight) :
unsigned int framesDropped) : Camera(imageRate, imageWidth, imageHeight),
Camera(imageRate, imageWidth, imageHeight, framesDropped),
_filePath(filePath), _filePath(filePath),
_src(kVideoFile), _src(kVideoFile),
_usbDevice(0) _usbDevice(0)
@@ -348,30 +302,31 @@ bool CameraVideo::init()
return true; return true;
} }
void CameraVideo::captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant) cv::Mat CameraVideo::captureImage()
{ {
cv::Mat img;
if(_capture.isOpened()) if(_capture.isOpened())
{ {
if(_capture.read(rgb)) if(_capture.read(img))
{ {
unsigned int w; unsigned int w;
unsigned int h; unsigned int h;
this->getImageSize(w, h); this->getImageSize(w, h);
if(!rgb.empty() && if(!img.empty() &&
w && w &&
h && h &&
w != (unsigned int)rgb.cols && w != (unsigned int)img.cols &&
h != (unsigned int)rgb.rows) h != (unsigned int)img.rows)
{ {
cv::Mat resampled; cv::Mat resampled;
cv::resize(rgb, resampled, cv::Size(w, h)); cv::resize(img, resampled, cv::Size(w, h));
rgb = resampled; img = resampled;
} }
else else
{ {
// clone required // clone required
rgb = rgb.clone(); img = img.clone();
} }
} }
else if(_usbDevice) else if(_usbDevice)
@@ -383,297 +338,7 @@ void CameraVideo::captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthCons
{ {
ULOGGER_WARN("The camera must be initialized before requesting an image."); ULOGGER_WARN("The camera must be initialized before requesting an image.");
} }
} return img;
/////////////////////////
// CameraRGBD
/////////////////////////
bool CameraRGBD::available()
{
return cv::getBuildInformation().find("OpenNI: YES") != std::string::npos;
}
CameraRGBD::CameraRGBD(float imageRate, bool asus) :
Camera(imageRate),
_asus(asus),
_depthFocal(0.0f)
{
}
CameraRGBD::~CameraRGBD()
{
_capture.release();
}
bool CameraRGBD::init()
{
if(_capture.isOpened())
{
_capture.release();
}
ULOGGER_DEBUG("CameraRGBD::init()");
_capture.open( _asus?CV_CAP_OPENNI_ASUS:CV_CAP_OPENNI );
if(_capture.isOpened())
{
_capture.set( CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CV_CAP_OPENNI_VGA_30HZ );
_depthFocal = _capture.get( CV_CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH );
// Print some avalible device settings.
UINFO("Depth generator output mode:");
UINFO("FRAME_WIDTH %f", _capture.get( CV_CAP_PROP_FRAME_WIDTH ));
UINFO("FRAME_HEIGHT %f", _capture.get( CV_CAP_PROP_FRAME_HEIGHT ));
UINFO("FRAME_MAX_DEPTH %f mm", _capture.get( CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH ));
UINFO("BASELINE %f mm", _capture.get( CV_CAP_PROP_OPENNI_BASELINE ));
UINFO("FPS %f", _capture.get( CV_CAP_PROP_FPS ));
UINFO("Focal %f", _capture.get( CV_CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH ));
UINFO("REGISTRATION %f", _capture.get( CV_CAP_PROP_OPENNI_REGISTRATION ));
if(_capture.get( CV_CAP_PROP_OPENNI_REGISTRATION ) == 0.0)
{
UERROR("Depth registration is not activated on this device!");
}
if( _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR_PRESENT ) )
{
UINFO("Image generator output mode:");
UINFO("FRAME_WIDTH %f", _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FRAME_WIDTH ));
UINFO("FRAME_HEIGHT %f", _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FRAME_HEIGHT ));
UINFO("FPS %f", _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FPS ));
}
else
{
UERROR("CameraRGBD: Device doesn't contain image generator.");
_capture.release();
return false;
}
}
else
{
ULOGGER_ERROR("CameraRGBD: Failed to create a capture object!");
_capture.release();
return false;
}
return true;
}
void CameraRGBD::captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant)
{
if(_capture.isOpened())
{
_capture.grab();
_capture.retrieve( depth, CV_CAP_OPENNI_DEPTH_MAP );
_capture.retrieve( rgb, CV_CAP_OPENNI_BGR_IMAGE );
depth = depth.clone();
rgb = rgb.clone();
UASSERT(_depthFocal > 0.0f);
depthConstant = 1.0f/_depthFocal;
}
else
{
ULOGGER_WARN("The camera must be initialized before requesting an image.");
}
}
/////////////////////////
// CameraOpenNI2
/////////////////////////
bool CameraOpenNI2::available()
{
#ifdef WITH_OPENNI2
return true;
#else
return false;
#endif
}
CameraOpenNI2::CameraOpenNI2(float imageRate) :
Camera(imageRate),
_device(new openni::Device()),
_color(new openni::VideoStream()),
_depth(new openni::VideoStream()),
_depthFocal(0.0f)
{
}
CameraOpenNI2::~CameraOpenNI2()
{
_color->stop();
_color->destroy();
_depth->stop();
_depth->destroy();
_device->close();
openni::OpenNI::shutdown();
delete _device;
delete _color;
delete _depth;
}
bool CameraOpenNI2::init()
{
openni::OpenNI::initialize();
if(_device->open(openni::ANY_DEVICE) != openni::STATUS_OK)
{
UERROR("CameraOpenNI2: Cannot open device.");
_device->close();
openni::OpenNI::shutdown();
return false;
}
if(!_device->isImageRegistrationModeSupported(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR))
{
UERROR("CameraOpenNI2: Device doesn't support depth/color registration.");
_device->close();
openni::OpenNI::shutdown();
return false;
}
if(_device->getSensorInfo(openni::SENSOR_DEPTH) == NULL ||
_device->getSensorInfo(openni::SENSOR_COLOR) == NULL)
{
UERROR("CameraOpenNI2: Cannot get sensor info for depth and color.");
_device->close();
openni::OpenNI::shutdown();
return false;
}
if(_depth->create(*_device, openni::SENSOR_DEPTH) != openni::STATUS_OK)
{
UERROR("CameraOpenNI2: Cannot create depth stream.");
_device->close();
openni::OpenNI::shutdown();
return false;
}
if(_color->create(*_device, openni::SENSOR_COLOR) != openni::STATUS_OK)
{
UERROR("CameraOpenNI2: Cannot create color stream.");
_depth->destroy();
_device->close();
openni::OpenNI::shutdown();
return false;
}
if(_device->setImageRegistrationMode(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR ) != openni::STATUS_OK)
{
UERROR("CameraOpenNI2: Failed to set depth/color registration.");
}
_depth->setMirroringEnabled(false);
_color->setMirroringEnabled(false);
const openni::Array<openni::VideoMode>& depthVideoModes = _depth->getSensorInfo().getSupportedVideoModes();
for(int i=0; i<depthVideoModes.getSize(); ++i)
{
UINFO("CameraOpenNI2: Depth video mode %d: fps=%d, pixel=%d, w=%d, h=%d",
i,
depthVideoModes[i].getFps(),
depthVideoModes[i].getPixelFormat(),
depthVideoModes[i].getResolutionX(),
depthVideoModes[i].getResolutionY());
}
const openni::Array<openni::VideoMode>& colorVideoModes = _color->getSensorInfo().getSupportedVideoModes();
for(int i=0; i<colorVideoModes.getSize(); ++i)
{
UINFO("CameraOpenNI2: Color video mode %d: fps=%d, pixel=%d, w=%d, h=%d",
i,
colorVideoModes[i].getFps(),
colorVideoModes[i].getPixelFormat(),
colorVideoModes[i].getResolutionX(),
colorVideoModes[i].getResolutionY());
}
openni::VideoMode mMode;
mMode.setFps(30);
mMode.setResolution(640,480);
mMode.setPixelFormat(openni::PIXEL_FORMAT_DEPTH_1_MM);
_depth->setVideoMode(mMode);
openni::VideoMode mModeColor;
mModeColor.setFps(30);
mModeColor.setResolution(640,480);
mModeColor.setPixelFormat(openni::PIXEL_FORMAT_RGB888);
_color->setVideoMode(mModeColor);
UINFO("CameraOpenNI2: Using depth video mode: fps=%d, pixel=%d, w=%d, h=%d, H-FOV=%f rad, V-FOV=%f rad",
_depth->getVideoMode().getFps(),
_depth->getVideoMode().getPixelFormat(),
_depth->getVideoMode().getResolutionX(),
_depth->getVideoMode().getResolutionY(),
_depth->getHorizontalFieldOfView(),
_depth->getVerticalFieldOfView());
bool registered = true;
if(registered)
{
_depthFocal = float(_color->getVideoMode().getResolutionX()/2) / std::tan(_color->getHorizontalFieldOfView()/2.0f);
}
else
{
_depthFocal = float(_depth->getVideoMode().getResolutionX()/2) / std::tan(_depth->getHorizontalFieldOfView()/2.0f);
}
UINFO("depth focal = %f", _depthFocal);
UINFO("CameraOpenNI2: Using color video mode: fps=%d, pixel=%d, w=%d, h=%d, H-FOV=%f rad, V-FOV=%f rad",
_color->getVideoMode().getFps(),
_color->getVideoMode().getPixelFormat(),
_color->getVideoMode().getResolutionX(),
_color->getVideoMode().getResolutionY(),
_color->getHorizontalFieldOfView(),
_color->getVerticalFieldOfView());
if(_depth->start() != openni::STATUS_OK ||
_color->start() != openni::STATUS_OK)
{
UERROR("CameraOpenNI2: Cannot start depth and/or color streams.");
_depth->stop();
_color->stop();
_depth->destroy();
_color->destroy();
_device->close();
openni::OpenNI::shutdown();
return false;
}
uSleep(1000); // just to make sure the sensor is correctly initialized
return true;
}
void CameraOpenNI2::captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant)
{
if(_device->isValid() &&
_depth->isValid() &&
_color->isValid() &&
_device->getSensorInfo(openni::SENSOR_DEPTH) != NULL &&
_device->getSensorInfo(openni::SENSOR_COLOR) != NULL)
{
openni::VideoFrameRef depthFrame, colorFrame;
_depth->readFrame(&depthFrame);
_color->readFrame(&colorFrame);
if(depthFrame.isValid() && colorFrame.isValid())
{
int h=depthFrame.getHeight();
int w=depthFrame.getWidth();
depth = cv::Mat(h, w, CV_16U, (void*)depthFrame.getData()).clone();
h=colorFrame.getHeight();
w=colorFrame.getWidth();
cv::Mat tmp(h, w, CV_8UC3, (void *)colorFrame.getData());
cv::cvtColor(tmp, rgb, CV_RGB2BGR);
}
UASSERT(_depthFocal != 0.0f);
depthConstant = 1.0f/_depthFocal;
}
else
{
ULOGGER_WARN("The camera must be initialized before requesting an image.");
}
} }
} // namespace rtabmap } // namespace rtabmap

View File

@@ -1,316 +0,0 @@
/*
* CameraFreenect.cpp
*
* Created on: 2014-06-02
* Author: Mathieu
*/
#include "rtabmap/core/CameraFreenect.h"
#include "rtabmap/core/CameraEvent.h"
#include "rtabmap/utilite/ULogger.h"
#include <rtabmap/utilite/UTimer.h>
#include <rtabmap/utilite/UConversion.h>
#include <rtabmap/utilite/UEventsManager.h>
#include <opencv2/imgproc/imgproc.hpp>
#ifdef WITH_FREENECT
#include <libfreenect.h>
#include <libfreenect-registration.h>
#endif
namespace rtabmap {
//
// FreenectDevice
//
FreenectDevice::FreenectDevice(freenect_context * ctx, int index) :
index_(index),
ctx_(ctx),
device_(0),
depthMat_(cv::Size(640,480),CV_16UC1),
rgbMat_(cv::Size(640,480), CV_8UC3, cv::Scalar(0)),
depthReady_(false),
rgbReady_(false),
depthFocal_(0.0f)
{
UASSERT(ctx_ != 0);
}
#ifdef WITH_FREENECT
FreenectDevice::~FreenectDevice() {
if(device_ && freenect_close_device(device_) < 0){} //FN_WARNING("Device did not shutdown in a clean fashion");
}
void FreenectDevice::startVideo() {
if(device_ && freenect_start_video(device_) < 0) UERROR("Cannot start RGB callback");
}
void FreenectDevice::stopVideo() {
if(device_ && freenect_stop_video(device_) < 0) UERROR("Cannot stop RGB callback");
}
void FreenectDevice::startDepth() {
if(device_ && freenect_start_depth(device_) < 0) UERROR("Cannot start depth callback");
}
void FreenectDevice::stopDepth() {
if(device_ && freenect_stop_depth(device_) < 0) UERROR("Cannot stop depth callback");
}
bool FreenectDevice::init()
{
if(freenect_open_device(ctx_, &device_, index_) < 0)
{
UERROR("FreenectDevice: Cannot open Kinect");
return false;
}
freenect_set_user(device_, this);
freenect_set_video_mode(device_, freenect_find_video_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_VIDEO_RGB));
freenect_set_depth_mode(device_, freenect_find_depth_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_DEPTH_REGISTERED));
freenect_set_depth_callback(device_, freenect_depth_callback);
freenect_set_video_callback(device_, freenect_video_callback);
bool registered = true;
float rgb_focal_length_sxga = 1050.0f;
float width_sxga = 1280.0f;
float width = freenect_get_current_depth_mode(device_).width;
float scale = width / width_sxga;
if(registered)
{
depthFocal_ = rgb_focal_length_sxga * scale;
}
else
{
freenect_registration reg = freenect_copy_registration(device_);
float depth_focal_length_sxga = reg.zero_plane_info.reference_distance / reg.zero_plane_info.reference_pixel_size;
freenect_destroy_registration(&reg);
depthFocal_ = depth_focal_length_sxga * scale;
}
UINFO("FreenectDevice: Depth focal = %f", depthFocal_);
return true;
}
void FreenectDevice::freenect_depth_callback(freenect_device *dev, void *depth, uint32_t timestamp) {
FreenectDevice* device = static_cast<FreenectDevice*>(freenect_get_user(dev));
device->DepthCallback(depth, timestamp);
}
void FreenectDevice::freenect_video_callback(freenect_device *dev, void *video, uint32_t timestamp) {
FreenectDevice* device = static_cast<FreenectDevice*>(freenect_get_user(dev));
device->VideoCallback(video, timestamp);
}
#else
FreenectDevice::~FreenectDevice() {}
void FreenectDevice::startVideo() {}
void FreenectDevice::stopVideo() {}
void FreenectDevice::startDepth() {}
void FreenectDevice::stopDepth() {}
bool FreenectDevice::init()
{
UERROR("RTAB-Map is not built with Freenect support!");
return false;
}
void FreenectDevice::freenect_depth_callback(freenect_device *dev, void *depth, uint32_t timestamp) {}
void FreenectDevice::freenect_video_callback(freenect_device *dev, void *video, uint32_t timestamp) {}
#endif
// Do not call directly even in child
void FreenectDevice::VideoCallback(void* _rgb, uint32_t timestamp)
{
rgbMutex_.lock();
uint8_t* rgb = static_cast<uint8_t*>(_rgb);
rgbMat_.data = rgb;
rgbReady_ = true;
rgbMutex_.unlock();
}
// Do not call directly even in child
void FreenectDevice::DepthCallback(void* _depth, uint32_t timestamp)
{
depthMutex_.lock();
uint16_t* depth = static_cast<uint16_t*>(_depth);
depthMat_.data = (uchar*) depth;
depthReady_ = true;
depthMutex_.unlock();
}
cv::Mat FreenectDevice::getRgb()
{
cv::Mat out;
rgbMutex_.lock();
if(rgbReady_)
{
cv::cvtColor(rgbMat_, out, CV_RGB2BGR);
rgbReady_ = false;
}
rgbMutex_.unlock();
return out;
}
cv::Mat FreenectDevice::getDepth()
{
cv::Mat out;
depthMutex_.lock();
if(depthReady_)
{
depthMat_.copyTo(out);
depthReady_ = false;
}
depthMutex_.unlock();
return out;
}
//
// CameraFreenect
//
bool CameraFreenect::available()
{
#ifdef WITH_FREENECT
return true;
#else
return false;
#endif
}
CameraFreenect::CameraFreenect(int deviceId, float inputRate, const Transform & localTransform) :
deviceId_(deviceId),
rate_(inputRate),
frameRateTimer_(new UTimer()),
localTransform_(localTransform),
seq_(0),
ctx_(0),
freenectDevice_(0)
{
#ifdef WITH_FREENECT
if(freenect_init(&ctx_, NULL) < 0) UERROR("Cannot initialize freenect library");
// We claim both the motor and camera devices, since this class exposes both.
// It does not support audio, so we do not claim it.
freenect_select_subdevices(ctx_, static_cast<freenect_device_flags>(FREENECT_DEVICE_MOTOR | FREENECT_DEVICE_CAMERA));
#endif
}
CameraFreenect::~CameraFreenect()
{
UDEBUG("");
join(true);
if(freenectDevice_)
{
delete freenectDevice_;
freenectDevice_ = 0;
}
#ifdef WITH_FREENECT
if(freenect_shutdown(ctx_) < 0){} //FN_WARNING("Freenect did not shutdown in a clean fashion");
#endif
delete frameRateTimer_;
}
bool CameraFreenect::init()
{
#ifdef WITH_FREENECT
if(!this->isRunning())
{
if(freenectDevice_)
{
delete freenectDevice_;
freenectDevice_ = 0;
}
seq_ = 0;
if(freenect_num_devices(ctx_) > 0)
{
freenectDevice_ = new FreenectDevice(ctx_, deviceId_);
if(freenectDevice_->init())
{
return true;
}
delete freenectDevice_;
freenectDevice_ = 0;
}
else
{
UERROR("CameraFreenect: No devices connected!");
}
}
else
{
UERROR("CameraFreenect: Cannot initialize the camera because it is already running...");
}
#else
UERROR("CameraFreenect: RTAB-Map is not built with Freenect support!");
#endif
return false;
}
void CameraFreenect::setFrameRate(float rate)
{
rate_ = rate;
}
void CameraFreenect::mainLoopBegin()
{
if(freenectDevice_)
{
freenectDevice_->startDepth();
freenectDevice_->startVideo();
frameRateTimer_->start();
}
else
{
UERROR("CameraFreenect: init should be called before starting the camera.");
this->kill();
}
}
void CameraFreenect::mainLoop()
{
#ifdef WITH_FREENECT
timeval t;
t.tv_sec = 0;
t.tv_usec = 10000;
if(freenect_process_events_timeout(ctx_, &t) < 0) UERROR("Cannot process freenect events");
if(freenectDevice_ && !this->isKilled())
{
float imageRate = rate_==0.0f?33.0f:rate_; // limit to 33Hz if infinity
if(frameRateTimer_->getElapsedTime() >= 1.0/double(imageRate)-0.000001)
{
double slept = frameRateTimer_->getElapsedTime();
frameRateTimer_->start();
UDEBUG("slept=%fs vs target=%fs", slept, 1.0/double(imageRate));
cv::Mat depth = freenectDevice_->getDepth();
cv::Mat rgb = freenectDevice_->getRgb();
if(depth.empty())
{
UWARN("CameraFreenect: Depth not ready! Try to reduce the image rate to avoid this warning...");
return;
}
if(rgb.empty())
{
UWARN("CameraFreenect: Rgb not ready! Try to reduce the image rate to avoid this warning...");
return;
}
UASSERT(freenectDevice_->getDepthFocal() != 0.0f);
float constant = 1.0f/freenectDevice_->getDepthFocal();
this->post(new CameraEvent(rgb, depth, constant, localTransform_, ++seq_));
}
}
#endif
}
void CameraFreenect::mainLoopEnd()
{
if(freenectDevice_)
{
freenectDevice_->stopDepth();
freenectDevice_->stopVideo();
}
}
} /* namespace rtabmap */

View File

@@ -1,152 +0,0 @@
/*
* CameraOpenni.cpp
*
* Created on: 2013-08-22
* Author: Mathieu
*/
#include "rtabmap/core/CameraOpenni.h"
#include "rtabmap/core/CameraEvent.h"
#include "rtabmap/utilite/ULogger.h"
#include <rtabmap/utilite/UTimer.h>
#include <rtabmap/utilite/UConversion.h>
#include <rtabmap/utilite/UEventsManager.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <pcl/io/openni_grabber.h>
namespace rtabmap {
CameraOpenni::CameraOpenni(const std::string & deviceId, float inputRate, const Transform & localTransform) :
interface_(0),
deviceId_(deviceId),
rate_(inputRate),
frameRateTimer_(new UTimer()),
localTransform_(localTransform),
seq_(0)
{
}
CameraOpenni::~CameraOpenni()
{
UDEBUG("");
kill();
delete frameRateTimer_;
if(interface_)
{
uSleep(100); // make sure it is stopped
delete interface_;
interface_ = 0;
}
}
void CameraOpenni::image_cb (
const boost::shared_ptr<openni_wrapper::Image>& rgb,
const boost::shared_ptr<openni_wrapper::DepthImage>& depth,
float constant)
{
if(rate_>0.0f)
{
if(frameRateTimer_->getElapsedTime() < 1.0f/rate_)
{
return;
}
}
frameRateTimer_->start();
UTimer t;
cv::Mat rgbFrame(rgb->getHeight(), rgb->getWidth(), CV_8UC3);
rgb->fillRGB(rgb->getWidth(), rgb->getHeight(), rgbFrame.data);
cv::Mat bgrFrame;
cv::cvtColor(rgbFrame, bgrFrame, CV_RGB2BGR);
cv::Mat depthFrame(rgb->getHeight(), rgb->getWidth(), CV_16UC1);
depth->fillDepthImageRaw(rgb->getWidth(), rgb->getHeight(), (unsigned short*)depthFrame.data);
UINFO("constant=%f focal=%f", constant, 1.0f/constant);
this->post(new CameraEvent(bgrFrame, depthFrame, constant, localTransform_, ++seq_));
}
bool CameraOpenni::init()
{
if(interface_ && interface_->isRunning())
{
UERROR("Already started!!!\n");
return false;
}
else if(interface_)
{
delete interface_;
interface_ = 0;
}
seq_ = 0;
try
{
interface_ = new pcl::OpenNIGrabber(deviceId_);
}
catch(const pcl::IOException& ex)
{
UERROR("OpenNI exception: %s", ex.what());
if(interface_)
{
delete interface_;
interface_ = 0;
}
return false;
}
frameRateTimer_->start();
return true;
}
void CameraOpenni::start()
{
if(interface_)
{
if(!connection_.connected())
{
boost::function<void (
const boost::shared_ptr<openni_wrapper::Image>&,
const boost::shared_ptr<openni_wrapper::DepthImage>&,
float)> f = boost::bind (&CameraOpenni::image_cb, this, _1, _2, _3);
connection_ = interface_->registerCallback (f);
}
if(!interface_->isRunning())
{
interface_->start ();
}
}
}
void CameraOpenni::pause()
{
if(connection_.connected())
{
connection_.disconnect();
}
}
void CameraOpenni::kill()
{
UDEBUG("");
if(interface_)
{
interface_->stop();
}
}
bool CameraOpenni::isRunning()
{
return (interface_ && interface_->isRunning());
}
void CameraOpenni::setFrameRate(float rate)
{
rate_ = rate;
}
} /* namespace rtabmap */

791
corelib/src/CameraRGBD.cpp Normal file
View File

@@ -0,0 +1,791 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rtabmap/core/CameraRGBD.h"
#include "rtabmap/core/DBDriver.h"
#include <rtabmap/utilite/UEventsManager.h>
#include <rtabmap/utilite/UConversion.h>
#include <rtabmap/utilite/UStl.h>
#include <rtabmap/utilite/UConversion.h>
#include <rtabmap/utilite/UFile.h>
#include <rtabmap/utilite/UDirectory.h>
#include <rtabmap/utilite/UTimer.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <pcl/io/openni_grabber.h>
#include <cmath>
#ifdef WITH_FREENECT
#include <libfreenect.h>
#include <libfreenect-registration.h>
#endif
#ifdef WITH_OPENNI2
#include <OpenNI.h>
#endif
namespace rtabmap
{
CameraRGBD::CameraRGBD(float imageRate, const Transform & localTransform) :
_imageRate(imageRate),
_localTransform(localTransform),
_frameRateTimer(new UTimer())
{
}
CameraRGBD::~CameraRGBD()
{
if(_frameRateTimer)
{
delete _frameRateTimer;
}
}
void CameraRGBD::takeImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant)
{
float imageRate = _imageRate==0.0f?33.0f:_imageRate; // limit to 33Hz if infinity
if(imageRate>0)
{
int sleepTime = (1000.0f/imageRate - 1000.0f*_frameRateTimer->getElapsedTime());
if(sleepTime > 2)
{
uSleep(sleepTime-2);
}
// Add precision at the cost of a small overhead
while(_frameRateTimer->getElapsedTime() < 1.0/double(imageRate)-0.000001)
{
//
}
double slept = _frameRateTimer->getElapsedTime();
_frameRateTimer->start();
UDEBUG("slept=%fs vs target=%fs", slept, 1.0/double(imageRate));
}
UTimer timer;
this->captureImage(rgb, depth, depthConstant);
UDEBUG("Time capturing image = %fs", timer.ticks());
}
/////////////////////////
// CameraOpenNIPCL
/////////////////////////
CameraOpenni::CameraOpenni(const std::string & deviceId, float imageRate, const Transform & localTransform) :
CameraRGBD(imageRate, localTransform),
interface_(0),
deviceId_(deviceId)
{
}
CameraOpenni::~CameraOpenni()
{
UDEBUG("");
if(connection_.connected())
{
connection_.disconnect();
}
if(interface_)
{
interface_->stop();
uSleep(1000); // make sure it is stopped
delete interface_;
interface_ = 0;
}
}
void CameraOpenni::image_cb (
const boost::shared_ptr<openni_wrapper::Image>& rgb,
const boost::shared_ptr<openni_wrapper::DepthImage>& depth,
float constant)
{
UScopeMutex s(dataMutex_);
cv::Mat rgbFrame(rgb->getHeight(), rgb->getWidth(), CV_8UC3);
rgb->fillRGB(rgb->getWidth(), rgb->getHeight(), rgbFrame.data);
cv::cvtColor(rgbFrame, rgb_, CV_RGB2BGR);
depth_ = cv::Mat(rgb->getHeight(), rgb->getWidth(), CV_16UC1);
depth->fillDepthImageRaw(rgb->getWidth(), rgb->getHeight(), (unsigned short*)depth_.data);
depthConstant_ = constant;
if(dataReady_.value() <= 0)
{
dataReady_.release();
}
}
bool CameraOpenni::init()
{
if(interface_)
{
interface_->stop();
uSleep(100); // make sure it is stopped
delete interface_;
interface_ = 0;
}
try
{
interface_ = new pcl::OpenNIGrabber(deviceId_);
boost::function<void (
const boost::shared_ptr<openni_wrapper::Image>&,
const boost::shared_ptr<openni_wrapper::DepthImage>&,
float)> f = boost::bind (&CameraOpenni::image_cb, this, _1, _2, _3);
connection_ = interface_->registerCallback (f);
interface_->start ();
}
catch(const pcl::IOException& ex)
{
UERROR("OpenNI exception: %s", ex.what());
if(interface_)
{
delete interface_;
interface_ = 0;
}
return false;
}
return true;
}
void CameraOpenni::captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant)
{
if(interface_ && interface_->isRunning())
{
dataReady_.acquire();
UScopeMutex s(dataMutex_);
depth = depth_;
rgb = rgb_;
depthConstant = depthConstant_;
depth_ = cv::Mat();
rgb_ = cv::Mat();
depthConstant_ = 0;
}
}
/////////////////////////
// CameraOpenNICV
/////////////////////////
bool CameraOpenNICV::available()
{
return cv::getBuildInformation().find("OpenNI: YES") != std::string::npos;
}
CameraOpenNICV::CameraOpenNICV(bool asus, float imageRate, const rtabmap::Transform & localTransform) :
CameraRGBD(imageRate, localTransform),
_asus(asus),
_depthFocal(0.0f)
{
}
CameraOpenNICV::~CameraOpenNICV()
{
_capture.release();
}
bool CameraOpenNICV::init()
{
if(_capture.isOpened())
{
_capture.release();
}
ULOGGER_DEBUG("CameraRGBD::init()");
_capture.open( _asus?CV_CAP_OPENNI_ASUS:CV_CAP_OPENNI );
if(_capture.isOpened())
{
_capture.set( CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CV_CAP_OPENNI_VGA_30HZ );
_depthFocal = _capture.get( CV_CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH );
// Print some avalible device settings.
UINFO("Depth generator output mode:");
UINFO("FRAME_WIDTH %f", _capture.get( CV_CAP_PROP_FRAME_WIDTH ));
UINFO("FRAME_HEIGHT %f", _capture.get( CV_CAP_PROP_FRAME_HEIGHT ));
UINFO("FRAME_MAX_DEPTH %f mm", _capture.get( CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH ));
UINFO("BASELINE %f mm", _capture.get( CV_CAP_PROP_OPENNI_BASELINE ));
UINFO("FPS %f", _capture.get( CV_CAP_PROP_FPS ));
UINFO("Focal %f", _capture.get( CV_CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH ));
UINFO("REGISTRATION %f", _capture.get( CV_CAP_PROP_OPENNI_REGISTRATION ));
if(_capture.get( CV_CAP_PROP_OPENNI_REGISTRATION ) == 0.0)
{
UERROR("Depth registration is not activated on this device!");
}
if( _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR_PRESENT ) )
{
UINFO("Image generator output mode:");
UINFO("FRAME_WIDTH %f", _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FRAME_WIDTH ));
UINFO("FRAME_HEIGHT %f", _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FRAME_HEIGHT ));
UINFO("FPS %f", _capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FPS ));
}
else
{
UERROR("CameraRGBD: Device doesn't contain image generator.");
_capture.release();
return false;
}
}
else
{
ULOGGER_ERROR("CameraRGBD: Failed to create a capture object!");
_capture.release();
return false;
}
return true;
}
void CameraOpenNICV::captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant)
{
if(_capture.isOpened())
{
_capture.grab();
_capture.retrieve( depth, CV_CAP_OPENNI_DEPTH_MAP );
_capture.retrieve( rgb, CV_CAP_OPENNI_BGR_IMAGE );
depth = depth.clone();
rgb = rgb.clone();
UASSERT(_depthFocal > 0.0f);
depthConstant = 1.0f/_depthFocal;
}
else
{
ULOGGER_WARN("The camera must be initialized before requesting an image.");
}
}
/////////////////////////
// CameraOpenNI2
/////////////////////////
bool CameraOpenNI2::available()
{
#ifdef WITH_OPENNI2
return true;
#else
return false;
#endif
}
CameraOpenNI2::CameraOpenNI2(float imageRate, const rtabmap::Transform & localTransform) :
CameraRGBD(imageRate, localTransform),
#ifdef WITH_OPENNI2
_device(new openni::Device()),
_color(new openni::VideoStream()),
_depth(new openni::VideoStream()),
#else
_device(0),
_color(0),
_depth(0),
#endif
_depthFocal(0.0f)
{
}
CameraOpenNI2::~CameraOpenNI2()
{
#ifdef WITH_OPENNI2
_color->stop();
_color->destroy();
_depth->stop();
_depth->destroy();
_device->close();
openni::OpenNI::shutdown();
delete _device;
delete _color;
delete _depth;
#endif
}
bool CameraOpenNI2::init()
{
#ifdef WITH_OPENNI2
openni::OpenNI::initialize();
if(_device->open(openni::ANY_DEVICE) != openni::STATUS_OK)
{
UERROR("CameraOpenNI2: Cannot open device.");
_device->close();
openni::OpenNI::shutdown();
return false;
}
if(!_device->isImageRegistrationModeSupported(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR))
{
UERROR("CameraOpenNI2: Device doesn't support depth/color registration.");
_device->close();
openni::OpenNI::shutdown();
return false;
}
if(_device->getSensorInfo(openni::SENSOR_DEPTH) == NULL ||
_device->getSensorInfo(openni::SENSOR_COLOR) == NULL)
{
UERROR("CameraOpenNI2: Cannot get sensor info for depth and color.");
_device->close();
openni::OpenNI::shutdown();
return false;
}
if(_depth->create(*_device, openni::SENSOR_DEPTH) != openni::STATUS_OK)
{
UERROR("CameraOpenNI2: Cannot create depth stream.");
_device->close();
openni::OpenNI::shutdown();
return false;
}
if(_color->create(*_device, openni::SENSOR_COLOR) != openni::STATUS_OK)
{
UERROR("CameraOpenNI2: Cannot create color stream.");
_depth->destroy();
_device->close();
openni::OpenNI::shutdown();
return false;
}
if(_device->setImageRegistrationMode(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR ) != openni::STATUS_OK)
{
UERROR("CameraOpenNI2: Failed to set depth/color registration.");
}
_depth->setMirroringEnabled(false);
_color->setMirroringEnabled(false);
const openni::Array<openni::VideoMode>& depthVideoModes = _depth->getSensorInfo().getSupportedVideoModes();
for(int i=0; i<depthVideoModes.getSize(); ++i)
{
UINFO("CameraOpenNI2: Depth video mode %d: fps=%d, pixel=%d, w=%d, h=%d",
i,
depthVideoModes[i].getFps(),
depthVideoModes[i].getPixelFormat(),
depthVideoModes[i].getResolutionX(),
depthVideoModes[i].getResolutionY());
}
const openni::Array<openni::VideoMode>& colorVideoModes = _color->getSensorInfo().getSupportedVideoModes();
for(int i=0; i<colorVideoModes.getSize(); ++i)
{
UINFO("CameraOpenNI2: Color video mode %d: fps=%d, pixel=%d, w=%d, h=%d",
i,
colorVideoModes[i].getFps(),
colorVideoModes[i].getPixelFormat(),
colorVideoModes[i].getResolutionX(),
colorVideoModes[i].getResolutionY());
}
openni::VideoMode mMode;
mMode.setFps(30);
mMode.setResolution(640,480);
mMode.setPixelFormat(openni::PIXEL_FORMAT_DEPTH_1_MM);
_depth->setVideoMode(mMode);
openni::VideoMode mModeColor;
mModeColor.setFps(30);
mModeColor.setResolution(640,480);
mModeColor.setPixelFormat(openni::PIXEL_FORMAT_RGB888);
_color->setVideoMode(mModeColor);
UINFO("CameraOpenNI2: Using depth video mode: fps=%d, pixel=%d, w=%d, h=%d, H-FOV=%f rad, V-FOV=%f rad",
_depth->getVideoMode().getFps(),
_depth->getVideoMode().getPixelFormat(),
_depth->getVideoMode().getResolutionX(),
_depth->getVideoMode().getResolutionY(),
_depth->getHorizontalFieldOfView(),
_depth->getVerticalFieldOfView());
bool registered = true;
if(registered)
{
_depthFocal = float(_color->getVideoMode().getResolutionX()/2) / std::tan(_color->getHorizontalFieldOfView()/2.0f);
}
else
{
_depthFocal = float(_depth->getVideoMode().getResolutionX()/2) / std::tan(_depth->getHorizontalFieldOfView()/2.0f);
}
UINFO("depth focal = %f", _depthFocal);
UINFO("CameraOpenNI2: Using color video mode: fps=%d, pixel=%d, w=%d, h=%d, H-FOV=%f rad, V-FOV=%f rad",
_color->getVideoMode().getFps(),
_color->getVideoMode().getPixelFormat(),
_color->getVideoMode().getResolutionX(),
_color->getVideoMode().getResolutionY(),
_color->getHorizontalFieldOfView(),
_color->getVerticalFieldOfView());
if(_depth->start() != openni::STATUS_OK ||
_color->start() != openni::STATUS_OK)
{
UERROR("CameraOpenNI2: Cannot start depth and/or color streams.");
_depth->stop();
_color->stop();
_depth->destroy();
_color->destroy();
_device->close();
openni::OpenNI::shutdown();
return false;
}
uSleep(1000); // just to make sure the sensor is correctly initialized
return true;
#else
UERROR("CameraOpenNI2: RTAB-Map is not built with OpenNI2 support!");
return false;
#endif
}
void CameraOpenNI2::captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant)
{
#ifdef WITH_OPENNI2
if(_device->isValid() &&
_depth->isValid() &&
_color->isValid() &&
_device->getSensorInfo(openni::SENSOR_DEPTH) != NULL &&
_device->getSensorInfo(openni::SENSOR_COLOR) != NULL)
{
openni::VideoFrameRef depthFrame, colorFrame;
_depth->readFrame(&depthFrame);
_color->readFrame(&colorFrame);
if(depthFrame.isValid() && colorFrame.isValid())
{
int h=depthFrame.getHeight();
int w=depthFrame.getWidth();
depth = cv::Mat(h, w, CV_16U, (void*)depthFrame.getData()).clone();
h=colorFrame.getHeight();
w=colorFrame.getWidth();
cv::Mat tmp(h, w, CV_8UC3, (void *)colorFrame.getData());
cv::cvtColor(tmp, rgb, CV_RGB2BGR);
}
UASSERT(_depthFocal != 0.0f);
depthConstant = 1.0f/_depthFocal;
}
else
{
ULOGGER_WARN("The camera must be initialized before requesting an image.");
}
#else
UERROR("CameraOpenNI2: RTAB-Map is not built with OpenNI2 support!");
#endif
}
#ifdef WITH_FREENECT
//
// FreenectDevice
//
class FreenectDevice : public UThread {
public:
FreenectDevice(freenect_context * ctx, int index) :
index_(index),
ctx_(ctx),
device_(0),
depthFocal_(0.0f)
{
UASSERT(ctx_ != 0);
}
~FreenectDevice()
{
this->join(true);
if(device_ && freenect_close_device(device_) < 0){} //FN_WARNING("Device did not shutdown in a clean fashion");
}
bool init()
{
if(freenect_open_device(ctx_, &device_, index_) < 0)
{
UERROR("FreenectDevice: Cannot open Kinect");
return false;
}
freenect_set_user(device_, this);
freenect_set_video_mode(device_, freenect_find_video_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_VIDEO_RGB));
freenect_set_depth_mode(device_, freenect_find_depth_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_DEPTH_REGISTERED));
depthBuffer_ = cv::Mat(cv::Size(640,480),CV_16UC1);
rgbBuffer_ = cv::Mat(cv::Size(640,480), CV_8UC3);
freenect_set_depth_buffer(device_, depthBuffer_.data);
freenect_set_video_buffer(device_, rgbBuffer_.data);
freenect_set_depth_callback(device_, freenect_depth_callback);
freenect_set_video_callback(device_, freenect_video_callback);
bool registered = true;
float rgb_focal_length_sxga = 1050.0f;
float width_sxga = 1280.0f;
float width = freenect_get_current_depth_mode(device_).width;
float scale = width / width_sxga;
if(registered)
{
depthFocal_ = rgb_focal_length_sxga * scale;
}
else
{
freenect_registration reg = freenect_copy_registration(device_);
float depth_focal_length_sxga = reg.zero_plane_info.reference_distance / reg.zero_plane_info.reference_pixel_size;
freenect_destroy_registration(&reg);
depthFocal_ = depth_focal_length_sxga * scale;
}
UINFO("FreenectDevice: Depth focal = %f", depthFocal_);
return true;
}
float getDepthFocal() const {return depthFocal_;}
void getData(cv::Mat & rgb, cv::Mat & depth)
{
if(this->isRunning())
{
dataReady_.acquire();
{
UScopeMutex s1(rgbMutex_);
if(!rgbLastFrame_.empty())
{
rgb = rgbLastFrame_;
rgbLastFrame_ = cv::Mat();
}
}
{
UScopeMutex s2(depthMutex_);
if(!depthLastFrame_.empty())
{
depth = depthLastFrame_;
depthLastFrame_= cv::Mat();
}
}
}
}
private:
// Do not call directly even in child
void VideoCallback(void* rgb)
{
UASSERT(rgbBuffer_.data == rgb);
UScopeMutex s1(rgbMutex_);
cv::cvtColor(rgbBuffer_, rgbLastFrame_, CV_RGB2BGR);
if(!depthLastFrame_.empty() && dataReady_.value() <= 0)
{
dataReady_.release();
}
}
// Do not call directly even in child
void DepthCallback(void* depth)
{
UASSERT(depthBuffer_.data == depth);
UScopeMutex s2(depthMutex_);
depthLastFrame_ = depthBuffer_.clone();
if(!rgbLastFrame_.empty() && dataReady_.value() <= 0)
{
dataReady_.release();
}
}
void startVideo() {
if(device_ && freenect_start_video(device_) < 0) UERROR("Cannot start RGB callback");
}
void stopVideo() {
if(device_ && freenect_stop_video(device_) < 0) UERROR("Cannot stop RGB callback");
}
void startDepth() {
if(device_ && freenect_start_depth(device_) < 0) UERROR("Cannot start depth callback");
}
void stopDepth() {
if(device_ && freenect_stop_depth(device_) < 0) UERROR("Cannot stop depth callback");
}
virtual void mainLoopBegin()
{
this->startDepth();
this->startVideo();
}
virtual void mainLoop()
{
timeval t;
t.tv_sec = 0;
t.tv_usec = 10000;
if(freenect_process_events_timeout(ctx_, &t) < 0)
{
UERROR("FreenectDevice: Cannot process freenect events");
this->kill();
}
}
virtual void mainLoopEnd()
{
this->stopDepth();
this->stopVideo();
dataReady_.release();
}
static void freenect_depth_callback(freenect_device *dev, void *depth, uint32_t timestamp) {
FreenectDevice* device = static_cast<FreenectDevice*>(freenect_get_user(dev));
device->DepthCallback(depth);
}
static void freenect_video_callback(freenect_device *dev, void *video, uint32_t timestamp) {
FreenectDevice* device = static_cast<FreenectDevice*>(freenect_get_user(dev));
device->VideoCallback(video);
}
//noncopyable
FreenectDevice( const FreenectDevice& );
const FreenectDevice& operator=( const FreenectDevice& );
private:
int index_;
freenect_context * ctx_;
freenect_device * device_;
cv::Mat depthBuffer_;
cv::Mat rgbBuffer_;
UMutex depthMutex_;
UMutex rgbMutex_;
cv::Mat depthLastFrame_;
cv::Mat rgbLastFrame_;
float depthFocal_;
USemaphore dataReady_;
};
#endif
//
// CameraFreenect
//
bool CameraFreenect::available()
{
#ifdef WITH_FREENECT
return true;
#else
return false;
#endif
}
CameraFreenect::CameraFreenect(int deviceId, float imageRate, const Transform & localTransform) :
CameraRGBD(imageRate, localTransform),
deviceId_(deviceId),
ctx_(0),
freenectDevice_(0)
{
#ifdef WITH_FREENECT
if(freenect_init(&ctx_, NULL) < 0) UERROR("Cannot initialize freenect library");
// We claim both the motor and camera devices, since this class exposes both.
// It does not support audio, so we do not claim it.
freenect_select_subdevices(ctx_, static_cast<freenect_device_flags>(FREENECT_DEVICE_MOTOR | FREENECT_DEVICE_CAMERA));
#endif
}
CameraFreenect::~CameraFreenect()
{
#ifdef WITH_FREENECT
if(freenectDevice_)
{
freenectDevice_->join(true);
delete freenectDevice_;
freenectDevice_ = 0;
}
if(ctx_)
{
if(freenect_shutdown(ctx_) < 0){} //FN_WARNING("Freenect did not shutdown in a clean fashion");
}
#endif
}
bool CameraFreenect::init()
{
#ifdef WITH_FREENECT
if(freenectDevice_)
{
freenectDevice_->join(true);
delete freenectDevice_;
freenectDevice_ = 0;
}
if(ctx_ && freenect_num_devices(ctx_) > 0)
{
freenectDevice_ = new FreenectDevice(ctx_, deviceId_);
if(freenectDevice_->init())
{
freenectDevice_->start();
uSleep(3000);
return true;
}
else
{
UERROR("CameraFreenect: Init failed!");
}
delete freenectDevice_;
freenectDevice_ = 0;
}
else
{
UERROR("CameraFreenect: No devices connected!");
}
#else
UERROR("CameraFreenect: RTAB-Map is not built with Freenect support!");
#endif
return false;
}
void CameraFreenect::captureImage(cv::Mat & rgb, cv::Mat & depth, float & depthConstant)
{
#ifdef WITH_FREENECT
if(ctx_ && freenectDevice_)
{
if(freenectDevice_->isRunning())
{
freenectDevice_->getData(rgb, depth);
UASSERT(freenectDevice_->getDepthFocal() != 0.0f);
depthConstant = 1.0f/freenectDevice_->getDepthFocal();
if(depth.empty())
{
UWARN("CameraFreenect: Data not ready! Try to reduce the image rate to avoid this warning...");
}
}
else
{
UERROR("CameraFreenect: Re-initialization needed!");
delete freenectDevice_;
freenectDevice_ = 0;
}
if(depth.empty() || rgb.empty())
{
rgb = cv::Mat();
depth = cv::Mat();
depthConstant = 0.0f;
}
}
#else
UERROR("CameraFreenect: RTAB-Map is not built with Freenect support!");
#endif
}
} // namespace rtabmap

View File

@@ -19,42 +19,70 @@
#include "rtabmap/core/CameraThread.h" #include "rtabmap/core/CameraThread.h"
#include "rtabmap/core/Camera.h" #include "rtabmap/core/Camera.h"
#include "rtabmap/core/CameraRGBD.h"
#include "rtabmap/core/CameraEvent.h" #include "rtabmap/core/CameraEvent.h"
#include "rtabmap/core/ParamEvent.h"
#include <rtabmap/utilite/UEventsManager.h>
#include <rtabmap/utilite/UTimer.h> #include <rtabmap/utilite/UTimer.h>
#include <rtabmap/utilite/ULogger.h>
namespace rtabmap namespace rtabmap
{ {
// ownership transferred // ownership transferred
CameraThread::CameraThread(Camera * camera, bool autoRestart) : CameraThread::CameraThread(Camera * camera) :
_camera(camera), _camera(camera),
_autoRestart(autoRestart), _cameraRGBD(0),
_seq(0) _seq(0)
{ {
UASSERT(_camera != 0); UASSERT(_camera != 0);
} }
// ownership transferred
CameraThread::CameraThread(CameraRGBD * camera) :
_camera(0),
_cameraRGBD(camera),
_seq(0)
{
UASSERT(_cameraRGBD != 0);
}
CameraThread::~CameraThread() CameraThread::~CameraThread()
{ {
join(true); join(true);
if(_camera)
{
delete _camera; delete _camera;
} }
if(_cameraRGBD)
{
delete _cameraRGBD;
}
}
void CameraThread::setImageRate(float imageRate)
{
if(_camera)
{
_camera->setImageRate(imageRate);
}
if(_cameraRGBD)
{
_cameraRGBD->setImageRate(imageRate);
}
}
bool CameraThread::init() bool CameraThread::init()
{ {
if(!this->isRunning()) if(!this->isRunning())
{
if(_camera)
{ {
_seq = 0; _seq = 0;
return _camera->init(); if(_cameraRGBD)
{
return _cameraRGBD->init();
} }
else else
{ {
UERROR("Cannot initialize the camera because the camera object is null..."); return _camera->init();
} }
} }
else else
@@ -67,29 +95,37 @@ bool CameraThread::init()
void CameraThread::mainLoop() void CameraThread::mainLoop()
{ {
UTimer timer; UTimer timer;
ULOGGER_DEBUG("Camera::process()"); UDEBUG("");
cv::Mat descriptors; cv::Mat descriptors;
std::vector<cv::KeyPoint> keypoints; std::vector<cv::KeyPoint> keypoints;
cv::Mat rgb, depth; cv::Mat rgb, depth;
float depthConstant = 0.0f; float depthConstant = 0.0f;
_camera->takeImage(rgb, depth, depthConstant); if(_cameraRGBD)
if(!rgb.empty() && !this->isKilled())
{ {
this->post(new CameraEvent(rgb, depth, depthConstant, _camera->getLocalTransform(), ++_seq)); _cameraRGBD->takeImage(rgb, depth, depthConstant);
}
else if(!this->isKilled())
{
if(_autoRestart)
{
_camera->init();
} }
else else
{ {
ULOGGER_DEBUG("Camera::process() : no more images..."); rgb = _camera->takeImage();
}
if(!rgb.empty() && !this->isKilled())
{
if(_cameraRGBD)
{
this->post(new CameraEvent(rgb, depth, depthConstant, _cameraRGBD->getLocalTransform(), ++_seq));
}
else
{
this->post(new CameraEvent(rgb, ++_seq));
}
}
else if(!this->isKilled())
{
UDEBUG("no more images...");
this->kill(); this->kill();
this->post(new CameraEvent()); this->post(new CameraEvent());
} }
} }
}
} // namespace rtabmap } // namespace rtabmap

View File

@@ -54,7 +54,7 @@ void filterKeypointsByDepth(
float depthConstant, float depthConstant,
float maxDepth) float maxDepth)
{ {
if(!depth.empty() && depthConstant > 0.0f && maxDepth > 0.0f && (descriptors.empty() || descriptors.rows == keypoints.size())) if(!depth.empty() && depthConstant > 0.0f && maxDepth > 0.0f && (descriptors.empty() || descriptors.rows == (int)keypoints.size()))
{ {
std::vector<cv::KeyPoint> output(keypoints.size()); std::vector<cv::KeyPoint> output(keypoints.size());
std::vector<int> indexes(keypoints.size(), 0); std::vector<int> indexes(keypoints.size(), 0);
@@ -71,7 +71,7 @@ void filterKeypointsByDepth(
output.resize(oi); output.resize(oi);
keypoints = output; keypoints = output;
if(!descriptors.empty() && keypoints.size() != descriptors.rows) if(!descriptors.empty() && (int)keypoints.size() != descriptors.rows)
{ {
if(keypoints.size() == 0) if(keypoints.size() == 0)
{ {

View File

@@ -7,8 +7,6 @@ SET(LIBRARIES
${OpenCV_LIBRARIES} ${OpenCV_LIBRARIES}
) )
add_definitions(${PCL_DEFINITIONS})
INCLUDE_DIRECTORIES(${INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
ADD_EXECUTABLE(bow_mapping main.cpp) ADD_EXECUTABLE(bow_mapping main.cpp)

View File

@@ -7,5 +7,6 @@ ELSE()
MESSAGE(STATUS "RTAB-Map GUI lib is not built, the RGBDMapping example will not be built...") MESSAGE(STATUS "RTAB-Map GUI lib is not built, the RGBDMapping example will not be built...")
ENDIF() ENDIF()
ADD_SUBDIRECTORY( CameraRGBD )

View File

@@ -19,8 +19,8 @@
#include "rtabmap/core/Rtabmap.h" #include "rtabmap/core/Rtabmap.h"
#include "rtabmap/core/RtabmapThread.h" #include "rtabmap/core/RtabmapThread.h"
#include "rtabmap/core/CameraOpenni.h" #include "rtabmap/core/CameraRGBD.h"
#include "rtabmap/core/CameraFreenect.h" #include "rtabmap/core/CameraThread.h"
#include "rtabmap/core/Odometry.h" #include "rtabmap/core/Odometry.h"
#include "rtabmap/utilite/UEventsManager.h" #include "rtabmap/utilite/UEventsManager.h"
#include <QtGui/QApplication> #include <QtGui/QApplication>
@@ -43,10 +43,10 @@ int main(int argc, char * argv[])
// Create the OpenNI camera, it will send a CameraEvent at the rate specified. // Create the OpenNI camera, it will send a CameraEvent at the rate specified.
// Set transform to camera so z is up, y is left and x going forward // Set transform to camera so z is up, y is left and x going forward
CameraOpenni camera("", 10, rtabmap::Transform(0,0,1,0, -1,0,0,0, 0,-1,0,0)); CameraRGBD * camera = new CameraOpenni("", 10, rtabmap::Transform(0,0,1,0, -1,0,0,0, 0,-1,0,0));
//CameraOpenKinect camera(0, 10, rtabmap::Transform(0,0,1,0, -1,0,0,0, 0,-1,0,0)); //CameraRGBD * camera = new CameraFreenect(0, 10, rtabmap::Transform(0,0,1,0, -1,0,0,0, 0,-1,0,0));
CameraThread cameraThread(camera);
if(!camera.init()) if(!cameraThread.init())
{ {
UERROR("Camera init failed!"); UERROR("Camera init failed!");
exit(1); exit(1);
@@ -72,12 +72,12 @@ int main(int argc, char * argv[])
// only the odometry will receive CameraEvent from that camera. RTAB-Map is // only the odometry will receive CameraEvent from that camera. RTAB-Map is
// also subscribed to OdometryEvent by default, so no need to create a pipe between // also subscribed to OdometryEvent by default, so no need to create a pipe between
// odometry and RTAB-Map. // odometry and RTAB-Map.
UEventsManager::createPipe(&camera, &odomThread, "CameraEvent"); UEventsManager::createPipe(&cameraThread, &odomThread, "CameraEvent");
// Let's start the threads // Let's start the threads
rtabmapThread.start(); rtabmapThread.start();
odomThread.start(); odomThread.start();
camera.start(); cameraThread.start();
mapBuilder.show(); mapBuilder.show();
app.exec(); // main loop app.exec(); // main loop
@@ -88,7 +88,7 @@ int main(int argc, char * argv[])
odomThread.unregisterFromEventsManager(); odomThread.unregisterFromEventsManager();
// Kill all threads // Kill all threads
camera.kill(); cameraThread.kill();
odomThread.join(true); odomThread.join(true);
rtabmapThread.join(true); rtabmapThread.join(true);

View File

@@ -205,8 +205,6 @@ private:
State _state; State _state;
rtabmap::CameraThread * _camera; rtabmap::CameraThread * _camera;
rtabmap::DBReader * _dbReader; rtabmap::DBReader * _dbReader;
rtabmap::CameraOpenni * _cameraOpenni;
rtabmap::CameraFreenect * _cameraOpenKinect;
rtabmap::OdometryThread * _odomThread; rtabmap::OdometryThread * _odomThread;
SrcType _srcType; SrcType _srcType;

View File

@@ -49,8 +49,6 @@ class QDoubleSpinBox;
namespace rtabmap { namespace rtabmap {
class CameraOpenni;
class CameraFreenect;
class OdometryThread; class OdometryThread;
class CameraThread; class CameraThread;
class Signature; class Signature;
@@ -151,12 +149,10 @@ public:
bool isSourceDatabaseUsed() const; bool isSourceDatabaseUsed() const;
bool isSourceOpenniUsed() const; bool isSourceOpenniUsed() const;
OdomType getOdometryType() const; OdomType getOdometryType() const;
bool getGeneralAutoRestart() const;
int getSourceImageType() const; int getSourceImageType() const;
QString getSourceImageTypeStr() const; QString getSourceImageTypeStr() const;
int getSourceWidth() const; int getSourceWidth() const;
int getSourceHeight() const; int getSourceHeight() const;
int getFramesDropped() const;
QString getSourceImagesPath() const; //Images group QString getSourceImagesPath() const; //Images group
QString getSourceImagesSuffix() const; //Images group QString getSourceImagesSuffix() const; //Images group
int getSourceImagesSuffixIndex() const; //Images group int getSourceImagesSuffixIndex() const; //Images group
@@ -196,7 +192,6 @@ public slots:
void setInputRate(double value); void setInputRate(double value);
void setDetectionRate(double value); void setDetectionRate(double value);
void setHardThr(int value); void setHardThr(int value);
void setAutoRestart(bool value);
void setTimeLimit(float value); void setTimeLimit(float value);
void setSLAMMode(bool enabled); void setSLAMMode(bool enabled);
void selectSourceImage(Src src = kSrcUndef); void selectSourceImage(Src src = kSrcUndef);
@@ -279,9 +274,7 @@ private:
QProgressDialog * _progressDialog; QProgressDialog * _progressDialog;
//Odometry test //Odometry test
CameraOpenni * _odomCameraOpenNI; CameraThread * _cameraThread;
CameraFreenect * _odomCameraFreenect;
CameraThread * _odomCameraOpenNICv;
OdometryThread * _odomThread; OdometryThread * _odomThread;
QVector<QCheckBox*> _3dRenderingShowClouds; QVector<QCheckBox*> _3dRenderingShowClouds;

View File

@@ -65,8 +65,7 @@
#include <QtGui/QInputDialog> #include <QtGui/QInputDialog>
//RGB-D stuff //RGB-D stuff
#include "rtabmap/core/CameraOpenni.h" #include "rtabmap/core/CameraRGBD.h"
#include "rtabmap/core/CameraFreenect.h"
#include "rtabmap/core/Odometry.h" #include "rtabmap/core/Odometry.h"
#include "rtabmap/core/OdometryEvent.h" #include "rtabmap/core/OdometryEvent.h"
#include "rtabmap/core/util3d.h" #include "rtabmap/core/util3d.h"
@@ -97,8 +96,6 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
_state(kIdle), _state(kIdle),
_camera(0), _camera(0),
_dbReader(0), _dbReader(0),
_cameraOpenni(0),
_cameraOpenKinect(0),
_odomThread(0), _odomThread(0),
_srcType(kSrcUndefined), _srcType(kSrcUndefined),
_preferencesDialog(0), _preferencesDialog(0),
@@ -291,8 +288,8 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
_ui->actionFreenect->setEnabled(CameraFreenect::available()); _ui->actionFreenect->setEnabled(CameraFreenect::available());
connect(_ui->actionOpenNI_CV, SIGNAL(triggered()), this, SLOT(selectOpenniCv())); connect(_ui->actionOpenNI_CV, SIGNAL(triggered()), this, SLOT(selectOpenniCv()));
connect(_ui->actionOpenNI_CV_ASUS, SIGNAL(triggered()), this, SLOT(selectOpenniCvAsus())); connect(_ui->actionOpenNI_CV_ASUS, SIGNAL(triggered()), this, SLOT(selectOpenniCvAsus()));
_ui->actionOpenNI_CV->setEnabled(CameraRGBD::available()); _ui->actionOpenNI_CV->setEnabled(CameraOpenNICV::available());
_ui->actionOpenNI_CV_ASUS->setEnabled(CameraRGBD::available()); _ui->actionOpenNI_CV_ASUS->setEnabled(CameraOpenNICV::available());
connect(_ui->actionOpenNI2, SIGNAL(triggered()), this, SLOT(selectOpenni2())); connect(_ui->actionOpenNI2, SIGNAL(triggered()), this, SLOT(selectOpenni2()));
_ui->actionOpenNI2->setEnabled(CameraOpenNI2::available()); _ui->actionOpenNI2->setEnabled(CameraOpenNI2::available());
@@ -420,18 +417,6 @@ void MainWindow::closeEvent(QCloseEvent* event)
delete _dbReader; delete _dbReader;
_dbReader = 0; _dbReader = 0;
} }
if(_cameraOpenni)
{
UERROR("CameraOpenni must be already deleted here!");
delete _cameraOpenni;
_cameraOpenni = 0;
}
if(_cameraOpenKinect)
{
UERROR("CameraOpenKinect must be already deleted here!");
delete _cameraOpenKinect;
_cameraOpenKinect = 0;
}
if(_odomThread) if(_odomThread)
{ {
UERROR("OdomThread must be already deleted here!"); UERROR("OdomThread must be already deleted here!");
@@ -1530,23 +1515,12 @@ void MainWindow::applyPrefSettings(PreferencesDialog::PANEL_FLAGS flags)
if(_camera) if(_camera)
{ {
_camera->getCamera()->setImageRate(_preferencesDialog->getGeneralInputRate()); _camera->setImageRate(_preferencesDialog->getGeneralInputRate());
_camera->setAutoRestart(_preferencesDialog->getGeneralAutoRestart());
} }
if(_dbReader) if(_dbReader)
{ {
_dbReader->setFrameRate(_preferencesDialog->getGeneralInputRate()); _dbReader->setFrameRate(_preferencesDialog->getGeneralInputRate());
} }
if(_cameraOpenni)
{
_cameraOpenni->setFrameRate(_preferencesDialog->getGeneralInputRate());
}
if(_cameraOpenKinect)
{
_cameraOpenKinect->setFrameRate(_preferencesDialog->getGeneralInputRate());
}
} }
if(flags & PreferencesDialog::kPanelGeneral) if(flags & PreferencesDialog::kPanelGeneral)
@@ -1965,24 +1939,6 @@ void MainWindow::startDetection()
emit stateChanged(kIdle); emit stateChanged(kIdle);
return; return;
} }
if(_cameraOpenni != 0)
{
QMessageBox::warning(this,
tr("RTAB-Map"),
tr("An Openni camera is running, stop it first."));
UWARN("_cameraOpenni is not null... it must be stopped first");
emit stateChanged(kIdle);
return;
}
if(_cameraOpenKinect != 0)
{
QMessageBox::warning(this,
tr("RTAB-Map"),
tr("A Freenect camera is running, stop it first."));
UWARN("_cameraOpenKinect is not null... it must be stopped first");
emit stateChanged(kIdle);
return;
}
// Adjust pre-requirements // Adjust pre-requirements
if( !_preferencesDialog->isSourceImageUsed() && if( !_preferencesDialog->isSourceImageUsed() &&
@@ -2029,62 +1985,40 @@ void MainWindow::startDetection()
_odomThread->start(); _odomThread->start();
} }
if(_preferencesDialog->getSourceRGBD() == PreferencesDialog::kSrcFreenect) CameraRGBD * camera = 0;
if(_preferencesDialog->getSourceRGBD() == PreferencesDialog::kSrcOpenNI_PCL)
{ {
_cameraOpenKinect = new CameraFreenect( camera = new CameraOpenni(
_preferencesDialog->getSourceOpenniDevice().toStdString(),
_preferencesDialog->getGeneralInputRate(),
_preferencesDialog->getSourceOpenniLocalTransform());
}
else if(_preferencesDialog->getSourceRGBD() == PreferencesDialog::kSrcOpenNI2)
{
camera = new CameraOpenNI2(
_preferencesDialog->getGeneralInputRate(),
_preferencesDialog->getSourceOpenniLocalTransform());
}
else if(_preferencesDialog->getSourceRGBD() == PreferencesDialog::kSrcFreenect)
{
camera = new CameraFreenect(
_preferencesDialog->getSourceOpenniDevice().isEmpty()?0:atoi(_preferencesDialog->getSourceOpenniDevice().toStdString().c_str()), _preferencesDialog->getSourceOpenniDevice().isEmpty()?0:atoi(_preferencesDialog->getSourceOpenniDevice().toStdString().c_str()),
_preferencesDialog->getGeneralInputRate(), _preferencesDialog->getGeneralInputRate(),
_preferencesDialog->getSourceOpenniLocalTransform()); _preferencesDialog->getSourceOpenniLocalTransform());
if(!_cameraOpenKinect->init())
{
ULOGGER_WARN("init CameraFreenect failed... ");
if(!_cameraOpenKinect->available())
{
QMessageBox::warning(this,
tr("RTAB-Map"),
tr("Freenect camera unavailable! RTAB-Map is not built with Freenect support (libfreenect)."));
}
else
{
QMessageBox::warning(this,
tr("RTAB-Map"),
tr("Freenect camera initialization failed!"));
}
emit stateChanged(kIdle);
delete _cameraOpenKinect;
_cameraOpenKinect = 0;
if(_odomThread)
{
delete _odomThread;
_odomThread = 0;
}
return;
}
if(_odomThread)
{
UEventsManager::createPipe(_cameraOpenKinect, _odomThread, "CameraEvent");
}
} }
else if(_preferencesDialog->getSourceRGBD() == PreferencesDialog::kSrcOpenNI_CV || else if(_preferencesDialog->getSourceRGBD() == PreferencesDialog::kSrcOpenNI_CV ||
_preferencesDialog->getSourceRGBD() == PreferencesDialog::kSrcOpenNI_CV_ASUS || _preferencesDialog->getSourceRGBD() == PreferencesDialog::kSrcOpenNI_CV_ASUS)
_preferencesDialog->getSourceRGBD() == PreferencesDialog::kSrcOpenNI2)
{ {
Camera * camera = 0; camera = new CameraOpenNICV(
if(_preferencesDialog->getSourceRGBD() == PreferencesDialog::kSrcOpenNI2) _preferencesDialog->getSourceRGBD() == PreferencesDialog::kSrcOpenNI_CV_ASUS,
{ _preferencesDialog->getGeneralInputRate(),
camera = new CameraOpenNI2( _preferencesDialog->getSourceOpenniLocalTransform());
_preferencesDialog->getGeneralInputRate());
} }
else else
{ {
camera = new CameraRGBD( UFATAL("RGBD Source type undefined!");
_preferencesDialog->getGeneralInputRate(),
_preferencesDialog->getSourceRGBD() == PreferencesDialog::kSrcOpenNI_CV_ASUS);
} }
camera->setLocalTransform(_preferencesDialog->getSourceOpenniLocalTransform());
if(!camera->init()) if(!camera->init())
{ {
ULOGGER_WARN("init camera failed... "); ULOGGER_WARN("init camera failed... ");
@@ -2108,35 +2042,6 @@ void MainWindow::startDetection()
UEventsManager::createPipe(_camera, _odomThread, "CameraEvent"); UEventsManager::createPipe(_camera, _odomThread, "CameraEvent");
} }
} }
else
{
_cameraOpenni = new CameraOpenni(
_preferencesDialog->getSourceOpenniDevice().toStdString(),
_preferencesDialog->getGeneralInputRate(),
_preferencesDialog->getSourceOpenniLocalTransform());
if(!_cameraOpenni->init())
{
ULOGGER_WARN("init CameraOpenni failed... ");
QMessageBox::warning(this,
tr("RTAB-Map"),
tr("Openni camera initialization failed!"));
emit stateChanged(kIdle);
delete _cameraOpenni;
_cameraOpenni = 0;
if(_odomThread)
{
delete _odomThread;
_odomThread = 0;
}
return;
}
if(_odomThread)
{
UEventsManager::createPipe(_cameraOpenni, _odomThread, "CameraEvent");
}
}
}
else if(_preferencesDialog->isSourceDatabaseUsed()) else if(_preferencesDialog->isSourceDatabaseUsed())
{ {
_dbReader = new DBReader(_preferencesDialog->getSourceDatabasePath().toStdString(), _dbReader = new DBReader(_preferencesDialog->getSourceDatabasePath().toStdString(),
@@ -2211,9 +2116,7 @@ void MainWindow::startDetection()
_preferencesDialog->getSourceImagesRefreshDir(), _preferencesDialog->getSourceImagesRefreshDir(),
_preferencesDialog->getGeneralInputRate(), _preferencesDialog->getGeneralInputRate(),
_preferencesDialog->getSourceWidth(), _preferencesDialog->getSourceWidth(),
_preferencesDialog->getSourceHeight(), _preferencesDialog->getSourceHeight());
_preferencesDialog->getFramesDropped()
);
} }
else if(sourceType == 2) else if(sourceType == 2)
{ {
@@ -2221,8 +2124,7 @@ void MainWindow::startDetection()
_preferencesDialog->getSourceVideoPath().toStdString(), _preferencesDialog->getSourceVideoPath().toStdString(),
_preferencesDialog->getGeneralInputRate(), _preferencesDialog->getGeneralInputRate(),
_preferencesDialog->getSourceWidth(), _preferencesDialog->getSourceWidth(),
_preferencesDialog->getSourceHeight(), _preferencesDialog->getSourceHeight());
_preferencesDialog->getFramesDropped());
} }
else //if(sourceType == 0) else //if(sourceType == 0)
{ {
@@ -2230,8 +2132,7 @@ void MainWindow::startDetection()
_preferencesDialog->getSourceUsbDeviceId(), _preferencesDialog->getSourceUsbDeviceId(),
_preferencesDialog->getGeneralInputRate(), _preferencesDialog->getGeneralInputRate(),
_preferencesDialog->getSourceWidth(), _preferencesDialog->getSourceWidth(),
_preferencesDialog->getSourceHeight(), _preferencesDialog->getSourceHeight());
_preferencesDialog->getFramesDropped());
} }
if(!camera->init()) if(!camera->init())
@@ -2274,7 +2175,7 @@ void MainWindow::startDetection()
// Could not be in the main thread here! (see handleEvents()) // Could not be in the main thread here! (see handleEvents())
void MainWindow::pauseDetection() void MainWindow::pauseDetection()
{ {
if(_camera || _dbReader || _cameraOpenni || _cameraOpenKinect) if(_camera || _dbReader)
{ {
if(_state == kPaused && (QApplication::keyboardModifiers() & Qt::ShiftModifier)) if(_state == kPaused && (QApplication::keyboardModifiers() & Qt::ShiftModifier))
{ {
@@ -2308,16 +2209,14 @@ void MainWindow::pauseDetection()
void MainWindow::stopDetection() void MainWindow::stopDetection()
{ {
if(_state == kIdle || (!_camera && !_dbReader && !_cameraOpenni && !_cameraOpenKinect)) if(_state == kIdle || (!_camera && !_dbReader))
{ {
return; return;
} }
if(_state == kDetecting && if(_state == kDetecting &&
( (_camera && _camera->isRunning()) || ( (_camera && _camera->isRunning()) ||
(_dbReader && _dbReader->isRunning()) || (_dbReader && _dbReader->isRunning()) ) )
(_cameraOpenni && _cameraOpenni->isRunning()) ||
(_cameraOpenKinect && _cameraOpenKinect->isRunning()) ) )
{ {
QMessageBox::StandardButton button = QMessageBox::question(this, tr("Stopping process..."), tr("Are you sure you want to stop the process?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::No); QMessageBox::StandardButton button = QMessageBox::question(this, tr("Stopping process..."), tr("Are you sure you want to stop the process?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
@@ -2339,16 +2238,6 @@ void MainWindow::stopDetection()
_dbReader->join(true); _dbReader->join(true);
} }
if(_cameraOpenni)
{
_cameraOpenni->kill();
}
if(_cameraOpenKinect)
{
_cameraOpenKinect->join(true);
}
if(_odomThread) if(_odomThread)
{ {
_ui->actionReset_Odometry->setEnabled(false); _ui->actionReset_Odometry->setEnabled(false);
@@ -2366,16 +2255,6 @@ void MainWindow::stopDetection()
delete _dbReader; delete _dbReader;
_dbReader = 0; _dbReader = 0;
} }
if(_cameraOpenni)
{
delete _cameraOpenni;
_cameraOpenni = 0;
}
if(_cameraOpenKinect)
{
delete _cameraOpenKinect;
_cameraOpenKinect = 0;
}
if(_odomThread) if(_odomThread)
{ {
delete _odomThread; delete _odomThread;
@@ -3815,16 +3694,6 @@ void MainWindow::changeState(MainWindow::State newState)
{ {
_dbReader->start(); _dbReader->start();
} }
if(_cameraOpenni)
{
_cameraOpenni->start();
}
if(_cameraOpenKinect)
{
_cameraOpenKinect->start();
}
break; break;
case kPaused: case kPaused:
@@ -3853,16 +3722,6 @@ void MainWindow::changeState(MainWindow::State newState)
{ {
_dbReader->start(); _dbReader->start();
} }
if(_cameraOpenni)
{
_cameraOpenni->start();
}
if(_cameraOpenKinect)
{
_cameraOpenKinect->start();
}
} }
else if(_state == kDetecting) else if(_state == kDetecting)
{ {
@@ -3889,16 +3748,6 @@ void MainWindow::changeState(MainWindow::State newState)
{ {
_dbReader->join(true); _dbReader->join(true);
} }
if(_cameraOpenni)
{
_cameraOpenni->pause();
}
if(_cameraOpenKinect)
{
_cameraOpenKinect->join(true);
}
} }
break; break;
case kMonitoring: case kMonitoring:

View File

@@ -49,7 +49,7 @@ OdometryViewer::OdometryViewer(int maxClouds, int decimation, float voxelSize, i
void OdometryViewer::processData() void OdometryViewer::processData()
{ {
rtabmap::Image data; rtabmap::Image data;
int quality; int quality = 0;
dataMutex_.lock(); dataMutex_.lock();
if(data_.size()) if(data_.size())
{ {

View File

@@ -38,8 +38,7 @@
#include "rtabmap/core/Rtabmap.h" #include "rtabmap/core/Rtabmap.h"
#include "rtabmap/core/Parameters.h" #include "rtabmap/core/Parameters.h"
#include "rtabmap/core/Odometry.h" #include "rtabmap/core/Odometry.h"
#include "rtabmap/core/CameraOpenni.h" #include "rtabmap/core/CameraRGBD.h"
#include "rtabmap/core/CameraFreenect.h"
#include "rtabmap/core/CameraThread.h" #include "rtabmap/core/CameraThread.h"
#include "rtabmap/core/Camera.h" #include "rtabmap/core/Camera.h"
#include "rtabmap/core/Memory.h" #include "rtabmap/core/Memory.h"
@@ -64,9 +63,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui(0), _ui(0),
_indexModel(0), _indexModel(0),
_initialized(false), _initialized(false),
_odomCameraOpenNI(0), _cameraThread(0),
_odomCameraFreenect(0),
_odomCameraOpenNICv(0),
_odomThread(0) _odomThread(0)
{ {
ULOGGER_DEBUG(""); ULOGGER_DEBUG("");
@@ -210,12 +207,10 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->stackedWidget_image->setCurrentIndex(_ui->source_comboBox_image_type->currentIndex()); _ui->stackedWidget_image->setCurrentIndex(_ui->source_comboBox_image_type->currentIndex());
connect(_ui->source_comboBox_image_type, SIGNAL(currentIndexChanged(int)), _ui->stackedWidget_image, SLOT(setCurrentIndex(int))); connect(_ui->source_comboBox_image_type, SIGNAL(currentIndexChanged(int)), _ui->stackedWidget_image, SLOT(setCurrentIndex(int)));
connect(_ui->source_comboBox_image_type, SIGNAL(currentIndexChanged(int)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->source_comboBox_image_type, SIGNAL(currentIndexChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->general_checkBox_autoRestart, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
//usbDevice group //usbDevice group
connect(_ui->source_usbDevice_spinBox_id, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->source_usbDevice_spinBox_id, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->source_spinBox_imgWidth, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->source_spinBox_imgWidth, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->source_spinBox_imgheight, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->source_spinBox_imgheight, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->source_spinBox_framesDropped, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
//images group //images group
connect(_ui->source_images_toolButton_selectSource, SIGNAL(clicked()), this, SLOT(selectSourceImage())); connect(_ui->source_images_toolButton_selectSource, SIGNAL(clicked()), this, SLOT(selectSourceImage()));
connect(_ui->source_images_lineEdit_path, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->source_images_lineEdit_path, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
@@ -238,8 +233,8 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->radioButton_freenect->setEnabled(CameraFreenect::available()); _ui->radioButton_freenect->setEnabled(CameraFreenect::available());
connect(_ui->radioButton_opennicv, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->radioButton_opennicv, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->radioButton_opennicvasus, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->radioButton_opennicvasus, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteSourcePanel()));
_ui->radioButton_opennicv->setEnabled(CameraRGBD::available()); _ui->radioButton_opennicv->setEnabled(CameraOpenNICV::available());
_ui->radioButton_opennicvasus->setEnabled(CameraRGBD::available()); _ui->radioButton_opennicvasus->setEnabled(CameraOpenNICV::available());
connect(_ui->radioButton_openni2, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->radioButton_openni2, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteSourcePanel()));
_ui->radioButton_openni2->setEnabled(CameraOpenNI2::available()); _ui->radioButton_openni2->setEnabled(CameraOpenNI2::available());
connect(_ui->lineEdit_openniDevice, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel())); connect(_ui->lineEdit_openniDevice, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
@@ -765,8 +760,6 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
_ui->groupBox_sourceImage->setChecked(false); _ui->groupBox_sourceImage->setChecked(false);
_ui->source_spinBox_imgWidth->setValue(0); _ui->source_spinBox_imgWidth->setValue(0);
_ui->source_spinBox_imgheight->setValue(0); _ui->source_spinBox_imgheight->setValue(0);
_ui->source_spinBox_framesDropped->setValue(0);
_ui->general_checkBox_autoRestart->setChecked(false);
_ui->source_images_spinBox_startPos->setValue(1); _ui->source_images_spinBox_startPos->setValue(1);
_ui->source_images_refreshDir->setChecked(false); _ui->source_images_refreshDir->setChecked(false);
@@ -987,11 +980,9 @@ void PreferencesDialog::readCameraSettings(const QString & filePath)
settings.beginGroup("Camera"); settings.beginGroup("Camera");
_ui->groupBox_sourceImage->setChecked(settings.value("imageUsed", _ui->groupBox_sourceImage->isChecked()).toBool()); _ui->groupBox_sourceImage->setChecked(settings.value("imageUsed", _ui->groupBox_sourceImage->isChecked()).toBool());
_ui->general_doubleSpinBox_imgRate->setValue(settings.value("imgRate", _ui->general_doubleSpinBox_imgRate->value()).toDouble()); _ui->general_doubleSpinBox_imgRate->setValue(settings.value("imgRate", _ui->general_doubleSpinBox_imgRate->value()).toDouble());
_ui->general_checkBox_autoRestart->setChecked(settings.value("autoRestart", _ui->general_checkBox_autoRestart->isChecked()).toBool());
_ui->source_comboBox_image_type->setCurrentIndex(settings.value("type", _ui->source_comboBox_image_type->currentIndex()).toInt()); _ui->source_comboBox_image_type->setCurrentIndex(settings.value("type", _ui->source_comboBox_image_type->currentIndex()).toInt());
_ui->source_spinBox_imgWidth->setValue(settings.value("imgWidth",_ui->source_spinBox_imgWidth->value()).toInt()); _ui->source_spinBox_imgWidth->setValue(settings.value("imgWidth",_ui->source_spinBox_imgWidth->value()).toInt());
_ui->source_spinBox_imgheight->setValue(settings.value("imgHeight",_ui->source_spinBox_imgheight->value()).toInt()); _ui->source_spinBox_imgheight->setValue(settings.value("imgHeight",_ui->source_spinBox_imgheight->value()).toInt());
_ui->source_spinBox_framesDropped->setValue(settings.value("framesDropped",_ui->source_spinBox_framesDropped->value()).toInt());
//usbDevice group //usbDevice group
settings.beginGroup("usbDevice"); settings.beginGroup("usbDevice");
_ui->source_usbDevice_spinBox_id->setValue(settings.value("id",_ui->source_usbDevice_spinBox_id->value()).toInt()); _ui->source_usbDevice_spinBox_id->setValue(settings.value("id",_ui->source_usbDevice_spinBox_id->value()).toInt());
@@ -1196,11 +1187,9 @@ void PreferencesDialog::writeCameraSettings(const QString & filePath)
settings.beginGroup("Camera"); settings.beginGroup("Camera");
settings.setValue("imageUsed", _ui->groupBox_sourceImage->isChecked()); settings.setValue("imageUsed", _ui->groupBox_sourceImage->isChecked());
settings.setValue("imgRate", _ui->general_doubleSpinBox_imgRate->value()); settings.setValue("imgRate", _ui->general_doubleSpinBox_imgRate->value());
settings.setValue("autoRestart", _ui->general_checkBox_autoRestart->isChecked());
settings.setValue("type", _ui->source_comboBox_image_type->currentIndex()); settings.setValue("type", _ui->source_comboBox_image_type->currentIndex());
settings.setValue("imgWidth", _ui->source_spinBox_imgWidth->value()); settings.setValue("imgWidth", _ui->source_spinBox_imgWidth->value());
settings.setValue("imgHeight", _ui->source_spinBox_imgheight->value()); settings.setValue("imgHeight", _ui->source_spinBox_imgheight->value());
settings.setValue("framesDropped", _ui->source_spinBox_framesDropped->value());
//usbDevice group //usbDevice group
settings.beginGroup("usbDevice"); settings.beginGroup("usbDevice");
settings.setValue("id", _ui->source_usbDevice_spinBox_id->value()); settings.setValue("id", _ui->source_usbDevice_spinBox_id->value());
@@ -2467,10 +2456,6 @@ PreferencesDialog::OdomType PreferencesDialog::getOdometryType() const
return kOdomICP; return kOdomICP;
} }
bool PreferencesDialog::getGeneralAutoRestart() const
{
return _ui->general_checkBox_autoRestart->isChecked();
}
int PreferencesDialog::getSourceImageType() const int PreferencesDialog::getSourceImageType() const
{ {
return _ui->source_comboBox_image_type->currentIndex(); return _ui->source_comboBox_image_type->currentIndex();
@@ -2487,10 +2472,6 @@ int PreferencesDialog::getSourceHeight() const
{ {
return _ui->source_spinBox_imgheight->value(); return _ui->source_spinBox_imgheight->value();
} }
int PreferencesDialog::getFramesDropped() const
{
return _ui->source_spinBox_framesDropped->value();
}
QString PreferencesDialog::getSourceImagesPath() const QString PreferencesDialog::getSourceImagesPath() const
{ {
return _ui->source_images_lineEdit_path->text(); return _ui->source_images_lineEdit_path->text();
@@ -2666,23 +2647,6 @@ void PreferencesDialog::setDetectionRate(double value)
} }
} }
void PreferencesDialog::setAutoRestart(bool value)
{
ULOGGER_DEBUG("autoRestart=%d", value);
if(_ui->general_checkBox_autoRestart->isChecked() != value)
{
_ui->general_checkBox_autoRestart->setChecked(value);
if(validateForm())
{
this->writeSettings();
}
else
{
this->readSettingsBegin();
}
}
}
void PreferencesDialog::setTimeLimit(float value) void PreferencesDialog::setTimeLimit(float value)
{ {
ULOGGER_DEBUG("timeLimit=%fs", value); ULOGGER_DEBUG("timeLimit=%fs", value);
@@ -2735,77 +2699,53 @@ void PreferencesDialog::testOdometry()
void PreferencesDialog::testOdometry(OdomType type) void PreferencesDialog::testOdometry(OdomType type)
{ {
UASSERT(_odomCameraOpenNI == 0 && _odomCameraFreenect == 0 && _odomThread == 0 && _odomCameraOpenNICv == 0); UASSERT(_odomThread == 0 && _cameraThread == 0);
if(this->getSourceRGBD() == kSrcFreenect) CameraRGBD * camera = 0;
if(this->getSourceRGBD() == kSrcOpenNI_PCL)
{ {
_odomCameraFreenect = new CameraFreenect( camera = new CameraOpenni(
this->getSourceOpenniDevice().isEmpty()?0:atoi(this->getSourceOpenniDevice().toStdString().c_str()),
this->getGeneralInputRate(),
this->getSourceOpenniLocalTransform());
if(!_odomCameraFreenect->init())
{
if(!_odomCameraFreenect->available())
{
QMessageBox::warning(this,
tr("RTAB-Map"),
tr("Freenect camera unavailable! RTAB-Map is not built with Freenect support (libfreenect)."));
}
else
{
QMessageBox::warning(this,
tr("RTAB-Map"),
tr("Freenect camera initialization failed!"));
}
delete _odomCameraFreenect;
_odomCameraFreenect = 0;
}
}
else if(this->getSourceRGBD() == kSrcOpenNI_CV ||
this->getSourceRGBD() == kSrcOpenNI_CV_ASUS ||
this->getSourceRGBD() == kSrcOpenNI2)
{
Camera * camera = 0;
if(this->getSourceRGBD() == kSrcOpenNI2)
{
camera = new CameraOpenNI2(
this->getGeneralInputRate());
}
else
{
camera = new CameraRGBD(
this->getGeneralInputRate(),
this->getSourceRGBD() == kSrcOpenNI_CV_ASUS);
}
camera->setLocalTransform(this->getSourceOpenniLocalTransform());
_odomCameraOpenNICv = new CameraThread(camera);
if(!_odomCameraOpenNICv->init())
{
QMessageBox::warning(this,
tr("RTAB-Map"),
tr("OpenNI-CV camera initialization failed!"));
delete _odomCameraOpenNICv;
_odomCameraOpenNICv = 0;
}
}
else
{
_odomCameraOpenNI = new CameraOpenni(
this->getSourceOpenniDevice().toStdString(), this->getSourceOpenniDevice().toStdString(),
this->getGeneralInputRate(), this->getGeneralInputRate(),
this->getSourceOpenniLocalTransform()); this->getSourceOpenniLocalTransform());
if(!_odomCameraOpenNI->init()) }
else if(this->getSourceRGBD() == kSrcOpenNI2)
{
camera = new CameraOpenNI2(
this->getGeneralInputRate(),
this->getSourceOpenniLocalTransform());
}
else if(this->getSourceRGBD() == kSrcFreenect)
{
camera = new CameraFreenect(
this->getSourceOpenniDevice().isEmpty()?0:atoi(this->getSourceOpenniDevice().toStdString().c_str()),
this->getGeneralInputRate(),
this->getSourceOpenniLocalTransform());
}
else if(this->getSourceRGBD() == kSrcOpenNI_CV || this->getSourceRGBD() == kSrcOpenNI_CV_ASUS)
{
camera = new CameraOpenNICV(
this->getSourceRGBD() == kSrcOpenNI_CV_ASUS,
this->getGeneralInputRate(),
this->getSourceOpenniLocalTransform());
}
else
{
UFATAL("RGBD Source type undefined!");
}
if(!camera->init())
{ {
QMessageBox::warning(this, QMessageBox::warning(this,
tr("RTAB-Map"), tr("RTAB-Map"),
tr("OpenNI camera initialization failed!")); tr("RGBD camera initialization failed!"));
delete _odomCameraOpenNI; delete camera;
_odomCameraOpenNI = 0; camera = 0;
}
} }
if(_odomCameraOpenNI || _odomCameraFreenect || _odomCameraOpenNICv)
if(camera)
{ {
Odometry * odometry; Odometry * odometry;
ParametersMap parameters = this->getAllParameters(); ParametersMap parameters = this->getAllParameters();
@@ -2841,18 +2781,8 @@ void PreferencesDialog::testOdometry(OdomType type)
UEventsManager::addHandler(_odomThread); UEventsManager::addHandler(_odomThread);
UEventsManager::addHandler(odomViewer); UEventsManager::addHandler(odomViewer);
if(_odomCameraFreenect) _cameraThread = new CameraThread(camera);
{ UEventsManager::createPipe(_cameraThread, _odomThread, "CameraEvent");
UEventsManager::createPipe(_odomCameraFreenect, _odomThread, "CameraEvent");
}
else if(_odomCameraOpenNICv)
{
UEventsManager::createPipe(_odomCameraOpenNICv, _odomThread, "CameraEvent");
}
else
{
UEventsManager::createPipe(_odomCameraOpenNI, _odomThread, "CameraEvent");
}
UEventsManager::createPipe(_odomThread, odomViewer, "OdometryEvent"); UEventsManager::createPipe(_odomThread, odomViewer, "OdometryEvent");
window->showNormal(); window->showNormal();
@@ -2862,41 +2792,18 @@ void PreferencesDialog::testOdometry(OdomType type)
QApplication::processEvents(); QApplication::processEvents();
_odomThread->start(); _odomThread->start();
if(_odomCameraFreenect) _cameraThread->start();
{
_odomCameraFreenect->start();
}
else if(_odomCameraOpenNICv)
{
_odomCameraOpenNICv->start();
}
else
{
_odomCameraOpenNI->start();
}
} }
} }
void PreferencesDialog::cleanOdometryTest() void PreferencesDialog::cleanOdometryTest()
{ {
UDEBUG(""); UDEBUG("");
if(_odomCameraOpenNI) if(_cameraThread)
{ {
_odomCameraOpenNI->kill(); _cameraThread->join(true);
delete _odomCameraOpenNI; delete _cameraThread;
_odomCameraOpenNI = 0; _cameraThread = 0;
}
if(_odomCameraFreenect)
{
_odomCameraFreenect->join(true);
delete _odomCameraFreenect;
_odomCameraFreenect = 0;
}
if(_odomCameraOpenNICv)
{
_odomCameraOpenNICv->join(true);
delete _odomCameraOpenNICv;
_odomCameraOpenNICv = 0;
} }
if(_odomThread) if(_odomThread)
{ {

View File

@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>908</width> <width>908</width>
<height>406</height> <height>494</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@@ -63,9 +63,9 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>-331</y> <y>0</y>
<width>609</width> <width>707</width>
<height>657</height> <height>752</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_16"> <layout class="QVBoxLayout" name="verticalLayout_16">
@@ -1363,21 +1363,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<widget class="QCheckBox" name="general_checkBox_autoRestart">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="1"> <item row="1" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Auto restart.</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_10"> <widget class="QLabel" name="label_10">
<property name="text"> <property name="text">
<string>Image width (set to 0 to use the default size of the source).</string> <string>Image width (set to 0 to use the default size of the source).</string>
@@ -1387,7 +1373,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="2" column="1">
<widget class="QLabel" name="label_11"> <widget class="QLabel" name="label_11">
<property name="text"> <property name="text">
<string>Image height (set to 0 to use the default size of the source).</string> <string>Image height (set to 0 to use the default size of the source).</string>
@@ -1397,7 +1383,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="1" column="0">
<widget class="QSpinBox" name="source_spinBox_imgWidth"> <widget class="QSpinBox" name="source_spinBox_imgWidth">
<property name="minimum"> <property name="minimum">
<number>0</number> <number>0</number>
@@ -1413,7 +1399,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="2" column="0">
<widget class="QSpinBox" name="source_spinBox_imgheight"> <widget class="QSpinBox" name="source_spinBox_imgheight">
<property name="minimum"> <property name="minimum">
<number>0</number> <number>0</number>
@@ -1429,46 +1415,6 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0">
<widget class="QCheckBox" name="general_checkBox_cameraKeypoints">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Keypoints extraction post threatement.</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_128">
<property name="text">
<string>Frames dropped (ignore X frames after each frame acquired, used to decrease source framerate)</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QSpinBox" name="source_spinBox_framesDropped">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>999999999</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>

View File

@@ -50,7 +50,6 @@ void showUsage()
" The height must be also specified if changed.\n" " The height must be also specified if changed.\n"
" -image_height # Force an image height (Default 0: original size used)\n" " -image_height # Force an image height (Default 0: original size used)\n"
" The height must be also specified if changed.\n" " The height must be also specified if changed.\n"
" -frames_dropped # Frames dropped from source (Default 0: no frames dropped)\n"
" -start_at # When \"path\" is a directory of images, set this parameter\n" " -start_at # When \"path\" is a directory of images, set this parameter\n"
" to start processing at image # (default 1)." " to start processing at image # (default 1)."
" -\"parameter name\" \"value\" Overwrite a specific RTAB-Map's parameter :\n" " -\"parameter name\" \"value\" Overwrite a specific RTAB-Map's parameter :\n"
@@ -114,7 +113,6 @@ int main(int argc, char * argv[])
int imageWidth = 0; int imageWidth = 0;
int imageHeight = 0; int imageHeight = 0;
int startAt = 1; int startAt = 1;
int framesDropped = 0;
ParametersMap pm; ParametersMap pm;
ULogger::Level logLevel = ULogger::kError; ULogger::Level logLevel = ULogger::kError;
ULogger::Level exitLevel = ULogger::kFatal; ULogger::Level exitLevel = ULogger::kFatal;
@@ -239,23 +237,6 @@ int main(int argc, char * argv[])
} }
continue; continue;
} }
if(strcmp(argv[i], "-frames_dropped") == 0)
{
++i;
if(i < argc)
{
framesDropped = std::atoi(argv[i]);
if(framesDropped < 0)
{
showUsage();
}
}
else
{
showUsage();
}
continue;
}
if(strcmp(argv[i], "-start_at") == 0) if(strcmp(argv[i], "-start_at") == 0)
{ {
++i; ++i;
@@ -357,11 +338,11 @@ int main(int argc, char * argv[])
Camera * camera = 0; Camera * camera = 0;
if(UDirectory::exists(path)) if(UDirectory::exists(path))
{ {
camera = new CameraImages(path, startAt, false, 1/rate, imageWidth, imageHeight, framesDropped); camera = new CameraImages(path, startAt, false, 1/rate, imageWidth, imageHeight);
} }
else else
{ {
camera = new CameraVideo(path, 1/rate, imageWidth, imageHeight, framesDropped); camera = new CameraVideo(path, 1/rate, imageWidth, imageHeight);
} }
if(!camera || !camera->init()) if(!camera || !camera->init())
@@ -402,7 +383,6 @@ int main(int argc, char * argv[])
printf(" Repeating data set = %s\n", repeat?"true":"false"); printf(" Repeating data set = %s\n", repeat?"true":"false");
printf(" Camera width=%d, height=%d (0 is default)\n", imageWidth, imageHeight); printf(" Camera width=%d, height=%d (0 is default)\n", imageWidth, imageHeight);
printf(" Camera starts at image %d (default 1)\n", startAt); printf(" Camera starts at image %d (default 1)\n", startAt);
printf(" Camera frames dropped %d (default 0)\n", framesDropped);
if(createGT) if(createGT)
{ {
printf(" Creating the ground truth matrix.\n"); printf(" Creating the ground truth matrix.\n");

View File

@@ -1,7 +1,8 @@
#include <rtabmap/utilite/ULogger.h> #include <rtabmap/utilite/ULogger.h>
#include <rtabmap/utilite/UFile.h> #include <rtabmap/utilite/UFile.h>
#include <rtabmap/core/CameraOpenni.h> #include <rtabmap/core/CameraThread.h>
#include <rtabmap/core/CameraRGBD.h>
#include <rtabmap/core/Camera.h> #include <rtabmap/core/Camera.h>
#include <rtabmap/core/CameraThread.h> #include <rtabmap/core/CameraThread.h>
#include <rtabmap/gui/DataRecorder.h> #include <rtabmap/gui/DataRecorder.h>
@@ -22,17 +23,12 @@ void showUsage()
exit(1); exit(1);
} }
rtabmap::CameraOpenni * openniCamera = 0;
rtabmap::CameraThread * cam = 0; rtabmap::CameraThread * cam = 0;
QApplication * app = 0; QApplication * app = 0;
// catch ctrl-c // catch ctrl-c
void sighandler(int sig) void sighandler(int sig)
{ {
printf("\nSignal %d caught...\n", sig); printf("\nSignal %d caught...\n", sig);
if(openniCamera)
{
openniCamera->kill();
}
if(cam) if(cam)
{ {
cam->join(true); cam->join(true);
@@ -119,7 +115,7 @@ int main (int argc, char * argv[])
if(openni) if(openni)
{ {
openniCamera = new rtabmap::CameraOpenni("", rate, rtabmap::Transform(0,0,1,0, -1,0,0,0, 0,-1,0,0)); cam = new rtabmap::CameraThread(new rtabmap::CameraOpenni("", rate, rtabmap::Transform(0,0,1,0, -1,0,0,0, 0,-1,0,0)));
} }
else else
{ {
@@ -140,9 +136,9 @@ int main (int argc, char * argv[])
app->processEvents(); app->processEvents();
} }
if(openni?openniCamera->init():cam->init()) if(cam->init())
{ {
openni?openniCamera->start():cam->start(); cam->start();
app->exec(); app->exec();
@@ -160,10 +156,6 @@ int main (int argc, char * argv[])
UERROR("Cannot initialize the recorder! Maybe the path is wrong: \"%s\"", fileName.toStdString().c_str()); UERROR("Cannot initialize the recorder! Maybe the path is wrong: \"%s\"", fileName.toStdString().c_str());
} }
if(openniCamera)
{
delete openniCamera;
}
if(cam) if(cam)
{ {
delete cam; delete cam;

View File

@@ -4,7 +4,8 @@
#include <rtabmap/utilite/UFile.h> #include <rtabmap/utilite/UFile.h>
#include <rtabmap/core/Odometry.h> #include <rtabmap/core/Odometry.h>
#include <rtabmap/gui/OdometryViewer.h> #include <rtabmap/gui/OdometryViewer.h>
#include <rtabmap/core/CameraOpenni.h> #include <rtabmap/core/CameraThread.h>
#include <rtabmap/core/CameraRGBD.h>
#include <rtabmap/core/DBReader.h> #include <rtabmap/core/DBReader.h>
#include <QtGui/QApplication> #include <QtGui/QApplication>
@@ -555,7 +556,7 @@ int main (int argc, char * argv[])
} }
else else
{ {
rtabmap::CameraOpenni camera("", rate, rtabmap::Transform(0,0,1,0, -1,0,0,0, 0,-1,0,0)); rtabmap::CameraThread camera(new rtabmap::CameraOpenni("", rate, rtabmap::Transform(0,0,1,0, -1,0,0,0, 0,-1,0,0)));
if(camera.init()) if(camera.init())
{ {
odomThread.start(); odomThread.start();