mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
Added OpenNI2 and Freenect calibration #115
This commit is contained in:
@@ -155,9 +155,11 @@ class RTABMAP_EXP CameraOpenNI2 :
|
|||||||
public:
|
public:
|
||||||
static bool available();
|
static bool available();
|
||||||
static bool exposureGainAvailable();
|
static bool exposureGainAvailable();
|
||||||
|
enum Type {kTypeColorDepth, kTypeIRDepth, kTypeIR};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CameraOpenNI2(const std::string & deviceId = "",
|
CameraOpenNI2(const std::string & deviceId = "",
|
||||||
|
Type type = kTypeColorDepth,
|
||||||
float imageRate = 0,
|
float imageRate = 0,
|
||||||
const Transform & localTransform = Transform::getIdentity());
|
const Transform & localTransform = Transform::getIdentity());
|
||||||
virtual ~CameraOpenNI2();
|
virtual ~CameraOpenNI2();
|
||||||
@@ -177,6 +179,7 @@ protected:
|
|||||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
virtual SensorData captureImage(CameraInfo * info = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Type _type;
|
||||||
openni::Device * _device;
|
openni::Device * _device;
|
||||||
openni::VideoStream * _color;
|
openni::VideoStream * _color;
|
||||||
openni::VideoStream * _depth;
|
openni::VideoStream * _depth;
|
||||||
@@ -184,6 +187,7 @@ private:
|
|||||||
float _depthFy;
|
float _depthFy;
|
||||||
std::string _deviceId;
|
std::string _deviceId;
|
||||||
bool _openNI2StampsAndIDsUsed;
|
bool _openNI2StampsAndIDsUsed;
|
||||||
|
StereoCameraModel _stereoModel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -197,10 +201,12 @@ class RTABMAP_EXP CameraFreenect :
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static bool available();
|
static bool available();
|
||||||
|
enum Type {kTypeColorDepth, kTypeIRDepth};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// default local transform z in, x right, y down));
|
// default local transform z in, x right, y down));
|
||||||
CameraFreenect(int deviceId= 0,
|
CameraFreenect(int deviceId= 0,
|
||||||
|
Type type = kTypeColorDepth,
|
||||||
float imageRate=0.0f,
|
float imageRate=0.0f,
|
||||||
const Transform & localTransform = Transform::getIdentity());
|
const Transform & localTransform = Transform::getIdentity());
|
||||||
virtual ~CameraFreenect();
|
virtual ~CameraFreenect();
|
||||||
@@ -214,8 +220,10 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int deviceId_;
|
int deviceId_;
|
||||||
|
Type type_;
|
||||||
freenect_context * ctx_;
|
freenect_context * ctx_;
|
||||||
FreenectDevice * freenectDevice_;
|
FreenectDevice * freenectDevice_;
|
||||||
|
StereoCameraModel stereoModel_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ public:
|
|||||||
|
|
||||||
void initRectificationMap() {left_.initRectificationMap(); right_.initRectificationMap();}
|
void initRectificationMap() {left_.initRectificationMap(); right_.initRectificationMap();}
|
||||||
|
|
||||||
void setName(const std::string & name);
|
void setName(const std::string & name, const std::string & leftSuffix = "left", const std::string & rightSuffix = "right");
|
||||||
const std::string & name() const {return name_;}
|
const std::string & name() const {return name_;}
|
||||||
|
|
||||||
// backward compatibility
|
// backward compatibility
|
||||||
@@ -95,6 +95,7 @@ public:
|
|||||||
|
|
||||||
bool load(const std::string & directory, const std::string & cameraName, bool ignoreStereoTransform = true);
|
bool load(const std::string & directory, const std::string & cameraName, bool ignoreStereoTransform = true);
|
||||||
bool save(const std::string & directory, bool ignoreStereoTransform = true) const;
|
bool save(const std::string & directory, bool ignoreStereoTransform = true) const;
|
||||||
|
bool saveStereoTransform(const std::string & directory) const;
|
||||||
|
|
||||||
double baseline() const {return right_.fx()!=0.0?-right_.Tx()/right_.fx():0.0;}
|
double baseline() const {return right_.fx()!=0.0?-right_.Tx()/right_.fx():0.0;}
|
||||||
|
|
||||||
@@ -117,7 +118,12 @@ public:
|
|||||||
const CameraModel & left() const {return left_;}
|
const CameraModel & left() const {return left_;}
|
||||||
const CameraModel & right() const {return right_;}
|
const CameraModel & right() const {return right_;}
|
||||||
|
|
||||||
|
const std::string & getLeftSuffix() const {return leftSuffix_;}
|
||||||
|
const std::string & getRightSuffix() const {return rightSuffix_;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::string leftSuffix_;
|
||||||
|
std::string rightSuffix_;
|
||||||
CameraModel left_;
|
CameraModel left_;
|
||||||
CameraModel right_;
|
CameraModel right_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ cv::Mat RTABMAP_EXP interpolate(const cv::Mat & image, int factor, float depthEr
|
|||||||
cv::Mat RTABMAP_EXP registerDepth(
|
cv::Mat RTABMAP_EXP registerDepth(
|
||||||
const cv::Mat & depth,
|
const cv::Mat & depth,
|
||||||
const cv::Mat & depthK,
|
const cv::Mat & depthK,
|
||||||
|
const cv::Size & colorSize,
|
||||||
const cv::Mat & colorK,
|
const cv::Mat & colorK,
|
||||||
const rtabmap::Transform & transform);
|
const rtabmap::Transform & transform);
|
||||||
|
|
||||||
|
|||||||
@@ -213,9 +213,9 @@ SensorData CameraOpenni::captureImage(CameraInfo * info)
|
|||||||
#ifdef HAVE_OPENNI
|
#ifdef HAVE_OPENNI
|
||||||
if(interface_ && interface_->isRunning())
|
if(interface_ && interface_->isRunning())
|
||||||
{
|
{
|
||||||
if(!dataReady_.acquire(1, 2000))
|
if(!dataReady_.acquire(1, 5000))
|
||||||
{
|
{
|
||||||
UWARN("Not received new frames since 2 seconds, end of stream reached!");
|
UWARN("Not received new frames since 5 seconds, end of stream reached!");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -379,9 +379,11 @@ bool CameraOpenNI2::exposureGainAvailable()
|
|||||||
|
|
||||||
CameraOpenNI2::CameraOpenNI2(
|
CameraOpenNI2::CameraOpenNI2(
|
||||||
const std::string & deviceId,
|
const std::string & deviceId,
|
||||||
|
Type type,
|
||||||
float imageRate,
|
float imageRate,
|
||||||
const rtabmap::Transform & localTransform) :
|
const rtabmap::Transform & localTransform) :
|
||||||
Camera(imageRate, localTransform),
|
Camera(imageRate, localTransform),
|
||||||
|
_type(type),
|
||||||
#ifdef RTABMAP_OPENNI2
|
#ifdef RTABMAP_OPENNI2
|
||||||
_device(new openni::Device()),
|
_device(new openni::Device()),
|
||||||
_color(new openni::VideoStream()),
|
_color(new openni::VideoStream()),
|
||||||
@@ -491,21 +493,81 @@ bool CameraOpenNI2::init(const std::string & calibrationFolder, const std::strin
|
|||||||
#ifdef RTABMAP_OPENNI2
|
#ifdef RTABMAP_OPENNI2
|
||||||
openni::OpenNI::initialize();
|
openni::OpenNI::initialize();
|
||||||
|
|
||||||
if(_device->open(_deviceId.empty()?openni::ANY_DEVICE:_deviceId.c_str()) != openni::STATUS_OK)
|
openni::Array<openni::DeviceInfo> devices;
|
||||||
|
openni::OpenNI::enumerateDevices(&devices);
|
||||||
|
for(int i=0; i<devices.getSize(); ++i)
|
||||||
|
{
|
||||||
|
UINFO("Device %d: Name=%s URI=%s Vendor=%s",
|
||||||
|
i,
|
||||||
|
devices[i].getName(),
|
||||||
|
devices[i].getUri(),
|
||||||
|
devices[i].getVendor());
|
||||||
|
}
|
||||||
|
if(_deviceId.empty() && devices.getSize() == 0)
|
||||||
|
{
|
||||||
|
UERROR("CameraOpenNI2: No device detected!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
openni::Status error = _device->open(_deviceId.empty()?openni::ANY_DEVICE:_deviceId.c_str());
|
||||||
|
if(error != openni::STATUS_OK)
|
||||||
{
|
{
|
||||||
if(!_deviceId.empty())
|
if(!_deviceId.empty())
|
||||||
{
|
{
|
||||||
UERROR("CameraOpenNI2: Cannot open device \"%s\".", _deviceId.c_str());
|
UERROR("CameraOpenNI2: Cannot open device \"%s\" (error=%d).", _deviceId.c_str(), error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UERROR("CameraOpenNI2: Cannot open device.");
|
#ifdef _WIN32
|
||||||
|
UERROR("CameraOpenNI2: Cannot open device \"%s\" with uri=\"%s\" (error=%d).", devices[0].getName(), devices[0].uri, error);
|
||||||
|
#else
|
||||||
|
UERROR("CameraOpenNI2: Cannot open device \"%s\" (error=%d). Verify if \"%s\" is in udev rules: \"/lib/udev/rules.d/40-libopenni2-0.rules\". If not, add it and reboot.", devices[0].getName(), error, devices[0].getUri());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
_device->close();
|
_device->close();
|
||||||
openni::OpenNI::shutdown();
|
openni::OpenNI::shutdown();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// look for calibration files
|
||||||
|
_stereoModel = StereoCameraModel();
|
||||||
|
bool hardwareRegistration = true;
|
||||||
|
if(!calibrationFolder.empty())
|
||||||
|
{
|
||||||
|
// we need the serial
|
||||||
|
std::string calibrationName = _device->getDeviceInfo().getName();
|
||||||
|
if(!cameraName.empty())
|
||||||
|
{
|
||||||
|
calibrationName = cameraName;
|
||||||
|
}
|
||||||
|
_stereoModel.setName(calibrationName, "depth", "rgb");
|
||||||
|
hardwareRegistration = !_stereoModel.load(calibrationFolder, calibrationName, false);
|
||||||
|
|
||||||
|
if(_type != kTypeColorDepth)
|
||||||
|
{
|
||||||
|
hardwareRegistration = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if((_type != kTypeColorDepth && !_stereoModel.left().isValidForRectification()) ||
|
||||||
|
(_type == kTypeColorDepth && !_stereoModel.right().isValidForRectification()))
|
||||||
|
{
|
||||||
|
UWARN("Missing calibration files for camera \"%s\" in \"%s\" folder, default calibration used.",
|
||||||
|
calibrationName.c_str(), calibrationFolder.c_str());
|
||||||
|
}
|
||||||
|
else if(_type == kTypeColorDepth && _stereoModel.right().isValidForRectification() && hardwareRegistration)
|
||||||
|
{
|
||||||
|
UWARN("Missing extrinsic calibration file for camera \"%s\" in \"%s\" folder, default registration is used even if rgb is rectified!",
|
||||||
|
calibrationName.c_str(), calibrationFolder.c_str());
|
||||||
|
}
|
||||||
|
else if(_type == kTypeColorDepth && _stereoModel.right().isValidForRectification() && !hardwareRegistration)
|
||||||
|
{
|
||||||
|
UINFO("Custom calibration files for \"%s\" were found in \"%s\" folder. To use "
|
||||||
|
"factory calibration, remove the corresponding files from that directory.", calibrationName.c_str(), calibrationFolder.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(UFile::getExtension(_deviceId).compare("oni")==0)
|
if(UFile::getExtension(_deviceId).compare("oni")==0)
|
||||||
{
|
{
|
||||||
if(_device->getPlaybackControl() &&
|
if(_device->getPlaybackControl() &&
|
||||||
@@ -517,7 +579,8 @@ bool CameraOpenNI2::init(const std::string & calibrationFolder, const std::strin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!_device->isImageRegistrationModeSupported(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR))
|
else if(_type==kTypeColorDepth && hardwareRegistration &&
|
||||||
|
!_device->isImageRegistrationModeSupported(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR))
|
||||||
{
|
{
|
||||||
UERROR("CameraOpenNI2: Device doesn't support depth/color registration.");
|
UERROR("CameraOpenNI2: Device doesn't support depth/color registration.");
|
||||||
_device->close();
|
_device->close();
|
||||||
@@ -526,9 +589,9 @@ bool CameraOpenNI2::init(const std::string & calibrationFolder, const std::strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(_device->getSensorInfo(openni::SENSOR_DEPTH) == NULL ||
|
if(_device->getSensorInfo(openni::SENSOR_DEPTH) == NULL ||
|
||||||
_device->getSensorInfo(openni::SENSOR_COLOR) == NULL)
|
_device->getSensorInfo(_type==kTypeColorDepth?openni::SENSOR_COLOR:openni::SENSOR_IR) == NULL)
|
||||||
{
|
{
|
||||||
UERROR("CameraOpenNI2: Cannot get sensor info for depth and color.");
|
UERROR("CameraOpenNI2: Cannot get sensor info for depth and %s.", _type==kTypeColorDepth?"color":"ir");
|
||||||
_device->close();
|
_device->close();
|
||||||
openni::OpenNI::shutdown();
|
openni::OpenNI::shutdown();
|
||||||
return false;
|
return false;
|
||||||
@@ -542,16 +605,17 @@ bool CameraOpenNI2::init(const std::string & calibrationFolder, const std::strin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_color->create(*_device, openni::SENSOR_COLOR) != openni::STATUS_OK)
|
if(_color->create(*_device, _type==kTypeColorDepth?openni::SENSOR_COLOR:openni::SENSOR_IR) != openni::STATUS_OK)
|
||||||
{
|
{
|
||||||
UERROR("CameraOpenNI2: Cannot create color stream.");
|
UERROR("CameraOpenNI2: Cannot create %s stream.", _type==kTypeColorDepth?"color":"ir");
|
||||||
_depth->destroy();
|
_depth->destroy();
|
||||||
_device->close();
|
_device->close();
|
||||||
openni::OpenNI::shutdown();
|
openni::OpenNI::shutdown();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_device->setImageRegistrationMode(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR ) != openni::STATUS_OK)
|
if(_type==kTypeColorDepth && hardwareRegistration &&
|
||||||
|
_device->setImageRegistrationMode(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR ) != openni::STATUS_OK)
|
||||||
{
|
{
|
||||||
UERROR("CameraOpenNI2: Failed to set depth/color registration.");
|
UERROR("CameraOpenNI2: Failed to set depth/color registration.");
|
||||||
}
|
}
|
||||||
@@ -578,7 +642,8 @@ bool CameraOpenNI2::init(const std::string & calibrationFolder, const std::strin
|
|||||||
const openni::Array<openni::VideoMode>& colorVideoModes = _color->getSensorInfo().getSupportedVideoModes();
|
const openni::Array<openni::VideoMode>& colorVideoModes = _color->getSensorInfo().getSupportedVideoModes();
|
||||||
for(int i=0; i<colorVideoModes.getSize(); ++i)
|
for(int i=0; i<colorVideoModes.getSize(); ++i)
|
||||||
{
|
{
|
||||||
UINFO("CameraOpenNI2: Color video mode %d: fps=%d, pixel=%d, w=%d, h=%d",
|
UINFO("CameraOpenNI2: %s video mode %d: fps=%d, pixel=%d, w=%d, h=%d",
|
||||||
|
_type==kTypeColorDepth?"color":"ir",
|
||||||
i,
|
i,
|
||||||
colorVideoModes[i].getFps(),
|
colorVideoModes[i].getFps(),
|
||||||
colorVideoModes[i].getPixelFormat(),
|
colorVideoModes[i].getPixelFormat(),
|
||||||
@@ -605,6 +670,40 @@ bool CameraOpenNI2::init(const std::string & calibrationFolder, const std::strin
|
|||||||
_depth->getVideoMode().getResolutionY(),
|
_depth->getVideoMode().getResolutionY(),
|
||||||
_depth->getHorizontalFieldOfView(),
|
_depth->getHorizontalFieldOfView(),
|
||||||
_depth->getVerticalFieldOfView());
|
_depth->getVerticalFieldOfView());
|
||||||
|
UINFO("CameraOpenNI2: Using %s video mode: fps=%d, pixel=%d, w=%d, h=%d, H-FOV=%f rad, V-FOV=%f rad",
|
||||||
|
_type==kTypeColorDepth?"color":"ir",
|
||||||
|
_color->getVideoMode().getFps(),
|
||||||
|
_color->getVideoMode().getPixelFormat(),
|
||||||
|
_color->getVideoMode().getResolutionX(),
|
||||||
|
_color->getVideoMode().getResolutionY(),
|
||||||
|
_color->getHorizontalFieldOfView(),
|
||||||
|
_color->getVerticalFieldOfView());
|
||||||
|
|
||||||
|
if(_depth->getVideoMode().getResolutionX() != 640 ||
|
||||||
|
_depth->getVideoMode().getResolutionY() != 480 ||
|
||||||
|
_depth->getVideoMode().getPixelFormat() != openni::PIXEL_FORMAT_DEPTH_1_MM)
|
||||||
|
{
|
||||||
|
UERROR("Could not set depth format to 640x480 pixel=%d(mm)!",
|
||||||
|
openni::PIXEL_FORMAT_DEPTH_1_MM);
|
||||||
|
_depth->destroy();
|
||||||
|
_color->destroy();
|
||||||
|
_device->close();
|
||||||
|
openni::OpenNI::shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(_color->getVideoMode().getResolutionX() != 640 ||
|
||||||
|
_color->getVideoMode().getResolutionY() != 480 ||
|
||||||
|
_color->getVideoMode().getPixelFormat() != openni::PIXEL_FORMAT_RGB888)
|
||||||
|
{
|
||||||
|
UERROR("Could not set %s format to 640x480 pixel=%d!",
|
||||||
|
_type==kTypeColorDepth?"color":"ir",
|
||||||
|
openni::PIXEL_FORMAT_RGB888);
|
||||||
|
_depth->destroy();
|
||||||
|
_color->destroy();
|
||||||
|
_device->close();
|
||||||
|
openni::OpenNI::shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(_color->getCameraSettings())
|
if(_color->getCameraSettings())
|
||||||
{
|
{
|
||||||
@@ -616,8 +715,7 @@ bool CameraOpenNI2::init(const std::string & calibrationFolder, const std::strin
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool registered = true;
|
if(_type==kTypeColorDepth && hardwareRegistration)
|
||||||
if(registered)
|
|
||||||
{
|
{
|
||||||
_depthFx = float(_color->getVideoMode().getResolutionX()/2) / std::tan(_color->getHorizontalFieldOfView()/2.0f);
|
_depthFx = float(_color->getVideoMode().getResolutionX()/2) / std::tan(_color->getHorizontalFieldOfView()/2.0f);
|
||||||
_depthFy = float(_color->getVideoMode().getResolutionY()/2) / std::tan(_color->getVerticalFieldOfView()/2.0f);
|
_depthFy = float(_color->getVideoMode().getResolutionY()/2) / std::tan(_color->getVerticalFieldOfView()/2.0f);
|
||||||
@@ -629,16 +727,13 @@ bool CameraOpenNI2::init(const std::string & calibrationFolder, const std::strin
|
|||||||
}
|
}
|
||||||
UINFO("depth fx=%f fy=%f", _depthFx, _depthFy);
|
UINFO("depth fx=%f fy=%f", _depthFx, _depthFy);
|
||||||
|
|
||||||
UINFO("CameraOpenNI2: Using color video mode: fps=%d, pixel=%d, w=%d, h=%d, H-FOV=%f rad, V-FOV=%f rad",
|
if(_type == kTypeIR)
|
||||||
_color->getVideoMode().getFps(),
|
{
|
||||||
_color->getVideoMode().getPixelFormat(),
|
UWARN("With type IR-only, depth stream will not be started");
|
||||||
_color->getVideoMode().getResolutionX(),
|
}
|
||||||
_color->getVideoMode().getResolutionY(),
|
|
||||||
_color->getHorizontalFieldOfView(),
|
|
||||||
_color->getVerticalFieldOfView());
|
|
||||||
|
|
||||||
if(_depth->start() != openni::STATUS_OK ||
|
if((_type != kTypeIR && _depth->start() != openni::STATUS_OK) ||
|
||||||
_color->start() != openni::STATUS_OK)
|
_color->start() != openni::STATUS_OK)
|
||||||
{
|
{
|
||||||
UERROR("CameraOpenNI2: Cannot start depth and/or color streams.");
|
UERROR("CameraOpenNI2: Cannot start depth and/or color streams.");
|
||||||
_depth->stop();
|
_depth->stop();
|
||||||
@@ -650,7 +745,7 @@ bool CameraOpenNI2::init(const std::string & calibrationFolder, const std::strin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uSleep(1000); // just to make sure the sensor is correctly initialized
|
uSleep(3000); // just to make sure the sensor is correctly initialized and exposure is set
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
@@ -684,35 +779,49 @@ SensorData CameraOpenNI2::captureImage(CameraInfo * info)
|
|||||||
_depth->isValid() &&
|
_depth->isValid() &&
|
||||||
_color->isValid() &&
|
_color->isValid() &&
|
||||||
_device->getSensorInfo(openni::SENSOR_DEPTH) != NULL &&
|
_device->getSensorInfo(openni::SENSOR_DEPTH) != NULL &&
|
||||||
_device->getSensorInfo(openni::SENSOR_COLOR) != NULL)
|
_device->getSensorInfo(_type==kTypeColorDepth?openni::SENSOR_COLOR:openni::SENSOR_IR) != NULL)
|
||||||
{
|
{
|
||||||
openni::VideoStream* depthStream[] = {_depth};
|
openni::VideoStream* depthStream[] = {_depth};
|
||||||
openni::VideoStream* colorStream[] = {_color};
|
openni::VideoStream* colorStream[] = {_color};
|
||||||
if(openni::OpenNI::waitForAnyStream(depthStream, 1, &readyStream, 2000) != openni::STATUS_OK ||
|
if((_type != kTypeIR && openni::OpenNI::waitForAnyStream(depthStream, 1, &readyStream, 5000) != openni::STATUS_OK) ||
|
||||||
openni::OpenNI::waitForAnyStream(colorStream, 1, &readyStream, 2000) != openni::STATUS_OK)
|
openni::OpenNI::waitForAnyStream(colorStream, 1, &readyStream, 5000) != openni::STATUS_OK)
|
||||||
{
|
{
|
||||||
UWARN("No frames received since the last 2 seconds, end of stream is reached!");
|
UWARN("No frames received since the last 5 seconds, end of stream is reached!");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
openni::VideoFrameRef depthFrame, colorFrame;
|
openni::VideoFrameRef depthFrame, colorFrame;
|
||||||
_depth->readFrame(&depthFrame);
|
if(_type != kTypeIR)
|
||||||
|
{
|
||||||
|
_depth->readFrame(&depthFrame);
|
||||||
|
}
|
||||||
_color->readFrame(&colorFrame);
|
_color->readFrame(&colorFrame);
|
||||||
cv::Mat depth, rgb;
|
cv::Mat depth, rgb;
|
||||||
if(depthFrame.isValid() && colorFrame.isValid())
|
if((_type == kTypeIR || depthFrame.isValid()) && colorFrame.isValid())
|
||||||
{
|
{
|
||||||
int h=depthFrame.getHeight();
|
int h,w;
|
||||||
int w=depthFrame.getWidth();
|
if(_type != kTypeIR)
|
||||||
depth = cv::Mat(h, w, CV_16U, (void*)depthFrame.getData()).clone();
|
{
|
||||||
|
h=depthFrame.getHeight();
|
||||||
|
w=depthFrame.getWidth();
|
||||||
|
depth = cv::Mat(h, w, CV_16U, (void*)depthFrame.getData()).clone();
|
||||||
|
}
|
||||||
h=colorFrame.getHeight();
|
h=colorFrame.getHeight();
|
||||||
w=colorFrame.getWidth();
|
w=colorFrame.getWidth();
|
||||||
cv::Mat tmp(h, w, CV_8UC3, (void *)colorFrame.getData());
|
cv::Mat tmp(h, w, CV_8UC3, (void *)colorFrame.getData());
|
||||||
cv::cvtColor(tmp, rgb, CV_RGB2BGR);
|
if(_type==kTypeColorDepth)
|
||||||
|
{
|
||||||
|
cv::cvtColor(tmp, rgb, CV_RGB2BGR);
|
||||||
|
}
|
||||||
|
else // IR
|
||||||
|
{
|
||||||
|
rgb = tmp.clone();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
UASSERT(_depthFx != 0.0f && _depthFy != 0.0f);
|
UASSERT(_depthFx != 0.0f && _depthFy != 0.0f);
|
||||||
if(!rgb.empty() && !depth.empty())
|
if(!rgb.empty() && (_type == kTypeIR || !depth.empty()))
|
||||||
{
|
{
|
||||||
|
// default calibration
|
||||||
CameraModel model(
|
CameraModel model(
|
||||||
_depthFx, //fx
|
_depthFx, //fx
|
||||||
_depthFy, //fy
|
_depthFy, //fy
|
||||||
@@ -721,6 +830,35 @@ SensorData CameraOpenNI2::captureImage(CameraInfo * info)
|
|||||||
this->getLocalTransform(),
|
this->getLocalTransform(),
|
||||||
0,
|
0,
|
||||||
rgb.size());
|
rgb.size());
|
||||||
|
|
||||||
|
if(_type==kTypeColorDepth)
|
||||||
|
{
|
||||||
|
if(_stereoModel.right().isValidForRectification())
|
||||||
|
{
|
||||||
|
rgb = _stereoModel.right().rectifyImage(rgb);
|
||||||
|
model = _stereoModel.right();
|
||||||
|
|
||||||
|
if(_stereoModel.left().isValidForRectification() && !_stereoModel.stereoTransform().isNull())
|
||||||
|
{
|
||||||
|
depth = _stereoModel.left().rectifyImage(depth, 0);
|
||||||
|
depth = util2d::registerDepth(depth, _stereoModel.left().K(), rgb.size(), _stereoModel.right().K(), _stereoModel.stereoTransform());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // IR
|
||||||
|
{
|
||||||
|
if(_stereoModel.left().isValidForRectification())
|
||||||
|
{
|
||||||
|
rgb = _stereoModel.left().rectifyImage(rgb);
|
||||||
|
if(_type!=kTypeIR)
|
||||||
|
{
|
||||||
|
depth = _stereoModel.left().rectifyImage(depth, 0);
|
||||||
|
}
|
||||||
|
model = _stereoModel.left();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
model.setLocalTransform(this->getLocalTransform());
|
||||||
|
|
||||||
if(_openNI2StampsAndIDsUsed)
|
if(_openNI2StampsAndIDsUsed)
|
||||||
{
|
{
|
||||||
data = SensorData(rgb, depth, model, depthFrame.getFrameIndex(), double(depthFrame.getTimestamp()) / 1000000.0);
|
data = SensorData(rgb, depth, model, depthFrame.getFrameIndex(), double(depthFrame.getTimestamp()) / 1000000.0);
|
||||||
@@ -748,8 +886,10 @@ SensorData CameraOpenNI2::captureImage(CameraInfo * info)
|
|||||||
//
|
//
|
||||||
class FreenectDevice : public UThread {
|
class FreenectDevice : public UThread {
|
||||||
public:
|
public:
|
||||||
FreenectDevice(freenect_context * ctx, int index) :
|
FreenectDevice(freenect_context * ctx, int index, bool color = true, bool registered = true) :
|
||||||
index_(index),
|
index_(index),
|
||||||
|
color_(color),
|
||||||
|
registered_(registered),
|
||||||
ctx_(ctx),
|
ctx_(ctx),
|
||||||
device_(0),
|
device_(0),
|
||||||
depthFocal_(0.0f)
|
depthFocal_(0.0f)
|
||||||
@@ -798,22 +938,37 @@ class FreenectDevice : public UThread {
|
|||||||
UERROR("Could not get serial for index %d", index_);
|
UERROR("Could not get serial for index %d", index_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINFO("color=%d registered=%d", color_?1:0, registered_?1:0);
|
||||||
|
|
||||||
freenect_set_user(device_, this);
|
freenect_set_user(device_, this);
|
||||||
freenect_set_video_mode(device_, freenect_find_video_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_VIDEO_RGB));
|
freenect_frame_mode videoMode = freenect_find_video_mode(FREENECT_RESOLUTION_MEDIUM, color_?FREENECT_VIDEO_RGB:FREENECT_VIDEO_IR_8BIT);
|
||||||
freenect_set_depth_mode(device_, freenect_find_depth_mode(FREENECT_RESOLUTION_MEDIUM, FREENECT_DEPTH_REGISTERED));
|
freenect_frame_mode depthMode = freenect_find_depth_mode(FREENECT_RESOLUTION_MEDIUM, color_ && registered_?FREENECT_DEPTH_REGISTERED:FREENECT_DEPTH_MM);
|
||||||
depthBuffer_ = cv::Mat(cv::Size(640,480),CV_16UC1);
|
if(!videoMode.is_valid)
|
||||||
rgbBuffer_ = cv::Mat(cv::Size(640,480), CV_8UC3);
|
{
|
||||||
|
UERROR("Freenect: video mode selected not valid!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!depthMode.is_valid)
|
||||||
|
{
|
||||||
|
UERROR("Freenect: depth mode selected not valid!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
UASSERT(videoMode.data_bits_per_pixel == 8 || videoMode.data_bits_per_pixel == 24);
|
||||||
|
UASSERT(depthMode.data_bits_per_pixel == 16);
|
||||||
|
freenect_set_video_mode(device_, videoMode);
|
||||||
|
freenect_set_depth_mode(device_, depthMode);
|
||||||
|
rgbIrBuffer_ = cv::Mat(cv::Size(videoMode.width,videoMode.height), color_?CV_8UC3:CV_8UC1);
|
||||||
|
depthBuffer_ = cv::Mat(cv::Size(depthMode.width,depthMode.height), CV_16UC1);
|
||||||
freenect_set_depth_buffer(device_, depthBuffer_.data);
|
freenect_set_depth_buffer(device_, depthBuffer_.data);
|
||||||
freenect_set_video_buffer(device_, rgbBuffer_.data);
|
freenect_set_video_buffer(device_, rgbIrBuffer_.data);
|
||||||
freenect_set_depth_callback(device_, freenect_depth_callback);
|
freenect_set_depth_callback(device_, freenect_depth_callback);
|
||||||
freenect_set_video_callback(device_, freenect_video_callback);
|
freenect_set_video_callback(device_, freenect_video_callback);
|
||||||
|
|
||||||
bool registered = true;
|
|
||||||
float rgb_focal_length_sxga = 1050.0f;
|
float rgb_focal_length_sxga = 1050.0f;
|
||||||
float width_sxga = 1280.0f;
|
float width_sxga = 1280.0f;
|
||||||
float width = freenect_get_current_depth_mode(device_).width;
|
float width = freenect_get_current_depth_mode(device_).width;
|
||||||
float scale = width / width_sxga;
|
float scale = width / width_sxga;
|
||||||
if(registered)
|
if(color_ && registered_)
|
||||||
{
|
{
|
||||||
depthFocal_ = rgb_focal_length_sxga * scale;
|
depthFocal_ = rgb_focal_length_sxga * scale;
|
||||||
}
|
}
|
||||||
@@ -836,16 +991,16 @@ class FreenectDevice : public UThread {
|
|||||||
{
|
{
|
||||||
if(this->isRunning())
|
if(this->isRunning())
|
||||||
{
|
{
|
||||||
if(!dataReady_.acquire(1, 2000))
|
if(!dataReady_.acquire(1, 5000))
|
||||||
{
|
{
|
||||||
UERROR("Not received any frames since 2 seconds, try to restart the camera again.");
|
UERROR("Not received any frames since 5 seconds, try to restart the camera again.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UScopeMutex s(dataMutex_);
|
UScopeMutex s(dataMutex_);
|
||||||
rgb = rgbLastFrame_;
|
rgb = rgbIrLastFrame_;
|
||||||
depth = depthLastFrame_;
|
depth = depthLastFrame_;
|
||||||
rgbLastFrame_ = cv::Mat();
|
rgbIrLastFrame_ = cv::Mat();
|
||||||
depthLastFrame_= cv::Mat();
|
depthLastFrame_= cv::Mat();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -855,10 +1010,18 @@ private:
|
|||||||
// Do not call directly even in child
|
// Do not call directly even in child
|
||||||
void VideoCallback(void* rgb)
|
void VideoCallback(void* rgb)
|
||||||
{
|
{
|
||||||
UASSERT(rgbBuffer_.data == rgb);
|
UASSERT(rgbIrBuffer_.data == rgb);
|
||||||
UScopeMutex s(dataMutex_);
|
UScopeMutex s(dataMutex_);
|
||||||
bool notify = rgbLastFrame_.empty();
|
bool notify = rgbIrLastFrame_.empty();
|
||||||
cv::cvtColor(rgbBuffer_, rgbLastFrame_, CV_RGB2BGR);
|
|
||||||
|
if(color_)
|
||||||
|
{
|
||||||
|
cv::cvtColor(rgbIrBuffer_, rgbIrLastFrame_, CV_RGB2BGR);
|
||||||
|
}
|
||||||
|
else // IrDepth
|
||||||
|
{
|
||||||
|
rgbIrLastFrame_ = rgbIrBuffer_.clone();
|
||||||
|
}
|
||||||
if(!depthLastFrame_.empty() && notify)
|
if(!depthLastFrame_.empty() && notify)
|
||||||
{
|
{
|
||||||
dataReady_.release();
|
dataReady_.release();
|
||||||
@@ -872,7 +1035,7 @@ private:
|
|||||||
UScopeMutex s(dataMutex_);
|
UScopeMutex s(dataMutex_);
|
||||||
bool notify = depthLastFrame_.empty();
|
bool notify = depthLastFrame_.empty();
|
||||||
depthLastFrame_ = depthBuffer_.clone();
|
depthLastFrame_ = depthBuffer_.clone();
|
||||||
if(!rgbLastFrame_.empty() && notify)
|
if(!rgbIrLastFrame_.empty() && notify)
|
||||||
{
|
{
|
||||||
dataReady_.release();
|
dataReady_.release();
|
||||||
}
|
}
|
||||||
@@ -931,14 +1094,16 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int index_;
|
int index_;
|
||||||
|
bool color_;
|
||||||
|
bool registered_;
|
||||||
std::string serial_;
|
std::string serial_;
|
||||||
freenect_context * ctx_;
|
freenect_context * ctx_;
|
||||||
freenect_device * device_;
|
freenect_device * device_;
|
||||||
cv::Mat depthBuffer_;
|
cv::Mat depthBuffer_;
|
||||||
cv::Mat rgbBuffer_;
|
cv::Mat rgbIrBuffer_;
|
||||||
UMutex dataMutex_;
|
UMutex dataMutex_;
|
||||||
cv::Mat depthLastFrame_;
|
cv::Mat depthLastFrame_;
|
||||||
cv::Mat rgbLastFrame_;
|
cv::Mat rgbIrLastFrame_;
|
||||||
float depthFocal_;
|
float depthFocal_;
|
||||||
USemaphore dataReady_;
|
USemaphore dataReady_;
|
||||||
};
|
};
|
||||||
@@ -956,9 +1121,10 @@ bool CameraFreenect::available()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CameraFreenect::CameraFreenect(int deviceId, float imageRate, const Transform & localTransform) :
|
CameraFreenect::CameraFreenect(int deviceId, Type type, float imageRate, const Transform & localTransform) :
|
||||||
Camera(imageRate, localTransform),
|
Camera(imageRate, localTransform),
|
||||||
deviceId_(deviceId),
|
deviceId_(deviceId),
|
||||||
|
type_(type),
|
||||||
ctx_(0),
|
ctx_(0),
|
||||||
freenectDevice_(0)
|
freenectDevice_(0)
|
||||||
{
|
{
|
||||||
@@ -997,7 +1163,50 @@ bool CameraFreenect::init(const std::string & calibrationFolder, const std::stri
|
|||||||
|
|
||||||
if(ctx_ && freenect_num_devices(ctx_) > 0)
|
if(ctx_ && freenect_num_devices(ctx_) > 0)
|
||||||
{
|
{
|
||||||
freenectDevice_ = new FreenectDevice(ctx_, deviceId_);
|
// look for calibration files
|
||||||
|
bool hardwareRegistration = true;
|
||||||
|
stereoModel_ = StereoCameraModel();
|
||||||
|
if(!calibrationFolder.empty())
|
||||||
|
{
|
||||||
|
// we need the serial, HACK: init a temp device to get it
|
||||||
|
FreenectDevice dev(ctx_, deviceId_);
|
||||||
|
if(!dev.init())
|
||||||
|
{
|
||||||
|
UERROR("CameraFreenect: Init failed!");
|
||||||
|
}
|
||||||
|
std::string calibrationName = dev.getSerial();
|
||||||
|
if(!cameraName.empty())
|
||||||
|
{
|
||||||
|
calibrationName = cameraName;
|
||||||
|
}
|
||||||
|
stereoModel_.setName(calibrationName, "depth", "rgb");
|
||||||
|
hardwareRegistration = !stereoModel_.load(calibrationFolder, calibrationName, false);
|
||||||
|
|
||||||
|
if(type_ == kTypeIRDepth)
|
||||||
|
{
|
||||||
|
hardwareRegistration = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if((type_ == kTypeIRDepth && !stereoModel_.left().isValidForRectification()) ||
|
||||||
|
(type_ == kTypeColorDepth && !stereoModel_.right().isValidForRectification()))
|
||||||
|
{
|
||||||
|
UWARN("Missing calibration files for camera \"%s\" in \"%s\" folder, default calibration used.",
|
||||||
|
calibrationName.c_str(), calibrationFolder.c_str());
|
||||||
|
}
|
||||||
|
else if(type_ == kTypeColorDepth && stereoModel_.right().isValidForRectification() && hardwareRegistration)
|
||||||
|
{
|
||||||
|
UWARN("Missing extrinsic calibration file for camera \"%s\" in \"%s\" folder, default registration is used even if rgb is rectified!",
|
||||||
|
calibrationName.c_str(), calibrationFolder.c_str());
|
||||||
|
}
|
||||||
|
else if(type_ == kTypeColorDepth && stereoModel_.right().isValidForRectification() && !hardwareRegistration)
|
||||||
|
{
|
||||||
|
UINFO("Custom calibration files for \"%s\" were found in \"%s\" folder. To use "
|
||||||
|
"factory calibration, remove the corresponding files from that directory.", calibrationName.c_str(), calibrationFolder.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
freenectDevice_ = new FreenectDevice(ctx_, deviceId_, type_==kTypeColorDepth, hardwareRegistration);
|
||||||
if(freenectDevice_->init())
|
if(freenectDevice_->init())
|
||||||
{
|
{
|
||||||
freenectDevice_->start();
|
freenectDevice_->start();
|
||||||
@@ -1050,18 +1259,43 @@ SensorData CameraFreenect::captureImage(CameraInfo * info)
|
|||||||
if(!rgb.empty() && !depth.empty())
|
if(!rgb.empty() && !depth.empty())
|
||||||
{
|
{
|
||||||
UASSERT(freenectDevice_->getDepthFocal() != 0.0f);
|
UASSERT(freenectDevice_->getDepthFocal() != 0.0f);
|
||||||
if(!rgb.empty() && !depth.empty())
|
|
||||||
|
// default calibration
|
||||||
|
CameraModel model(
|
||||||
|
freenectDevice_->getDepthFocal(), //fx
|
||||||
|
freenectDevice_->getDepthFocal(), //fy
|
||||||
|
float(rgb.cols/2) - 0.5f, //cx
|
||||||
|
float(rgb.rows/2) - 0.5f, //cy
|
||||||
|
this->getLocalTransform(),
|
||||||
|
0,
|
||||||
|
rgb.size());
|
||||||
|
|
||||||
|
if(type_==kTypeIRDepth)
|
||||||
{
|
{
|
||||||
CameraModel model(
|
if(stereoModel_.left().isValidForRectification())
|
||||||
freenectDevice_->getDepthFocal(), //fx
|
{
|
||||||
freenectDevice_->getDepthFocal(), //fy
|
rgb = stereoModel_.left().rectifyImage(rgb);
|
||||||
float(rgb.cols/2) - 0.5f, //cx
|
depth = stereoModel_.left().rectifyImage(depth, 0);
|
||||||
float(rgb.rows/2) - 0.5f, //cy
|
model = stereoModel_.left();
|
||||||
this->getLocalTransform(),
|
}
|
||||||
0,
|
|
||||||
rgb.size());
|
|
||||||
data = SensorData(rgb, depth, model, this->getNextSeqID(), UTimer::now());
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(stereoModel_.right().isValidForRectification())
|
||||||
|
{
|
||||||
|
rgb = stereoModel_.right().rectifyImage(rgb);
|
||||||
|
model = stereoModel_.right();
|
||||||
|
|
||||||
|
if(stereoModel_.left().isValidForRectification() && !stereoModel_.stereoTransform().isNull())
|
||||||
|
{
|
||||||
|
depth = stereoModel_.left().rectifyImage(depth, 0);
|
||||||
|
depth = util2d::registerDepth(depth, stereoModel_.left().K(), rgb.size(), stereoModel_.right().K(), stereoModel_.stereoTransform());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
model.setLocalTransform(this->getLocalTransform());
|
||||||
|
|
||||||
|
data = SensorData(rgb, depth, model, this->getNextSeqID(), UTimer::now());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1248,6 +1482,9 @@ bool CameraFreenect2::init(const std::string & calibrationFolder, const std::str
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
UINFO("Custom calibration files for \"%s\" were found in \"%s\" folder. To use "
|
||||||
|
"factory calibration, remove the corresponding files from that directory.", calibrationName.c_str(), calibrationFolder.c_str());
|
||||||
|
|
||||||
if(type_==kTypeColor2DepthSD)
|
if(type_==kTypeColor2DepthSD)
|
||||||
{
|
{
|
||||||
UWARN("Freenect2: When using custom calibration file, type "
|
UWARN("Freenect2: When using custom calibration file, type "
|
||||||
@@ -1445,6 +1682,7 @@ SensorData CameraFreenect2::captureImage(CameraInfo * info)
|
|||||||
depth = util2d::registerDepth(
|
depth = util2d::registerDepth(
|
||||||
depth,
|
depth,
|
||||||
stereoModel_.left().P().colRange(0,3).rowRange(0,3), //scaled depth K
|
stereoModel_.left().P().colRange(0,3).rowRange(0,3), //scaled depth K
|
||||||
|
depth.size(),
|
||||||
stereoModel_.right().P().colRange(0,3).rowRange(0,3), //scaled color K
|
stereoModel_.right().P().colRange(0,3).rowRange(0,3), //scaled color K
|
||||||
stereoModel_.stereoTransform());
|
stereoModel_.stereoTransform());
|
||||||
util2d::fillRegisteredDepthHoles(depth, true, false);
|
util2d::fillRegisteredDepthHoles(depth, true, false);
|
||||||
|
|||||||
@@ -42,13 +42,15 @@ StereoCameraModel::StereoCameraModel(
|
|||||||
const cv::Mat & K2, const cv::Mat & D2, const cv::Mat & R2, const cv::Mat & P2,
|
const cv::Mat & K2, const cv::Mat & D2, const cv::Mat & R2, const cv::Mat & P2,
|
||||||
const cv::Mat & R, const cv::Mat & T, const cv::Mat & E, const cv::Mat & F,
|
const cv::Mat & R, const cv::Mat & T, const cv::Mat & E, const cv::Mat & F,
|
||||||
const Transform & localTransform) :
|
const Transform & localTransform) :
|
||||||
left_(name+"_left", imageSize1, K1, D1, R1, P1, localTransform),
|
leftSuffix_("left"),
|
||||||
right_(name+"_right", imageSize2, K2, D2, R2, P2, localTransform),
|
rightSuffix_("right"),
|
||||||
name_(name),
|
left_(name+"_"+leftSuffix_, imageSize1, K1, D1, R1, P1, localTransform),
|
||||||
R_(R),
|
right_(name+"_"+rightSuffix_, imageSize2, K2, D2, R2, P2, localTransform),
|
||||||
T_(T),
|
name_(name),
|
||||||
E_(E),
|
R_(R),
|
||||||
F_(F)
|
T_(T),
|
||||||
|
E_(E),
|
||||||
|
F_(F)
|
||||||
{
|
{
|
||||||
UASSERT(R_.empty() || (R_.rows == 3 && R_.cols == 3 && R_.type() == CV_64FC1));
|
UASSERT(R_.empty() || (R_.rows == 3 && R_.cols == 3 && R_.type() == CV_64FC1));
|
||||||
UASSERT(T_.empty() || (T_.rows == 3 && T_.cols == 1 && T_.type() == CV_64FC1));
|
UASSERT(T_.empty() || (T_.rows == 3 && T_.cols == 1 && T_.type() == CV_64FC1));
|
||||||
@@ -64,6 +66,8 @@ StereoCameraModel::StereoCameraModel(
|
|||||||
const cv::Mat & T,
|
const cv::Mat & T,
|
||||||
const cv::Mat & E,
|
const cv::Mat & E,
|
||||||
const cv::Mat & F) :
|
const cv::Mat & F) :
|
||||||
|
leftSuffix_("left"),
|
||||||
|
rightSuffix_("right"),
|
||||||
left_(leftCameraModel),
|
left_(leftCameraModel),
|
||||||
right_(rightCameraModel),
|
right_(rightCameraModel),
|
||||||
name_(name),
|
name_(name),
|
||||||
@@ -72,8 +76,8 @@ StereoCameraModel::StereoCameraModel(
|
|||||||
E_(E),
|
E_(E),
|
||||||
F_(F)
|
F_(F)
|
||||||
{
|
{
|
||||||
left_.setName(name+"_left");
|
left_.setName(name+"_"+getLeftSuffix());
|
||||||
right_.setName(name+"_right");
|
right_.setName(name+"_"+getRightSuffix());
|
||||||
UASSERT(R_.empty() || (R_.rows == 3 && R_.cols == 3 && R_.type() == CV_64FC1));
|
UASSERT(R_.empty() || (R_.rows == 3 && R_.cols == 3 && R_.type() == CV_64FC1));
|
||||||
UASSERT(T_.empty() || (T_.rows == 3 && T_.cols == 1 && T_.type() == CV_64FC1));
|
UASSERT(T_.empty() || (T_.rows == 3 && T_.cols == 1 && T_.type() == CV_64FC1));
|
||||||
UASSERT(E_.empty() || (E_.rows == 3 && E_.cols == 3 && E_.type() == CV_64FC1));
|
UASSERT(E_.empty() || (E_.rows == 3 && E_.cols == 3 && E_.type() == CV_64FC1));
|
||||||
@@ -99,12 +103,14 @@ StereoCameraModel::StereoCameraModel(
|
|||||||
const CameraModel & leftCameraModel,
|
const CameraModel & leftCameraModel,
|
||||||
const CameraModel & rightCameraModel,
|
const CameraModel & rightCameraModel,
|
||||||
const Transform & extrinsics) :
|
const Transform & extrinsics) :
|
||||||
|
leftSuffix_("left"),
|
||||||
|
rightSuffix_("right"),
|
||||||
left_(leftCameraModel),
|
left_(leftCameraModel),
|
||||||
right_(rightCameraModel),
|
right_(rightCameraModel),
|
||||||
name_(name)
|
name_(name)
|
||||||
{
|
{
|
||||||
left_.setName(name+"_left");
|
left_.setName(name+"_"+getLeftSuffix());
|
||||||
right_.setName(name+"_right");
|
right_.setName(name+"_"+getRightSuffix());
|
||||||
|
|
||||||
if(!extrinsics.isNull())
|
if(!extrinsics.isNull())
|
||||||
{
|
{
|
||||||
@@ -132,8 +138,10 @@ StereoCameraModel::StereoCameraModel(
|
|||||||
double baseline,
|
double baseline,
|
||||||
const Transform & localTransform,
|
const Transform & localTransform,
|
||||||
const cv::Size & imageSize) :
|
const cv::Size & imageSize) :
|
||||||
left_(fx, fy, cx, cy, localTransform, 0, imageSize),
|
leftSuffix_("left"),
|
||||||
right_(fx, fy, cx, cy, localTransform, baseline*-fx, imageSize)
|
rightSuffix_("right"),
|
||||||
|
left_(fx, fy, cx, cy, localTransform, 0, imageSize),
|
||||||
|
right_(fx, fy, cx, cy, localTransform, baseline*-fx, imageSize)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,23 +155,29 @@ StereoCameraModel::StereoCameraModel(
|
|||||||
double baseline,
|
double baseline,
|
||||||
const Transform & localTransform,
|
const Transform & localTransform,
|
||||||
const cv::Size & imageSize) :
|
const cv::Size & imageSize) :
|
||||||
left_(name+"_left", fx, fy, cx, cy, localTransform, 0, imageSize),
|
leftSuffix_("left"),
|
||||||
right_(name+"_right", fx, fy, cx, cy, localTransform, baseline*-fx, imageSize),
|
rightSuffix_("right"),
|
||||||
name_(name)
|
left_(name+"_"+getLeftSuffix(), fx, fy, cx, cy, localTransform, 0, imageSize),
|
||||||
|
right_(name+"_"+getRightSuffix(), fx, fy, cx, cy, localTransform, baseline*-fx, imageSize),
|
||||||
|
name_(name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void StereoCameraModel::setName(const std::string & name)
|
void StereoCameraModel::setName(const std::string & name, const std::string & leftSuffix, const std::string & rightSuffix)
|
||||||
{
|
{
|
||||||
name_=name;
|
name_=name;
|
||||||
left_.setName(name_+"_left");
|
leftSuffix_ = leftSuffix;
|
||||||
right_.setName(name_+"_right");
|
rightSuffix_ = rightSuffix;
|
||||||
|
left_.setName(name_+"_"+getLeftSuffix());
|
||||||
|
right_.setName(name_+"_"+getRightSuffix());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StereoCameraModel::load(const std::string & directory, const std::string & cameraName, bool ignoreStereoTransform)
|
bool StereoCameraModel::load(const std::string & directory, const std::string & cameraName, bool ignoreStereoTransform)
|
||||||
{
|
{
|
||||||
name_ = cameraName;
|
name_ = cameraName;
|
||||||
if(left_.load(directory, cameraName+"_left") && right_.load(directory, cameraName+"_right"))
|
bool leftLoaded = left_.load(directory, cameraName+"_"+getLeftSuffix());
|
||||||
|
bool rightLoaded = right_.load(directory, cameraName+"_"+getRightSuffix());
|
||||||
|
if(leftLoaded && rightLoaded)
|
||||||
{
|
{
|
||||||
if(ignoreStereoTransform)
|
if(ignoreStereoTransform)
|
||||||
{
|
{
|
||||||
@@ -277,63 +291,69 @@ bool StereoCameraModel::save(const std::string & directory, bool ignoreStereoTra
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
std::string filePath = directory+"/"+name_+"_pose.yaml";
|
return saveStereoTransform(directory);
|
||||||
if(!filePath.empty() && (!R_.empty() && !T_.empty()))
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StereoCameraModel::saveStereoTransform(const std::string & directory) const
|
||||||
|
{
|
||||||
|
std::string filePath = directory+"/"+name_+"_pose.yaml";
|
||||||
|
if(!filePath.empty() && (!R_.empty() && !T_.empty()))
|
||||||
|
{
|
||||||
|
UINFO("Saving stereo calibration to file \"%s\"", filePath.c_str());
|
||||||
|
cv::FileStorage fs(filePath, cv::FileStorage::WRITE);
|
||||||
|
|
||||||
|
// export in ROS calibration format
|
||||||
|
|
||||||
|
if(!name_.empty())
|
||||||
{
|
{
|
||||||
UINFO("Saving stereo calibration to file \"%s\"", filePath.c_str());
|
fs << "camera_name" << name_;
|
||||||
cv::FileStorage fs(filePath, cv::FileStorage::WRITE);
|
|
||||||
|
|
||||||
// export in ROS calibration format
|
|
||||||
|
|
||||||
if(!name_.empty())
|
|
||||||
{
|
|
||||||
fs << "camera_name" << name_;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!R_.empty())
|
|
||||||
{
|
|
||||||
fs << "rotation_matrix" << "{";
|
|
||||||
fs << "rows" << R_.rows;
|
|
||||||
fs << "cols" << R_.cols;
|
|
||||||
fs << "data" << std::vector<double>((double*)R_.data, ((double*)R_.data)+(R_.rows*R_.cols));
|
|
||||||
fs << "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!T_.empty())
|
|
||||||
{
|
|
||||||
fs << "translation_matrix" << "{";
|
|
||||||
fs << "rows" << T_.rows;
|
|
||||||
fs << "cols" << T_.cols;
|
|
||||||
fs << "data" << std::vector<double>((double*)T_.data, ((double*)T_.data)+(T_.rows*T_.cols));
|
|
||||||
fs << "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!E_.empty())
|
|
||||||
{
|
|
||||||
fs << "essential_matrix" << "{";
|
|
||||||
fs << "rows" << E_.rows;
|
|
||||||
fs << "cols" << E_.cols;
|
|
||||||
fs << "data" << std::vector<double>((double*)E_.data, ((double*)E_.data)+(E_.rows*E_.cols));
|
|
||||||
fs << "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!F_.empty())
|
|
||||||
{
|
|
||||||
fs << "fundamental_matrix" << "{";
|
|
||||||
fs << "rows" << F_.rows;
|
|
||||||
fs << "cols" << F_.cols;
|
|
||||||
fs << "data" << std::vector<double>((double*)F_.data, ((double*)F_.data)+(F_.rows*F_.cols));
|
|
||||||
fs << "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.release();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if(!R_.empty())
|
||||||
{
|
{
|
||||||
UERROR("Failed saving stereo extrinsics (they are null).");
|
fs << "rotation_matrix" << "{";
|
||||||
|
fs << "rows" << R_.rows;
|
||||||
|
fs << "cols" << R_.cols;
|
||||||
|
fs << "data" << std::vector<double>((double*)R_.data, ((double*)R_.data)+(R_.rows*R_.cols));
|
||||||
|
fs << "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!T_.empty())
|
||||||
|
{
|
||||||
|
fs << "translation_matrix" << "{";
|
||||||
|
fs << "rows" << T_.rows;
|
||||||
|
fs << "cols" << T_.cols;
|
||||||
|
fs << "data" << std::vector<double>((double*)T_.data, ((double*)T_.data)+(T_.rows*T_.cols));
|
||||||
|
fs << "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!E_.empty())
|
||||||
|
{
|
||||||
|
fs << "essential_matrix" << "{";
|
||||||
|
fs << "rows" << E_.rows;
|
||||||
|
fs << "cols" << E_.cols;
|
||||||
|
fs << "data" << std::vector<double>((double*)E_.data, ((double*)E_.data)+(E_.rows*E_.cols));
|
||||||
|
fs << "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!F_.empty())
|
||||||
|
{
|
||||||
|
fs << "fundamental_matrix" << "{";
|
||||||
|
fs << "rows" << F_.rows;
|
||||||
|
fs << "cols" << F_.cols;
|
||||||
|
fs << "data" << std::vector<double>((double*)F_.data, ((double*)F_.data)+(F_.rows*F_.cols));
|
||||||
|
fs << "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.release();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UERROR("Failed saving stereo extrinsics (they are null).");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1337,6 +1337,7 @@ cv::Mat interpolate(const cv::Mat & image, int factor, float depthErrorRatio)
|
|||||||
cv::Mat registerDepth(
|
cv::Mat registerDepth(
|
||||||
const cv::Mat & depth,
|
const cv::Mat & depth,
|
||||||
const cv::Mat & depthK,
|
const cv::Mat & depthK,
|
||||||
|
const cv::Size & colorSize,
|
||||||
const cv::Mat & colorK,
|
const cv::Mat & colorK,
|
||||||
const rtabmap::Transform & transform)
|
const rtabmap::Transform & transform)
|
||||||
{
|
{
|
||||||
@@ -1356,10 +1357,13 @@ cv::Mat registerDepth(
|
|||||||
float rcx = colorK.at<double>(0,2);
|
float rcx = colorK.at<double>(0,2);
|
||||||
float rcy = colorK.at<double>(1,2);
|
float rcy = colorK.at<double>(1,2);
|
||||||
|
|
||||||
|
//UDEBUG("depth(%dx%d) fx=%f fy=%f cx=%f cy=%f", depth.cols, depth.rows, fx, fy, cx, cy);
|
||||||
|
//UDEBUG("color(%dx%d) fx=%f fy=%f cx=%f cy=%f", colorSize.width, colorSize.height, rfx, rfy, rcx, rcy);
|
||||||
|
|
||||||
Eigen::Affine3f proj = transform.toEigen3f();
|
Eigen::Affine3f proj = transform.toEigen3f();
|
||||||
Eigen::Vector4f P4,P3;
|
Eigen::Vector4f P4,P3;
|
||||||
P4[3] = 1;
|
P4[3] = 1;
|
||||||
cv::Mat registered = cv::Mat::zeros(depth.rows, depth.cols, depth.type());
|
cv::Mat registered = cv::Mat::zeros(colorSize, depth.type());
|
||||||
|
|
||||||
bool depthInMM = depth.type() == CV_16UC1;
|
bool depthInMM = depth.type() == CV_16UC1;
|
||||||
for(int y=0; y<depth.rows; ++y)
|
for(int y=0; y<depth.rows; ++y)
|
||||||
|
|||||||
@@ -779,7 +779,10 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cloudFromSensorData(
|
|||||||
|
|
||||||
if(tmp->size())
|
if(tmp->size())
|
||||||
{
|
{
|
||||||
tmp = util3d::transformPointCloud(tmp, model.localTransform());
|
if(!model.localTransform().isNull() && !model.localTransform().isIdentity())
|
||||||
|
{
|
||||||
|
tmp = util3d::transformPointCloud(tmp, model.localTransform());
|
||||||
|
}
|
||||||
|
|
||||||
if(sensorData.cameraModels().size() > 1)
|
if(sensorData.cameraModels().size() > 1)
|
||||||
{
|
{
|
||||||
@@ -833,7 +836,7 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cloudFromSensorData(
|
|||||||
|
|
||||||
if(cloud->size())
|
if(cloud->size())
|
||||||
{
|
{
|
||||||
if(cloud->size())
|
if(cloud->size() && !sensorData.stereoCameraModel().left().localTransform().isNull() && !sensorData.stereoCameraModel().left().localTransform().isIdentity())
|
||||||
{
|
{
|
||||||
cloud = util3d::transformPointCloud(cloud, sensorData.stereoCameraModel().left().localTransform());
|
cloud = util3d::transformPointCloud(cloud, sensorData.stereoCameraModel().left().localTransform());
|
||||||
}
|
}
|
||||||
@@ -862,8 +865,8 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudRGBFromSensorData(
|
|||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
UASSERT(int((sensorData.imageRaw().cols/sensorData.cameraModels().size())*sensorData.cameraModels().size()) == sensorData.imageRaw().cols);
|
UASSERT(int((sensorData.imageRaw().cols/sensorData.cameraModels().size())*sensorData.cameraModels().size()) == sensorData.imageRaw().cols);
|
||||||
UASSERT(int((sensorData.depthRaw().cols/sensorData.cameraModels().size())*sensorData.cameraModels().size()) == sensorData.depthRaw().cols);
|
UASSERT(int((sensorData.depthRaw().cols/sensorData.cameraModels().size())*sensorData.cameraModels().size()) == sensorData.depthRaw().cols);
|
||||||
UASSERT(sensorData.imageRaw().cols % sensorData.depthRaw().cols == 0);
|
UASSERT_MSG(sensorData.imageRaw().cols % sensorData.depthRaw().cols == 0, uFormat("rgb=%d depth=%d", sensorData.imageRaw().cols, sensorData.depthRaw().cols).c_str());
|
||||||
UASSERT(sensorData.imageRaw().rows % sensorData.depthRaw().rows == 0);
|
UASSERT_MSG(sensorData.imageRaw().rows % sensorData.depthRaw().rows == 0, uFormat("rgb=%d depth=%d", sensorData.imageRaw().rows, sensorData.depthRaw().rows).c_str());
|
||||||
int subRGBWidth = sensorData.imageRaw().cols/sensorData.cameraModels().size();
|
int subRGBWidth = sensorData.imageRaw().cols/sensorData.cameraModels().size();
|
||||||
int subDepthWidth = sensorData.depthRaw().cols/sensorData.cameraModels().size();
|
int subDepthWidth = sensorData.depthRaw().cols/sensorData.cameraModels().size();
|
||||||
|
|
||||||
@@ -929,7 +932,10 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudRGBFromSensorData(
|
|||||||
|
|
||||||
if(tmp->size())
|
if(tmp->size())
|
||||||
{
|
{
|
||||||
tmp = util3d::transformPointCloud(tmp, model.localTransform());
|
if(!model.localTransform().isNull() && !model.localTransform().isIdentity())
|
||||||
|
{
|
||||||
|
tmp = util3d::transformPointCloud(tmp, model.localTransform());
|
||||||
|
}
|
||||||
|
|
||||||
if(sensorData.cameraModels().size() > 1)
|
if(sensorData.cameraModels().size() > 1)
|
||||||
{
|
{
|
||||||
@@ -972,7 +978,7 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudRGBFromSensorData(
|
|||||||
validIndices,
|
validIndices,
|
||||||
stereoParameters);
|
stereoParameters);
|
||||||
|
|
||||||
if(cloud->size())
|
if(cloud->size() && !sensorData.stereoCameraModel().left().localTransform().isNull() && !sensorData.stereoCameraModel().left().localTransform().isIdentity())
|
||||||
{
|
{
|
||||||
cloud = util3d::transformPointCloud(cloud, sensorData.stereoCameraModel().left().localTransform());
|
cloud = util3d::transformPointCloud(cloud, sensorData.stereoCameraModel().left().localTransform());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,26 +56,32 @@ public:
|
|||||||
const rtabmap::CameraModel & getRightCameraModel() const {return models_[1];}
|
const rtabmap::CameraModel & getRightCameraModel() const {return models_[1];}
|
||||||
const rtabmap::StereoCameraModel & getStereoCameraModel() const {return stereoModel_;}
|
const rtabmap::StereoCameraModel & getStereoCameraModel() const {return stereoModel_;}
|
||||||
bool isProcessing() const {return processingData_;}
|
bool isProcessing() const {return processingData_;}
|
||||||
|
int getStereoPairs() const {return (int)stereoImagePoints_[0].size();}
|
||||||
|
|
||||||
void saveSettings(QSettings & settings, const QString & group = "") const;
|
void saveSettings(QSettings & settings, const QString & group = "") const;
|
||||||
void loadSettings(QSettings & settings, const QString & group = "");
|
void loadSettings(QSettings & settings, const QString & group = "");
|
||||||
void resetSettings();
|
void resetSettings();
|
||||||
|
|
||||||
|
void setCameraName(const QString & name);
|
||||||
|
void setProgressVisibility(bool visible);
|
||||||
void setSwitchedImages(bool switched);
|
void setSwitchedImages(bool switched);
|
||||||
void setStereoMode(bool stereo);
|
void setStereoMode(bool stereo, const QString & leftSuffix = "left", const QString & rightSuffix = "right");
|
||||||
void setSavingDirectory(const QString & savingDirectory) {savingDirectory_ = savingDirectory;}
|
void setSavingDirectory(const QString & savingDirectory) {savingDirectory_ = savingDirectory;}
|
||||||
|
|
||||||
|
StereoCameraModel stereoCalibration(const CameraModel & left, const CameraModel & right, bool ignoreStereoRectification) const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setBoardWidth(int width);
|
void setBoardWidth(int width);
|
||||||
void setBoardHeight(int height);
|
void setBoardHeight(int height);
|
||||||
void setSquareSize(double size);
|
void setSquareSize(double size);
|
||||||
void setMaxScale(int scale);
|
void setMaxScale(int scale);
|
||||||
|
|
||||||
private slots:
|
|
||||||
void processImages(const cv::Mat & imageLeft, const cv::Mat & imageRight, const QString & cameraName);
|
void processImages(const cv::Mat & imageLeft, const cv::Mat & imageRight, const QString & cameraName);
|
||||||
void restart();
|
|
||||||
void calibrate();
|
void calibrate();
|
||||||
|
void restart();
|
||||||
bool save();
|
bool save();
|
||||||
|
|
||||||
|
private slots:
|
||||||
void unlock();
|
void unlock();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -96,6 +102,8 @@ private:
|
|||||||
private:
|
private:
|
||||||
// parameters
|
// parameters
|
||||||
bool stereo_;
|
bool stereo_;
|
||||||
|
QString leftSuffix_;
|
||||||
|
QString rightSuffix_;
|
||||||
QString savingDirectory_;
|
QString savingDirectory_;
|
||||||
|
|
||||||
QString cameraName_;
|
QString cameraName_;
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ public:
|
|||||||
int getSourceScanNormalsK() const;
|
int getSourceScanNormalsK() const;
|
||||||
Transform getSourceLocalTransform() const; //Openni group
|
Transform getSourceLocalTransform() const; //Openni group
|
||||||
Transform getLaserLocalTransform() const; // directory images
|
Transform getLaserLocalTransform() const; // directory images
|
||||||
Camera * createCamera(bool useRawImages = false); // return camera should be deleted if not null
|
Camera * createCamera(bool useRawImages = false, bool useColor = true); // return camera should be deleted if not null
|
||||||
|
|
||||||
int getIgnoredDCComponents() const;
|
int getIgnoredDCComponents() const;
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ namespace rtabmap {
|
|||||||
CalibrationDialog::CalibrationDialog(bool stereo, const QString & savingDirectory, bool switchImages, QWidget * parent) :
|
CalibrationDialog::CalibrationDialog(bool stereo, const QString & savingDirectory, bool switchImages, QWidget * parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
stereo_(stereo),
|
stereo_(stereo),
|
||||||
|
leftSuffix_("left"),
|
||||||
|
rightSuffix_("right"),
|
||||||
savingDirectory_(savingDirectory),
|
savingDirectory_(savingDirectory),
|
||||||
processingData_(false),
|
processingData_(false),
|
||||||
savedCalibration_(false)
|
savedCalibration_(false)
|
||||||
@@ -149,15 +151,28 @@ void CalibrationDialog::resetSettings()
|
|||||||
this->setSquareSize(0.033);
|
this->setSquareSize(0.033);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CalibrationDialog::setCameraName(const QString & name)
|
||||||
|
{
|
||||||
|
cameraName_ = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CalibrationDialog::setProgressVisibility(bool visible)
|
||||||
|
{
|
||||||
|
ui_->groupBox_progress->setVisible(visible);
|
||||||
|
}
|
||||||
|
|
||||||
void CalibrationDialog::setSwitchedImages(bool switched)
|
void CalibrationDialog::setSwitchedImages(bool switched)
|
||||||
{
|
{
|
||||||
ui_->checkBox_switchImages->setChecked(switched);
|
ui_->checkBox_switchImages->setChecked(switched);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalibrationDialog::setStereoMode(bool stereo)
|
void CalibrationDialog::setStereoMode(bool stereo, const QString & leftSuffix, const QString & rightSuffix)
|
||||||
{
|
{
|
||||||
|
leftSuffix_ = leftSuffix;
|
||||||
|
rightSuffix_ = rightSuffix;
|
||||||
this->restart();
|
this->restart();
|
||||||
|
|
||||||
|
ui_->groupBox_progress->setVisible(true);
|
||||||
stereo_ = stereo;
|
stereo_ = stereo;
|
||||||
ui_->progressBar_x_2->setVisible(stereo_);
|
ui_->progressBar_x_2->setVisible(stereo_);
|
||||||
ui_->progressBar_y_2->setVisible(stereo_);
|
ui_->progressBar_y_2->setVisible(stereo_);
|
||||||
@@ -601,7 +616,6 @@ void CalibrationDialog::restart()
|
|||||||
models_[0] = CameraModel();
|
models_[0] = CameraModel();
|
||||||
models_[1] = CameraModel();
|
models_[1] = CameraModel();
|
||||||
stereoModel_ = StereoCameraModel();
|
stereoModel_ = StereoCameraModel();
|
||||||
cameraName_.clear();
|
|
||||||
minIrs_[0] = 0x0000;
|
minIrs_[0] = 0x0000;
|
||||||
maxIrs_[0] = 0x7fff;
|
maxIrs_[0] = 0x7fff;
|
||||||
minIrs_[1] = 0x0000;
|
minIrs_[1] = 0x0000;
|
||||||
@@ -769,101 +783,7 @@ void CalibrationDialog::calibrate()
|
|||||||
|
|
||||||
if(stereo_ && models_[0].isValidForRectification() && models_[1].isValidForRectification())
|
if(stereo_ && models_[0].isValidForRectification() && models_[1].isValidForRectification())
|
||||||
{
|
{
|
||||||
UINFO("stereo calibration (samples=%d)...", (int)stereoImagePoints_[0].size());
|
stereoModel_ = stereoCalibration(models_[0], models_[1], false);
|
||||||
cv::Size imageSize = imageSize_[0].width > imageSize_[1].width?imageSize_[0]:imageSize_[1];
|
|
||||||
cv::Mat R, T, E, F;
|
|
||||||
|
|
||||||
std::vector<std::vector<cv::Point3f> > objectPoints(1);
|
|
||||||
cv::Size boardSize(ui_->spinBox_boardWidth->value(), ui_->spinBox_boardHeight->value());
|
|
||||||
float squareSize = ui_->doubleSpinBox_squareSize->value();
|
|
||||||
// compute board corner positions
|
|
||||||
for( int i = 0; i < boardSize.height; ++i )
|
|
||||||
for( int j = 0; j < boardSize.width; ++j )
|
|
||||||
objectPoints[0].push_back(cv::Point3f(float( j*squareSize ), float( i*squareSize ), 0));
|
|
||||||
objectPoints.resize(stereoImagePoints_[0].size(), objectPoints[0]);
|
|
||||||
|
|
||||||
// calibrate extrinsic
|
|
||||||
#if CV_MAJOR_VERSION < 3
|
|
||||||
double rms = cv::stereoCalibrate(
|
|
||||||
objectPoints,
|
|
||||||
stereoImagePoints_[0],
|
|
||||||
stereoImagePoints_[1],
|
|
||||||
models_[0].K_raw(), models_[0].D_raw(),
|
|
||||||
models_[1].K_raw(), models_[1].D_raw(),
|
|
||||||
imageSize, R, T, E, F,
|
|
||||||
cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 100, 1e-5),
|
|
||||||
cv::CALIB_FIX_INTRINSIC);
|
|
||||||
#else
|
|
||||||
double rms = cv::stereoCalibrate(
|
|
||||||
objectPoints,
|
|
||||||
stereoImagePoints_[0],
|
|
||||||
stereoImagePoints_[1],
|
|
||||||
models_[0].K_raw(), models_[0].D_raw(),
|
|
||||||
models_[1].K_raw(), models_[1].D_raw(),
|
|
||||||
imageSize, R, T, E, F,
|
|
||||||
cv::CALIB_FIX_INTRINSIC,
|
|
||||||
cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 100, 1e-5));
|
|
||||||
#endif
|
|
||||||
UINFO("stereo calibration... done with RMS error=%f", rms);
|
|
||||||
|
|
||||||
std::cout << "R = " << R << std::endl;
|
|
||||||
std::cout << "T = " << T << std::endl;
|
|
||||||
std::cout << "E = " << E << std::endl;
|
|
||||||
std::cout << "F = " << F << std::endl;
|
|
||||||
|
|
||||||
if(imageSize_[0] == imageSize_[1])
|
|
||||||
{
|
|
||||||
//Stereo, compute stereo rectification
|
|
||||||
|
|
||||||
cv::Mat R1, R2, P1, P2, Q;
|
|
||||||
cv::stereoRectify(models_[0].K_raw(), models_[0].D_raw(),
|
|
||||||
models_[1].K_raw(), models_[1].D_raw(),
|
|
||||||
imageSize, R, T, R1, R2, P1, P2, Q,
|
|
||||||
cv::CALIB_ZERO_DISPARITY, 0, imageSize);
|
|
||||||
|
|
||||||
double err = 0;
|
|
||||||
int npoints = 0;
|
|
||||||
std::vector<cv::Vec3f> lines[2];
|
|
||||||
UINFO("Computing avg re-projection error...");
|
|
||||||
for(unsigned int i = 0; i < stereoImagePoints_[0].size(); i++ )
|
|
||||||
{
|
|
||||||
int npt = (int)stereoImagePoints_[0][i].size();
|
|
||||||
|
|
||||||
cv::Mat imgpt0 = cv::Mat(stereoImagePoints_[0][i]);
|
|
||||||
cv::Mat imgpt1 = cv::Mat(stereoImagePoints_[1][i]);
|
|
||||||
cv::undistortPoints(imgpt0, imgpt0, models_[0].K_raw(), models_[0].D_raw(), R1, P1);
|
|
||||||
cv::undistortPoints(imgpt1, imgpt1, models_[1].K_raw(), models_[1].D_raw(), R2, P2);
|
|
||||||
computeCorrespondEpilines(imgpt0, 1, F, lines[0]);
|
|
||||||
computeCorrespondEpilines(imgpt1, 2, F, lines[1]);
|
|
||||||
|
|
||||||
for(int j = 0; j < npt; j++ )
|
|
||||||
{
|
|
||||||
double errij = fabs(stereoImagePoints_[0][i][j].x*lines[1][j][0] +
|
|
||||||
stereoImagePoints_[0][i][j].y*lines[1][j][1] + lines[1][j][2]) +
|
|
||||||
fabs(stereoImagePoints_[1][i][j].x*lines[0][j][0] +
|
|
||||||
stereoImagePoints_[1][i][j].y*lines[0][j][1] + lines[0][j][2]);
|
|
||||||
err += errij;
|
|
||||||
}
|
|
||||||
npoints += npt;
|
|
||||||
}
|
|
||||||
double totalAvgErr = err/(double)npoints;
|
|
||||||
UINFO("stereo avg re projection error = %f", totalAvgErr);
|
|
||||||
|
|
||||||
stereoModel_ = StereoCameraModel(
|
|
||||||
cameraName_.toStdString(),
|
|
||||||
imageSize_[0], models_[0].K_raw(), models_[0].D_raw(), R1, P1,
|
|
||||||
imageSize_[1], models_[1].K_raw(), models_[1].D_raw(), R2, P2,
|
|
||||||
R, T, E, F);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Kinect, ignore the stereo rectification
|
|
||||||
stereoModel_ = StereoCameraModel(
|
|
||||||
cameraName_.toStdString(),
|
|
||||||
imageSize_[0], models_[0].K_raw(), models_[0].D_raw(), models_[0].R(), models_[0].P(),
|
|
||||||
imageSize_[1], models_[1].K_raw(), models_[1].D_raw(), models_[1].R(), models_[1].P(),
|
|
||||||
R, T, E, F);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream strR1, strP1, strR2, strP2;
|
std::stringstream strR1, strP1, strR2, strP2;
|
||||||
strR1 << stereoModel_.left().R();
|
strR1 << stereoModel_.left().R();
|
||||||
@@ -902,6 +822,127 @@ void CalibrationDialog::calibrate()
|
|||||||
processingData_ = false;
|
processingData_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StereoCameraModel CalibrationDialog::stereoCalibration(const CameraModel & left, const CameraModel & right, bool ignoreStereoRectification) const
|
||||||
|
{
|
||||||
|
StereoCameraModel output;
|
||||||
|
if(stereoImagePoints_[0].empty())
|
||||||
|
{
|
||||||
|
UERROR("No stereo correspondences!");
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
UINFO("stereo calibration (samples=%d)...", (int)stereoImagePoints_[0].size());
|
||||||
|
|
||||||
|
if(left.imageSize()!=imageSize_[0])
|
||||||
|
{
|
||||||
|
UERROR("left model (%dx%d) has not the same size as the processed images (%dx%d)",
|
||||||
|
left.imageSize().width, left.imageSize().height,
|
||||||
|
imageSize_[0].width, imageSize_[0].height);
|
||||||
|
}
|
||||||
|
if(right.imageSize()!=imageSize_[1])
|
||||||
|
{
|
||||||
|
UERROR("right model (%dx%d) has not the same size as the processed images (%dx%d)",
|
||||||
|
right.imageSize().width, right.imageSize().height,
|
||||||
|
imageSize_[1].width, imageSize_[1].height);
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Size imageSize = imageSize_[0].width > imageSize_[1].width?imageSize_[0]:imageSize_[1];
|
||||||
|
cv::Mat R, T, E, F;
|
||||||
|
|
||||||
|
std::vector<std::vector<cv::Point3f> > objectPoints(1);
|
||||||
|
cv::Size boardSize(ui_->spinBox_boardWidth->value(), ui_->spinBox_boardHeight->value());
|
||||||
|
float squareSize = ui_->doubleSpinBox_squareSize->value();
|
||||||
|
// compute board corner positions
|
||||||
|
for( int i = 0; i < boardSize.height; ++i )
|
||||||
|
for( int j = 0; j < boardSize.width; ++j )
|
||||||
|
objectPoints[0].push_back(cv::Point3f(float( j*squareSize ), float( i*squareSize ), 0));
|
||||||
|
objectPoints.resize(stereoImagePoints_[0].size(), objectPoints[0]);
|
||||||
|
|
||||||
|
// calibrate extrinsic
|
||||||
|
#if CV_MAJOR_VERSION < 3
|
||||||
|
double rms = cv::stereoCalibrate(
|
||||||
|
objectPoints,
|
||||||
|
stereoImagePoints_[0],
|
||||||
|
stereoImagePoints_[1],
|
||||||
|
left.K_raw(), left.D_raw(),
|
||||||
|
right.K_raw(), right.D_raw(),
|
||||||
|
imageSize, R, T, E, F,
|
||||||
|
cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 100, 1e-5),
|
||||||
|
cv::CALIB_FIX_INTRINSIC);
|
||||||
|
#else
|
||||||
|
double rms = cv::stereoCalibrate(
|
||||||
|
objectPoints,
|
||||||
|
stereoImagePoints_[0],
|
||||||
|
stereoImagePoints_[1],
|
||||||
|
left.K_raw(), left.D_raw(),
|
||||||
|
right.K_raw(), right.D_raw(),
|
||||||
|
imageSize, R, T, E, F,
|
||||||
|
cv::CALIB_FIX_INTRINSIC,
|
||||||
|
cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 100, 1e-5));
|
||||||
|
#endif
|
||||||
|
UINFO("stereo calibration... done with RMS error=%f", rms);
|
||||||
|
|
||||||
|
std::cout << "R = " << R << std::endl;
|
||||||
|
std::cout << "T = " << T << std::endl;
|
||||||
|
std::cout << "E = " << E << std::endl;
|
||||||
|
std::cout << "F = " << F << std::endl;
|
||||||
|
|
||||||
|
if(imageSize_[0] == imageSize_[1] && !ignoreStereoRectification)
|
||||||
|
{
|
||||||
|
UINFO("Compute stereo rectification");
|
||||||
|
|
||||||
|
cv::Mat R1, R2, P1, P2, Q;
|
||||||
|
cv::stereoRectify(left.K_raw(), left.D_raw(),
|
||||||
|
right.K_raw(), right.D_raw(),
|
||||||
|
imageSize, R, T, R1, R2, P1, P2, Q,
|
||||||
|
cv::CALIB_ZERO_DISPARITY, 0, imageSize);
|
||||||
|
|
||||||
|
double err = 0;
|
||||||
|
int npoints = 0;
|
||||||
|
std::vector<cv::Vec3f> lines[2];
|
||||||
|
UINFO("Computing avg re-projection error...");
|
||||||
|
for(unsigned int i = 0; i < stereoImagePoints_[0].size(); i++ )
|
||||||
|
{
|
||||||
|
int npt = (int)stereoImagePoints_[0][i].size();
|
||||||
|
|
||||||
|
cv::Mat imgpt0 = cv::Mat(stereoImagePoints_[0][i]);
|
||||||
|
cv::Mat imgpt1 = cv::Mat(stereoImagePoints_[1][i]);
|
||||||
|
cv::undistortPoints(imgpt0, imgpt0, left.K_raw(), left.D_raw(), R1, P1);
|
||||||
|
cv::undistortPoints(imgpt1, imgpt1, right.K_raw(), right.D_raw(), R2, P2);
|
||||||
|
computeCorrespondEpilines(imgpt0, 1, F, lines[0]);
|
||||||
|
computeCorrespondEpilines(imgpt1, 2, F, lines[1]);
|
||||||
|
|
||||||
|
for(int j = 0; j < npt; j++ )
|
||||||
|
{
|
||||||
|
double errij = fabs(stereoImagePoints_[0][i][j].x*lines[1][j][0] +
|
||||||
|
stereoImagePoints_[0][i][j].y*lines[1][j][1] + lines[1][j][2]) +
|
||||||
|
fabs(stereoImagePoints_[1][i][j].x*lines[0][j][0] +
|
||||||
|
stereoImagePoints_[1][i][j].y*lines[0][j][1] + lines[0][j][2]);
|
||||||
|
err += errij;
|
||||||
|
}
|
||||||
|
npoints += npt;
|
||||||
|
}
|
||||||
|
double totalAvgErr = err/(double)npoints;
|
||||||
|
UINFO("stereo avg re projection error = %f", totalAvgErr);
|
||||||
|
|
||||||
|
output = StereoCameraModel(
|
||||||
|
cameraName_.toStdString(),
|
||||||
|
imageSize_[0], left.K_raw(), left.D_raw(), R1, P1,
|
||||||
|
imageSize_[1], right.K_raw(), right.D_raw(), R2, P2,
|
||||||
|
R, T, E, F);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UDEBUG("%s", cameraName_.toStdString().c_str());
|
||||||
|
//Kinect, ignore the stereo rectification
|
||||||
|
output = StereoCameraModel(
|
||||||
|
cameraName_.toStdString(),
|
||||||
|
imageSize_[0], left.K_raw(), left.D_raw(), left.R(), left.P(),
|
||||||
|
imageSize_[1], right.K_raw(), right.D_raw(), right.R(), right.P(),
|
||||||
|
R, T, E, F);
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
bool CalibrationDialog::save()
|
bool CalibrationDialog::save()
|
||||||
{
|
{
|
||||||
bool saved = false;
|
bool saved = false;
|
||||||
@@ -941,10 +982,11 @@ bool CalibrationDialog::save()
|
|||||||
QString dir = QFileInfo(filePath).absoluteDir().absolutePath();
|
QString dir = QFileInfo(filePath).absoluteDir().absolutePath();
|
||||||
if(!name.isEmpty())
|
if(!name.isEmpty())
|
||||||
{
|
{
|
||||||
stereoModel_.setName(name.toStdString());
|
bool switched = ui_->checkBox_switchImages->isChecked();
|
||||||
|
stereoModel_.setName(name.toStdString(), switched?rightSuffix_.toStdString():leftSuffix_.toStdString(), switched?leftSuffix_.toStdString():rightSuffix_.toStdString());
|
||||||
std::string base = (dir+QDir::separator()+name).toStdString();
|
std::string base = (dir+QDir::separator()+name).toStdString();
|
||||||
std::string leftPath = base+"_left.yaml";
|
std::string leftPath = base+"_"+stereoModel_.getLeftSuffix()+".yaml";
|
||||||
std::string rightPath = base+"_right.yaml";
|
std::string rightPath = base+"_"+stereoModel_.getRightSuffix()+".yaml";
|
||||||
std::string posePath = base+"_pose.yaml";
|
std::string posePath = base+"_pose.yaml";
|
||||||
if(stereoModel_.save(dir.toStdString(), false))
|
if(stereoModel_.save(dir.toStdString(), false))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4091,7 +4091,7 @@ int PreferencesDialog::getSourceScanNormalsK() const
|
|||||||
return _ui->spinBox_cameraImages_scanNormalsK->value();
|
return _ui->spinBox_cameraImages_scanNormalsK->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
Camera * PreferencesDialog::createCamera(bool useRawImages)
|
Camera * PreferencesDialog::createCamera(bool useRawImages, bool useColor)
|
||||||
{
|
{
|
||||||
Src driver = this->getSourceDriver();
|
Src driver = this->getSourceDriver();
|
||||||
Camera * camera = 0;
|
Camera * camera = 0;
|
||||||
@@ -4114,37 +4114,19 @@ Camera * PreferencesDialog::createCamera(bool useRawImages)
|
|||||||
}
|
}
|
||||||
else if(driver == PreferencesDialog::kSrcOpenNI2)
|
else if(driver == PreferencesDialog::kSrcOpenNI2)
|
||||||
{
|
{
|
||||||
if(useRawImages)
|
camera = new CameraOpenNI2(
|
||||||
{
|
_ui->lineEdit_openni2OniPath->text().isEmpty()?this->getSourceDevice().toStdString():_ui->lineEdit_openni2OniPath->text().toStdString(),
|
||||||
QMessageBox::warning(this, tr("Calibration"),
|
useColor?CameraOpenNI2::kTypeColorDepth:CameraOpenNI2::kTypeIRDepth,
|
||||||
tr("Using raw images for \"OpenNI2\" driver is not yet supported. "
|
this->getGeneralInputRate(),
|
||||||
"Factory calibration loaded from OpenNI2 is used."), QMessageBox::Ok);
|
this->getSourceLocalTransform());
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
camera = new CameraOpenNI2(
|
|
||||||
_ui->lineEdit_openni2OniPath->text().isEmpty()?this->getSourceDevice().toStdString():_ui->lineEdit_openni2OniPath->text().toStdString(),
|
|
||||||
this->getGeneralInputRate(),
|
|
||||||
this->getSourceLocalTransform());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(driver == PreferencesDialog::kSrcFreenect)
|
else if(driver == PreferencesDialog::kSrcFreenect)
|
||||||
{
|
{
|
||||||
if(useRawImages)
|
camera = new CameraFreenect(
|
||||||
{
|
this->getSourceDevice().isEmpty()?0:atoi(this->getSourceDevice().toStdString().c_str()),
|
||||||
QMessageBox::warning(this, tr("Calibration"),
|
useColor?CameraFreenect::kTypeColorDepth:CameraFreenect::kTypeIRDepth,
|
||||||
tr("Using raw images for \"Freenect\" driver is not yet supported. "
|
this->getGeneralInputRate(),
|
||||||
"Factory calibration loaded from Freenect is used."), QMessageBox::Ok);
|
this->getSourceLocalTransform());
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
camera = new CameraFreenect(
|
|
||||||
this->getSourceDevice().isEmpty()?0:atoi(this->getSourceDevice().toStdString().c_str()),
|
|
||||||
this->getGeneralInputRate(),
|
|
||||||
this->getSourceLocalTransform());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(driver == PreferencesDialog::kSrcOpenNI_CV ||
|
else if(driver == PreferencesDialog::kSrcOpenNI_CV ||
|
||||||
driver == PreferencesDialog::kSrcOpenNI_CV_ASUS)
|
driver == PreferencesDialog::kSrcOpenNI_CV_ASUS)
|
||||||
@@ -4179,12 +4161,22 @@ Camera * PreferencesDialog::createCamera(bool useRawImages)
|
|||||||
}
|
}
|
||||||
else if (driver == kSrcRealSense)
|
else if (driver == kSrcRealSense)
|
||||||
{
|
{
|
||||||
camera = new CameraRealSense(
|
if(useRawImages)
|
||||||
this->getSourceDevice().isEmpty() ? 0 : atoi(this->getSourceDevice().toStdString().c_str()),
|
{
|
||||||
_ui->comboBox_realsensePresetRGB->currentIndex(),
|
QMessageBox::warning(this, tr("Calibration"),
|
||||||
_ui->comboBox_realsensePresetDepth->currentIndex(),
|
tr("Using raw images for \"RealSense\" driver is not yet supported. "
|
||||||
this->getGeneralInputRate(),
|
"Factory calibration loaded from RealSense is used."), QMessageBox::Ok);
|
||||||
this->getSourceLocalTransform());
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
camera = new CameraRealSense(
|
||||||
|
this->getSourceDevice().isEmpty() ? 0 : atoi(this->getSourceDevice().toStdString().c_str()),
|
||||||
|
_ui->comboBox_realsensePresetRGB->currentIndex(),
|
||||||
|
_ui->comboBox_realsensePresetDepth->currentIndex(),
|
||||||
|
this->getGeneralInputRate(),
|
||||||
|
this->getSourceLocalTransform());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(driver == kSrcRGBDImages)
|
else if(driver == kSrcRGBDImages)
|
||||||
{
|
{
|
||||||
@@ -4372,12 +4364,11 @@ Camera * PreferencesDialog::createCamera(bool useRawImages)
|
|||||||
|
|
||||||
if(camera)
|
if(camera)
|
||||||
{
|
{
|
||||||
// don't set calibration folder if we want raw images
|
|
||||||
QString dir = this->getCameraInfoDir();
|
QString dir = this->getCameraInfoDir();
|
||||||
QString calibrationFile = _ui->lineEdit_calibrationFile->text();
|
QString calibrationFile = _ui->lineEdit_calibrationFile->text();
|
||||||
if(!(driver >= kSrcRGB && driver <= kSrcVideo))
|
if(!(driver >= kSrcRGB && driver <= kSrcVideo))
|
||||||
{
|
{
|
||||||
calibrationFile.remove("_left.yaml").remove("_right.yaml").remove("_pose.yaml");
|
calibrationFile.remove("_left.yaml").remove("_right.yaml").remove("_pose.yaml").remove("_rgb.yaml").remove("_depth.yaml");
|
||||||
}
|
}
|
||||||
QString name = QFileInfo(calibrationFile.remove(".yaml")).baseName();
|
QString name = QFileInfo(calibrationFile.remove(".yaml")).baseName();
|
||||||
if(!_ui->lineEdit_calibrationFile->text().isEmpty())
|
if(!_ui->lineEdit_calibrationFile->text().isEmpty())
|
||||||
@@ -4389,6 +4380,7 @@ Camera * PreferencesDialog::createCamera(bool useRawImages)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// don't set calibration folder if we want raw images
|
||||||
if(!camera->init(useRawImages?"":dir.toStdString(), name.toStdString()))
|
if(!camera->init(useRawImages?"":dir.toStdString(), name.toStdString()))
|
||||||
{
|
{
|
||||||
UWARN("init camera failed... ");
|
UWARN("init camera failed... ");
|
||||||
@@ -4642,11 +4634,6 @@ void PreferencesDialog::calibrate()
|
|||||||
tr("Cannot calibrate database source!"));
|
tr("Cannot calibrate database source!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Camera * camera = this->createCamera(true);
|
|
||||||
if(!camera)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!this->getCameraInfoDir().isEmpty())
|
if(!this->getCameraInfoDir().isEmpty())
|
||||||
{
|
{
|
||||||
@@ -4660,20 +4647,195 @@ void PreferencesDialog::calibrate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_calibrationDialog->setStereoMode(this->getSourceType() != kSrcRGB); // RGB+Depth or left+right
|
|
||||||
_calibrationDialog->setSwitchedImages(dynamic_cast<CameraFreenect2*>(camera) != 0);
|
|
||||||
_calibrationDialog->setSavingDirectory(this->getCameraInfoDir());
|
|
||||||
_calibrationDialog->registerToEventsManager();
|
|
||||||
|
|
||||||
CameraThread cameraThread(camera, this->getAllParameters());
|
Src driver = this->getSourceDriver();
|
||||||
UEventsManager::createPipe(&cameraThread, _calibrationDialog, "CameraEvent");
|
if(driver == PreferencesDialog::kSrcFreenect || driver == PreferencesDialog::kSrcOpenNI2)
|
||||||
|
{
|
||||||
|
// 3 steps calibration: RGB -> IR -> Extrinsic
|
||||||
|
QMessageBox::StandardButton button = QMessageBox::question(this, tr("Calibration"),
|
||||||
|
tr("With \"%1\" driver, Color and IR cameras cannot be streamed at the "
|
||||||
|
"same time. A 3-steps calibration is required (Color -> IR -> extrinsics). We will "
|
||||||
|
"start with the Color camera calibration. Do you want to continue?").arg(this->getSourceDriverStr()),
|
||||||
|
QMessageBox::Yes | QMessageBox::No | QMessageBox::Ignore, QMessageBox::Yes);
|
||||||
|
|
||||||
cameraThread.start();
|
if(button == QMessageBox::Yes || button == QMessageBox::Ignore)
|
||||||
|
{
|
||||||
|
_calibrationDialog->setSavingDirectory(this->getCameraInfoDir());
|
||||||
|
|
||||||
_calibrationDialog->exec();
|
Camera * camera = 0;
|
||||||
_calibrationDialog->unregisterFromEventsManager();
|
|
||||||
|
|
||||||
cameraThread.join(true);
|
// Step 1: RGB
|
||||||
|
if(button != QMessageBox::Ignore)
|
||||||
|
{
|
||||||
|
camera = this->createCamera(true, true); // RAW color
|
||||||
|
if(!camera)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_calibrationDialog->setStereoMode(false); // this forces restart
|
||||||
|
_calibrationDialog->setCameraName(QString(camera->getSerial().c_str())+"_rgb");
|
||||||
|
_calibrationDialog->registerToEventsManager();
|
||||||
|
CameraThread cameraThread(camera, this->getAllParameters());
|
||||||
|
UEventsManager::createPipe(&cameraThread, _calibrationDialog, "CameraEvent");
|
||||||
|
cameraThread.start();
|
||||||
|
_calibrationDialog->exec();
|
||||||
|
_calibrationDialog->unregisterFromEventsManager();
|
||||||
|
cameraThread.join(true);
|
||||||
|
camera = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button = QMessageBox::question(this, tr("Calibration"),
|
||||||
|
tr("We will now calibrate the IR camera. Hide the IR projector with a Post-It and "
|
||||||
|
"make sure you have enough ambient IR light (e.g., external IR source or sunlight!) to see the "
|
||||||
|
"checkboard with the IR camera. Do you want to continue?"),
|
||||||
|
QMessageBox::Yes | QMessageBox::No | QMessageBox::Ignore, QMessageBox::Yes);
|
||||||
|
if(button == QMessageBox::Yes || button == QMessageBox::Ignore)
|
||||||
|
{
|
||||||
|
// Step 2: IR
|
||||||
|
if(button != QMessageBox::Ignore)
|
||||||
|
{
|
||||||
|
camera = this->createCamera(true, false); // RAW ir
|
||||||
|
if(!camera)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_calibrationDialog->setStereoMode(false); // this forces restart
|
||||||
|
_calibrationDialog->setCameraName(QString(camera->getSerial().c_str())+"_depth");
|
||||||
|
_calibrationDialog->registerToEventsManager();
|
||||||
|
CameraThread cameraThread(camera, this->getAllParameters());
|
||||||
|
UEventsManager::createPipe(&cameraThread, _calibrationDialog, "CameraEvent");
|
||||||
|
cameraThread.start();
|
||||||
|
_calibrationDialog->exec();
|
||||||
|
_calibrationDialog->unregisterFromEventsManager();
|
||||||
|
cameraThread.join(true);
|
||||||
|
camera = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button = QMessageBox::question(this, tr("Calibration"),
|
||||||
|
tr("We will now calibrate the extrinsics. Important: Make sure "
|
||||||
|
"the cameras and the checkboard don't move and that both "
|
||||||
|
"cameras can see the checkboard. We will repeat this "
|
||||||
|
"multiple times. Each time, you will have to move the camera (or "
|
||||||
|
"checkboard) for a different point of view. Do you want to "
|
||||||
|
"continue?"),
|
||||||
|
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
int totalSamples = 0;
|
||||||
|
if(button == QMessageBox::Yes)
|
||||||
|
{
|
||||||
|
totalSamples = QInputDialog::getInt(this, tr("Calibration"), tr("Samples: "), 3, 1, 99, 1, &ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ok)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
_calibrationDialog->setStereoMode(true, "depth", "rgb"); // this forces restart
|
||||||
|
_calibrationDialog->setCameraName("");
|
||||||
|
_calibrationDialog->setModal(true);
|
||||||
|
_calibrationDialog->setProgressVisibility(false);
|
||||||
|
_calibrationDialog->show();
|
||||||
|
CameraModel irModel;
|
||||||
|
CameraModel rgbModel;
|
||||||
|
for(;count < totalSamples && button == QMessageBox::Yes; )
|
||||||
|
{
|
||||||
|
// Step 3: Extrinsics
|
||||||
|
camera = this->createCamera(false, true); // Rectified color
|
||||||
|
if(!camera)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SensorData rgbData = camera->takeImage();
|
||||||
|
UASSERT(rgbData.cameraModels().size() == 1);
|
||||||
|
rgbModel = rgbData.cameraModels()[0];
|
||||||
|
delete camera;
|
||||||
|
camera = this->createCamera(false, false); // Rectified ir
|
||||||
|
if(!camera)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SensorData irData = camera->takeImage();
|
||||||
|
std::string serial = camera->getSerial();
|
||||||
|
UASSERT(irData.cameraModels().size() == 1);
|
||||||
|
irModel = irData.cameraModels()[0];
|
||||||
|
delete camera;
|
||||||
|
|
||||||
|
if(!rgbData.imageRaw().empty() && !irData.imageRaw().empty())
|
||||||
|
{
|
||||||
|
// assume rgb sensor is on right (e.g., Kinect, Xtion Live Pro)
|
||||||
|
int pair = _calibrationDialog->getStereoPairs();
|
||||||
|
_calibrationDialog->processImages(irData.imageRaw(), rgbData.imageRaw(), serial.c_str());
|
||||||
|
if(_calibrationDialog->getStereoPairs() - pair > 0)
|
||||||
|
{
|
||||||
|
++count;
|
||||||
|
if(count < totalSamples)
|
||||||
|
{
|
||||||
|
button = QMessageBox::question(this, tr("Calibration"),
|
||||||
|
tr("A stereo pair has been taken (total=%1/%2). Move the checkboard or "
|
||||||
|
"camera to another position. Press \"Yes\" when you are ready "
|
||||||
|
"for the next capture.").arg(count).arg(totalSamples),
|
||||||
|
QMessageBox::Yes | QMessageBox::Abort, QMessageBox::Yes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
button = QMessageBox::question(this, tr("Calibration"),
|
||||||
|
tr("Could not detect the checkboard on both images or "
|
||||||
|
"the point of view didn't change enough. Try again?"),
|
||||||
|
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
button = QMessageBox::question(this, tr("Calibration"),
|
||||||
|
tr("Failed to start the camera. Try again?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(count == totalSamples && button == QMessageBox::Yes)
|
||||||
|
{
|
||||||
|
StereoCameraModel stereoModel = _calibrationDialog->stereoCalibration(irModel, rgbModel, true);
|
||||||
|
stereoModel.setName(stereoModel.name(), "depth", "rgb");
|
||||||
|
if(stereoModel.stereoTransform().isNull())
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, tr("Calibration"),
|
||||||
|
tr("Extrinsic calibration has failed!"), QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
else if(stereoModel.saveStereoTransform(this->getCameraInfoDir().toStdString()))
|
||||||
|
{
|
||||||
|
QMessageBox::information(this, tr("Calibration"),
|
||||||
|
tr("Calibration is completed! Extrinsics have been saved to \"%1/%2_pose.yaml\"").arg(this->getCameraInfoDir()).arg(stereoModel.name().c_str()), QMessageBox::Ok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // standard calibration
|
||||||
|
{
|
||||||
|
Camera * camera = this->createCamera(true);
|
||||||
|
if(!camera)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool freenect2 = this->getSourceType() == kSrcFreenect2;
|
||||||
|
_calibrationDialog->setStereoMode(this->getSourceType() != kSrcRGB, freenect2?"rgb":"left", freenect2?"depth":"right"); // RGB+Depth or left+right
|
||||||
|
_calibrationDialog->setSwitchedImages(freenect2);
|
||||||
|
_calibrationDialog->setSavingDirectory(this->getCameraInfoDir());
|
||||||
|
_calibrationDialog->registerToEventsManager();
|
||||||
|
|
||||||
|
CameraThread cameraThread(camera, this->getAllParameters());
|
||||||
|
UEventsManager::createPipe(&cameraThread, _calibrationDialog, "CameraEvent");
|
||||||
|
|
||||||
|
cameraThread.start();
|
||||||
|
|
||||||
|
_calibrationDialog->exec();
|
||||||
|
_calibrationDialog->unregisterFromEventsManager();
|
||||||
|
|
||||||
|
cameraThread.join(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreferencesDialog::calibrateSimple()
|
void PreferencesDialog::calibrateSimple()
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1314</width>
|
<width>1314</width>
|
||||||
<height>853</height>
|
<height>847</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -145,8 +145,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>371</width>
|
<width>353</width>
|
||||||
<height>822</height>
|
<height>816</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
@@ -275,463 +275,463 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_progress">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Progress</string>
|
<string>Progress</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
<item row="2" column="0">
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1,1">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_19">
|
||||||
|
<property name="text">
|
||||||
|
<string>Serial</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="label_serial">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QCheckBox" name="checkBox_switchImages">
|
||||||
|
<property name="text">
|
||||||
|
<string>Switch images</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Count</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QProgressBar" name="progressBar_count">
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
<property name="format">
|
||||||
|
<string>%p</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QProgressBar" name="progressBar_count_2">
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
<property name="invertedAppearance">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="format">
|
||||||
|
<string>%p</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>X</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QProgressBar" name="progressBar_x">
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
<property name="format">
|
||||||
|
<string>%p%</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QProgressBar" name="progressBar_x_2">
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
<property name="invertedAppearance">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textDirection">
|
||||||
|
<enum>QProgressBar::TopToBottom</enum>
|
||||||
|
</property>
|
||||||
|
<property name="format">
|
||||||
|
<string>%p%</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Y</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QProgressBar" name="progressBar_y">
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2">
|
||||||
|
<widget class="QProgressBar" name="progressBar_y_2">
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
<property name="invertedAppearance">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Size</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QProgressBar" name="progressBar_size">
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="2">
|
||||||
|
<widget class="QProgressBar" name="progressBar_size_2">
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
<property name="invertedAppearance">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Skew</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QProgressBar" name="progressBar_skew">
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="2">
|
||||||
|
<widget class="QProgressBar" name="progressBar_skew_2">
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
<property name="invertedAppearance">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="1,0">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_calibrate">
|
||||||
|
<property name="text">
|
||||||
|
<string>Calibrate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBox_unlock">
|
||||||
|
<property name="text">
|
||||||
|
<string>Unlock</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
|
<property name="title">
|
||||||
|
<string>Camera intrinsic parameters</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="label_fx">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label_fy">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_K">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLabel" name="label_cx">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_11">
|
||||||
|
<property name="text">
|
||||||
|
<string>cy</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLabel" name="label_cy">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Camera matrix</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>K</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_9">
|
||||||
|
<property name="text">
|
||||||
|
<string>fy</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_10">
|
||||||
|
<property name="text">
|
||||||
|
<string>cx</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>fx</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QLabel" name="label_17">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Distorsion coefficients</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>R</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="2">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_D_2">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Distorsion coefficients</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>D</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_D">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="0">
|
||||||
|
<widget class="QLabel" name="label_14">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Avg. reproduction error</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Error</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="1">
|
||||||
|
<widget class="QLabel" name="label_error">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QLabel" name="label_fx_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QLabel" name="label_cx_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QLabel" name="label_fy_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2">
|
||||||
|
<widget class="QLabel" name="label_cy_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="2">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_K_2">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="0">
|
||||||
|
<widget class="QLabel" name="label_18">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Distorsion coefficients</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>P</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_R">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_P">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="2">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_R_2">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="2">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_P_2">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_baseline_name">
|
||||||
|
<property name="text">
|
||||||
|
<string>baseline</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="2">
|
||||||
|
<widget class="QLabel" name="label_baseline">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="2">
|
||||||
|
<widget class="QLabel" name="label_error_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>0</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_save">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>X</string>
|
<string>Export calibration (*.yaml)</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0">
|
<item>
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QPushButton" name="pushButton_restart">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Skew</string>
|
<string>Restart</string>
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QProgressBar" name="progressBar_skew">
|
|
||||||
<property name="value">
|
|
||||||
<number>24</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QProgressBar" name="progressBar_size">
|
|
||||||
<property name="value">
|
|
||||||
<number>24</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Y</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QProgressBar" name="progressBar_count">
|
|
||||||
<property name="value">
|
|
||||||
<number>24</number>
|
|
||||||
</property>
|
|
||||||
<property name="format">
|
|
||||||
<string>%p</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QProgressBar" name="progressBar_x">
|
|
||||||
<property name="value">
|
|
||||||
<number>24</number>
|
|
||||||
</property>
|
|
||||||
<property name="format">
|
|
||||||
<string>%p%</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QProgressBar" name="progressBar_y">
|
|
||||||
<property name="value">
|
|
||||||
<number>24</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Size</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_5">
|
|
||||||
<property name="text">
|
|
||||||
<string>Count</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="2">
|
|
||||||
<widget class="QProgressBar" name="progressBar_x_2">
|
|
||||||
<property name="value">
|
|
||||||
<number>24</number>
|
|
||||||
</property>
|
|
||||||
<property name="invertedAppearance">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textDirection">
|
|
||||||
<enum>QProgressBar::TopToBottom</enum>
|
|
||||||
</property>
|
|
||||||
<property name="format">
|
|
||||||
<string>%p%</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="2">
|
|
||||||
<widget class="QProgressBar" name="progressBar_y_2">
|
|
||||||
<property name="value">
|
|
||||||
<number>24</number>
|
|
||||||
</property>
|
|
||||||
<property name="invertedAppearance">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="2">
|
|
||||||
<widget class="QProgressBar" name="progressBar_size_2">
|
|
||||||
<property name="value">
|
|
||||||
<number>24</number>
|
|
||||||
</property>
|
|
||||||
<property name="invertedAppearance">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="2">
|
|
||||||
<widget class="QProgressBar" name="progressBar_skew_2">
|
|
||||||
<property name="value">
|
|
||||||
<number>24</number>
|
|
||||||
</property>
|
|
||||||
<property name="invertedAppearance">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_19">
|
|
||||||
<property name="text">
|
|
||||||
<string>Serial</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLabel" name="label_serial">
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
|
||||||
<widget class="QProgressBar" name="progressBar_count_2">
|
|
||||||
<property name="value">
|
|
||||||
<number>24</number>
|
|
||||||
</property>
|
|
||||||
<property name="invertedAppearance">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="format">
|
|
||||||
<string>%p</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QCheckBox" name="checkBox_switchImages">
|
|
||||||
<property name="text">
|
|
||||||
<string>Switch images</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="1,0">
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pushButton_calibrate">
|
|
||||||
<property name="text">
|
|
||||||
<string>Calibrate</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="checkBox_unlock">
|
|
||||||
<property name="text">
|
|
||||||
<string>Unlock</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox_3">
|
|
||||||
<property name="title">
|
|
||||||
<string>Camera intrinsic parameters</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLabel" name="label_fx">
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLabel" name="label_fy">
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QLineEdit" name="lineEdit_K">
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLabel" name="label_cx">
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_11">
|
|
||||||
<property name="text">
|
|
||||||
<string>cy</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QLabel" name="label_cy">
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Camera matrix</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>K</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_9">
|
|
||||||
<property name="text">
|
|
||||||
<string>fy</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_10">
|
|
||||||
<property name="text">
|
|
||||||
<string>cx</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_8">
|
|
||||||
<property name="text">
|
|
||||||
<string>fx</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="0">
|
|
||||||
<widget class="QLabel" name="label_17">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Distorsion coefficients</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>R</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="2">
|
|
||||||
<widget class="QLineEdit" name="lineEdit_D_2">
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0">
|
|
||||||
<widget class="QLabel" name="label_7">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Distorsion coefficients</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>D</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="1">
|
|
||||||
<widget class="QLineEdit" name="lineEdit_D">
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="0">
|
|
||||||
<widget class="QLabel" name="label_14">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Avg. reproduction error</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Error</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="1">
|
|
||||||
<widget class="QLabel" name="label_error">
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="2">
|
|
||||||
<widget class="QLabel" name="label_fx_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="2">
|
|
||||||
<widget class="QLabel" name="label_cx_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
|
||||||
<widget class="QLabel" name="label_fy_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="2">
|
|
||||||
<widget class="QLabel" name="label_cy_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="2">
|
|
||||||
<widget class="QLineEdit" name="lineEdit_K_2">
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="8" column="0">
|
|
||||||
<widget class="QLabel" name="label_18">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Distorsion coefficients</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>P</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="1">
|
|
||||||
<widget class="QLineEdit" name="lineEdit_R">
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="8" column="1">
|
|
||||||
<widget class="QLineEdit" name="lineEdit_P">
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="2">
|
|
||||||
<widget class="QLineEdit" name="lineEdit_R_2">
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="8" column="2">
|
|
||||||
<widget class="QLineEdit" name="lineEdit_P_2">
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="label_baseline_name">
|
|
||||||
<property name="text">
|
|
||||||
<string>baseline</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="2">
|
|
||||||
<widget class="QLabel" name="label_baseline">
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="2">
|
|
||||||
<widget class="QLabel" name="label_error_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>0</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pushButton_save">
|
|
||||||
<property name="text">
|
|
||||||
<string>Export calibration (*.yaml)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pushButton_restart">
|
|
||||||
<property name="text">
|
|
||||||
<string>Restart</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ int main (int argc, char * argv[])
|
|||||||
UERROR("Not built with OpenNI2 support...");
|
UERROR("Not built with OpenNI2 support...");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
camera = new rtabmap::CameraOpenNI2(deviceId, rate, t);
|
camera = new rtabmap::CameraOpenNI2(deviceId, CameraOpenNI2::kTypeColorDepth, rate, t);
|
||||||
}
|
}
|
||||||
else if(driver == 2)
|
else if(driver == 2)
|
||||||
{
|
{
|
||||||
@@ -197,7 +197,7 @@ int main (int argc, char * argv[])
|
|||||||
UERROR("Not built with Freenect support...");
|
UERROR("Not built with Freenect support...");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
camera = new rtabmap::CameraFreenect(deviceId.size()?atoi(deviceId.c_str()):0, rate, t);
|
camera = new rtabmap::CameraFreenect(deviceId.size()?atoi(deviceId.c_str()):0, CameraFreenect::kTypeColorDepth, rate, t);
|
||||||
}
|
}
|
||||||
else if(driver == 3)
|
else if(driver == 3)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ int main (int argc, char * argv[])
|
|||||||
UERROR("Not built with OpenNI2 support...");
|
UERROR("Not built with OpenNI2 support...");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
camera = new rtabmap::CameraOpenNI2("", rate, t);
|
camera = new rtabmap::CameraOpenNI2("", rtabmap::CameraOpenNI2::kTypeColorDepth, rate, t);
|
||||||
}
|
}
|
||||||
else if(driver == 2)
|
else if(driver == 2)
|
||||||
{
|
{
|
||||||
@@ -250,7 +250,7 @@ int main (int argc, char * argv[])
|
|||||||
UERROR("Not built with Freenect support...");
|
UERROR("Not built with Freenect support...");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
camera = new rtabmap::CameraFreenect(0, rate, t);
|
camera = new rtabmap::CameraFreenect(0, rtabmap::CameraFreenect::kTypeColorDepth, rate, t);
|
||||||
}
|
}
|
||||||
else if(driver == 3)
|
else if(driver == 3)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user