Skip to content
Snippets Groups Projects
Commit c971d703 authored by Nicolas Pope's avatar Nicolas Pope
Browse files

Potentially working calibration code

parent 5a25f2ba
Branches
Tags
No related merge requests found
......@@ -33,7 +33,7 @@ endif (WIN32)
if (UNIX)
add_definitions(-DUNIX)
set(FTL_CONFIG_ROOT "$ENV{HOME}/.config/ftl")
set(FTL_CONFIG_ROOT "\"$ENV{HOME}/.config/ftl\"")
set(FTL_CACHE_ROOT "$ENV{HOME}/.cache/ftl")
set(FTL_DATA_ROOT "$ENV{HOME}/.local/share/ftl")
endif (UNIX)
......
......@@ -4,13 +4,70 @@
#include <opencv2/opencv.hpp>
#include <ftl/local.hpp>
#include <string>
#include <vector>
namespace cv {
class FileStorage;
class FileNode;
};
namespace ftl {
class Calibrate {
public:
class Settings {
public:
Settings() : goodInput(false) {}
enum Pattern { NOT_EXISTING, CHESSBOARD, CIRCLES_GRID, ASYMMETRIC_CIRCLES_GRID };
enum InputType { INVALID, CAMERA, VIDEO_FILE, IMAGE_LIST };
void write(cv::FileStorage& fs) const;
void read(const cv::FileNode& node);
void validate();
//Mat nextImage();
static bool readStringList( const std::string& filename, std::vector<std::string>& l );
static bool isListOfImages( const std::string& filename);
public:
cv::Size boardSize; // The size of the board -> Number of items by width and height
Pattern calibrationPattern; // One of the Chessboard, circles, or asymmetric circle pattern
float squareSize; // The size of a square in your defined unit (point, millimeter,etc).
int nrFrames; // The number of frames to use from the input for calibration
float aspectRatio; // The aspect ratio
int delay; // In case of a video input
bool writePoints; // Write detected feature points
bool writeExtrinsics; // Write extrinsic parameters
bool writeGrid; // Write refined 3D target grid points
bool calibZeroTangentDist; // Assume zero tangential distortion
bool calibFixPrincipalPoint; // Fix the principal point at the center
bool flipVertical; // Flip the captured images around the horizontal axis
std::string outputFileName; // The name of the file where to write
bool showUndistorsed; // Show undistorted images after calibration
std::string input; // The input ->
bool useFisheye; // use fisheye camera model for calibration
bool fixK1; // fix K1 distortion coefficient
bool fixK2; // fix K2 distortion coefficient
bool fixK3; // fix K3 distortion coefficient
bool fixK4; // fix K4 distortion coefficient
bool fixK5; // fix K5 distortion coefficient
int cameraID;
std::vector<std::string> imageList;
size_t atImageList;
//cv::VideoCapture inputCapture;
InputType inputType;
bool goodInput;
int flag;
private:
std::string patternToUse;
};
public:
Calibrate(ftl::LocalSource *s, const std::string &cal);
bool recalibrate(const std::string &conf);
bool recalibrate();
bool undistort(cv::Mat &l, cv::Mat &r);
bool rectified(cv::Mat &l, cv::Mat &r);
......@@ -19,11 +76,25 @@ class Calibrate {
private:
bool runCalibration(cv::Mat &img, cv::Mat &cam);
bool _recalibrate(size_t cam);
cv::Mat _nextImage(size_t cam);
private:
ftl::LocalSource *local_;
Settings settings_;
bool calibrated_;
std::vector<cv::Mat> map1_;
std::vector<cv::Mat> map2_;
};
};
/*static inline void read(const cv::FileNode& node, ftl::Calibrate::Settings& x, const ftl::Calibrate::Settings& default_value = ftl::Calibrate::Settings())
{
if(node.empty())
x = default_value;
else
x.read(node);
}*/
#endif // _FTL_CALIBRATION_HPP_
......@@ -14,8 +14,8 @@ class LocalSource {
LocalSource();
LocalSource(const std::string &vid);
//bool left(cv::Mat &m);
//bool right(cv::Mat &m);
bool left(cv::Mat &m);
bool right(cv::Mat &m);
bool get(cv::Mat &l, cv::Mat &r);
//void setFramerate(float fps);
......
......@@ -14,19 +14,15 @@
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <glog/logging.h>
using namespace cv;
using namespace std;
using ftl::Calibrate;
class Settings
{
public:
Settings() : goodInput(false) {}
enum Pattern { NOT_EXISTING, CHESSBOARD, CIRCLES_GRID, ASYMMETRIC_CIRCLES_GRID };
enum InputType { INVALID, CAMERA, VIDEO_FILE, IMAGE_LIST };
void write(FileStorage& fs) const //Write serialization for this class
void Calibrate::Settings::write(FileStorage& fs) const //Write serialization for this class
{
fs << "{"
<< "BoardSize_Width" << boardSize.width
......@@ -41,16 +37,16 @@ public:
<< "Write_DetectedFeaturePoints" << writePoints
<< "Write_extrinsicParameters" << writeExtrinsics
<< "Write_gridPoints" << writeGrid
<< "Write_outputFileName" << outputFileName
//<< "Write_outputFileName" << outputFileName
<< "Show_UndistortedImage" << showUndistorsed
//<< "Show_UndistortedImage" << showUndistorsed
<< "Input_FlipAroundHorizontalAxis" << flipVertical
<< "Input_Delay" << delay
<< "Input" << input
//<< "Input" << input
<< "}";
}
void read(const FileNode& node) //Read serialization for this class
void Calibrate::Settings::read(const FileNode& node) //Read serialization for this class
{
node["BoardSize_Width" ] >> boardSize.width;
node["BoardSize_Height"] >> boardSize.height;
......@@ -61,13 +57,13 @@ public:
node["Write_DetectedFeaturePoints"] >> writePoints;
node["Write_extrinsicParameters"] >> writeExtrinsics;
node["Write_gridPoints"] >> writeGrid;
node["Write_outputFileName"] >> outputFileName;
//node["Write_outputFileName"] >> outputFileName;
node["Calibrate_AssumeZeroTangentialDistortion"] >> calibZeroTangentDist;
node["Calibrate_FixPrincipalPointAtTheCenter"] >> calibFixPrincipalPoint;
node["Calibrate_UseFisheyeModel"] >> useFisheye;
node["Input_FlipAroundHorizontalAxis"] >> flipVertical;
node["Show_UndistortedImage"] >> showUndistorsed;
node["Input"] >> input;
//node["Show_UndistortedImage"] >> showUndistorsed;
//node["Input"] >> input;
node["Input_Delay"] >> delay;
node["Fix_K1"] >> fixK1;
node["Fix_K2"] >> fixK2;
......@@ -77,55 +73,22 @@ public:
validate();
}
void validate()
void Calibrate::Settings::validate()
{
goodInput = true;
if (boardSize.width <= 0 || boardSize.height <= 0)
{
cerr << "Invalid Board size: " << boardSize.width << " " << boardSize.height << endl;
LOG(ERROR) << "Invalid Board size: " << boardSize.width << " " << boardSize.height;
goodInput = false;
}
if (squareSize <= 10e-6)
{
cerr << "Invalid square size " << squareSize << endl;
LOG(ERROR) << "Invalid square size " << squareSize;
goodInput = false;
}
if (nrFrames <= 0)
{
cerr << "Invalid number of frames " << nrFrames << endl;
goodInput = false;
}
if (input.empty()) // Check for valid input
inputType = INVALID;
else
{
if (input[0] >= '0' && input[0] <= '9')
{
stringstream ss(input);
ss >> cameraID;
inputType = CAMERA;
}
else
{
if (isListOfImages(input) && readStringList(input, imageList))
{
inputType = IMAGE_LIST;
nrFrames = (nrFrames < (int)imageList.size()) ? nrFrames : (int)imageList.size();
}
else
inputType = VIDEO_FILE;
}
if (inputType == CAMERA)
inputCapture.open(cameraID);
if (inputType == VIDEO_FILE)
inputCapture.open(input);
if (inputType != IMAGE_LIST && !inputCapture.isOpened())
inputType = INVALID;
}
if (inputType == INVALID)
{
cerr << " Input does not exist: " << input;
LOG(ERROR) << "Invalid number of frames " << nrFrames;
goodInput = false;
}
......@@ -155,28 +118,24 @@ public:
if (!patternToUse.compare("ASYMMETRIC_CIRCLES_GRID")) calibrationPattern = ASYMMETRIC_CIRCLES_GRID;
if (calibrationPattern == NOT_EXISTING)
{
cerr << " Camera calibration mode does not exist: " << patternToUse << endl;
LOG(ERROR) << " Camera calibration mode does not exist: " << patternToUse;
goodInput = false;
}
atImageList = 0;
}
Mat nextImage()
Mat Calibrate::_nextImage(size_t cam)
{
Mat result;
if( inputCapture.isOpened() )
{
Mat view0;
inputCapture >> view0;
view0.copyTo(result);
if (cam == 0) {
local_->left(result);
} else if (cam == 1 && local_->isStereo()) {
local_->right(result);
}
else if( atImageList < imageList.size() )
result = imread(imageList[atImageList++], IMREAD_COLOR);
return result;
}
static bool readStringList( const string& filename, vector<string>& l )
bool Calibrate::Settings::readStringList( const string& filename, vector<string>& l )
{
l.clear();
FileStorage fs(filename, FileStorage::READ);
......@@ -191,7 +150,7 @@ public:
return true;
}
static bool isListOfImages( const string& filename)
bool Calibrate::Settings::isListOfImages( const string& filename)
{
string s(filename);
// Look for file extension
......@@ -200,150 +159,93 @@ public:
else
return true;
}
public:
Size boardSize; // The size of the board -> Number of items by width and height
Pattern calibrationPattern; // One of the Chessboard, circles, or asymmetric circle pattern
float squareSize; // The size of a square in your defined unit (point, millimeter,etc).
int nrFrames; // The number of frames to use from the input for calibration
float aspectRatio; // The aspect ratio
int delay; // In case of a video input
bool writePoints; // Write detected feature points
bool writeExtrinsics; // Write extrinsic parameters
bool writeGrid; // Write refined 3D target grid points
bool calibZeroTangentDist; // Assume zero tangential distortion
bool calibFixPrincipalPoint; // Fix the principal point at the center
bool flipVertical; // Flip the captured images around the horizontal axis
string outputFileName; // The name of the file where to write
bool showUndistorsed; // Show undistorted images after calibration
string input; // The input ->
bool useFisheye; // use fisheye camera model for calibration
bool fixK1; // fix K1 distortion coefficient
bool fixK2; // fix K2 distortion coefficient
bool fixK3; // fix K3 distortion coefficient
bool fixK4; // fix K4 distortion coefficient
bool fixK5; // fix K5 distortion coefficient
int cameraID;
vector<string> imageList;
size_t atImageList;
VideoCapture inputCapture;
InputType inputType;
bool goodInput;
int flag;
private:
string patternToUse;
};
static inline void read(const FileNode& node, Settings& x, const Settings& default_value = Settings())
{
if(node.empty())
x = default_value;
else
x.read(node);
}
Calibrate::Calibrate(ftl::LocalSource *s, const std::string &cal) : local_(s) {
}
bool Calibrate::recalibrate(const std::string &conf) {
return false;
}
enum { DETECTION = 0, CAPTURING = 1, CALIBRATED = 2 };
bool Calibrate::undistort(cv::Mat &l, cv::Mat &r) {
local_->get(l,r);
return false;
}
bool runCalibrationAndSave(Calibrate::Settings& s, Size imageSize, Mat& cameraMatrix, Mat& distCoeffs,
vector<vector<Point2f> > imagePoints, float grid_width, bool release_object);
bool Calibrate::rectified(cv::Mat &l, cv::Mat &r) {
return undistort(l,r);
}
bool Calibrate::isCalibrated() {
return false;
Calibrate::Calibrate(ftl::LocalSource *s, const std::string &cal) : local_(s) {
FileStorage fs(cal, FileStorage::READ); // Read the settings
if (!fs.isOpened())
{
LOG(ERROR) << "Could not open the configuration file: \"" << cal << "\"";
return;
}
//fs["Settings"] >> settings_;
settings_.read(fs["Settings"]);
fs.release();
enum { DETECTION = 0, CAPTURING = 1, CALIBRATED = 2 };
bool runCalibrationAndSave(Settings& s, Size imageSize, Mat& cameraMatrix, Mat& distCoeffs,
vector<vector<Point2f> > imagePoints, float grid_width, bool release_object);
int main2(int argc, char* argv[])
if (!settings_.goodInput)
{
LOG(ERROR) << "Invalid input detected. Application stopping.";
return;
}
map1_.resize(2);
map2_.resize(2);
//! [file_read]
Settings s;
const string inputSettingsFile = parser.get<string>(0);
FileStorage fs(inputSettingsFile, FileStorage::READ); // Read the settings
if (!fs.isOpened())
{
cout << "Could not open the configuration file: \"" << inputSettingsFile << "\"" << endl;
parser.printMessage();
return -1;
calibrated_ = false;
}
fs["Settings"] >> s;
fs.release(); // close Settings file
//! [file_read]
//FileStorage fout("settings.yml", FileStorage::WRITE); // write config as YAML
//fout << "Settings" << s;
bool Calibrate::recalibrate() {
bool r = _recalibrate(0);
if (local_->isStereo()) r |= _recalibrate(1);
if (!s.goodInput)
{
cout << "Invalid input detected. Application stopping. " << endl;
return -1;
if (r) calibrated_ = true;
return r;
}
int winSize = parser.get<int>("winSize");
bool Calibrate::_recalibrate(size_t cam) {
// TODO WHAT IS WINSIZE!!
int winSize = 11; //parser.get<int>("winSize");
float grid_width = s.squareSize * (s.boardSize.width - 1);
float grid_width = settings_.squareSize * (settings_.boardSize.width - 1);
bool release_object = false;
if (parser.has("d")) {
grid_width = parser.get<float>("d");
release_object = true;
}
vector<vector<Point2f> > imagePoints;
Mat cameraMatrix, distCoeffs;
Size imageSize;
int mode = s.inputType == Settings::IMAGE_LIST ? CAPTURING : DETECTION;
int mode = CAPTURING;
clock_t prevTimestamp = 0;
const Scalar RED(0,0,255), GREEN(0,255,0);
const char ESC_KEY = 27;
settings_.outputFileName = string(FTL_CONFIG_ROOT "/calib_cam") + std::to_string(cam) + ".yml";
//! [get_input]
for(;;)
{
Mat view;
bool blinkOutput = false;
//bool blinkOutput = false;
view = s.nextImage();
view = _nextImage(cam);
LOG(INFO) << "Grabbing calibration image...";
//----- If no more image, or got enough, then stop calibration and show result -------------
if( mode == CAPTURING && imagePoints.size() >= (size_t)s.nrFrames )
if( mode == CAPTURING && imagePoints.size() >= (size_t)settings_.nrFrames )
{
if(runCalibrationAndSave(s, imageSize, cameraMatrix, distCoeffs, imagePoints, grid_width,
release_object))
if(runCalibrationAndSave(settings_, imageSize, cameraMatrix, distCoeffs, imagePoints, grid_width,
release_object)) {
LOG(INFO) << "Calibration completed";
mode = CALIBRATED;
else
} else
mode = DETECTION;
}
if(view.empty()) // If there are no more images stop the loop
{
LOG(INFO) << "More calibration images are required";
// if calibration threshold was not reached yet, calibrate now
if( mode != CALIBRATED && !imagePoints.empty() )
runCalibrationAndSave(s, imageSize, cameraMatrix, distCoeffs, imagePoints, grid_width,
runCalibrationAndSave(settings_, imageSize, cameraMatrix, distCoeffs, imagePoints, grid_width,
release_object);
break;
}
//! [get_input]
imageSize = view.size(); // Format input image.
if( s.flipVertical ) flip( view, view, 0 );
if( settings_.flipVertical ) flip( view, view, 0 );
//! [find_pattern]
vector<Point2f> pointBuf;
......@@ -352,21 +254,21 @@ int main2(int argc, char* argv[])
int chessBoardFlags = CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE;
if(!s.useFisheye) {
if(!settings_.useFisheye) {
// fast check erroneously fails with high distortions like fisheye
chessBoardFlags |= CALIB_CB_FAST_CHECK;
}
switch( s.calibrationPattern ) // Find feature points on the input format
switch( settings_.calibrationPattern ) // Find feature points on the input format
{
case Settings::CHESSBOARD:
found = findChessboardCorners( view, s.boardSize, pointBuf, chessBoardFlags);
found = findChessboardCorners( view, settings_.boardSize, pointBuf, chessBoardFlags);
break;
case Settings::CIRCLES_GRID:
found = findCirclesGrid( view, s.boardSize, pointBuf );
found = findCirclesGrid( view, settings_.boardSize, pointBuf );
break;
case Settings::ASYMMETRIC_CIRCLES_GRID:
found = findCirclesGrid( view, s.boardSize, pointBuf, CALIB_CB_ASYMMETRIC_GRID );
found = findCirclesGrid( view, settings_.boardSize, pointBuf, CALIB_CB_ASYMMETRIC_GRID );
break;
default:
found = false;
......@@ -377,7 +279,7 @@ int main2(int argc, char* argv[])
if ( found) // If done with success,
{
// improve the found corners' coordinate accuracy for chessboard
if( s.calibrationPattern == Settings::CHESSBOARD)
if( settings_.calibrationPattern == Settings::CHESSBOARD)
{
Mat viewGray;
cvtColor(view, viewGray, COLOR_BGR2GRAY);
......@@ -386,20 +288,22 @@ int main2(int argc, char* argv[])
}
if( mode == CAPTURING && // For camera only take new samples after delay time
(!s.inputCapture.isOpened() || clock() - prevTimestamp > s.delay*1e-3*CLOCKS_PER_SEC) )
(clock() - prevTimestamp > settings_.delay*1e-3*CLOCKS_PER_SEC) )
{
imagePoints.push_back(pointBuf);
prevTimestamp = clock();
blinkOutput = s.inputCapture.isOpened();
// blinkOutput = s.inputCapture.isOpened();
}
// Draw the corners.
drawChessboardCorners( view, s.boardSize, Mat(pointBuf), found );
drawChessboardCorners( view, settings_.boardSize, Mat(pointBuf), found );
} else {
LOG(WARNING) << "No calibration pattern found";
}
//! [pattern_found]
//----------------------------- Output Text ------------------------------------------------
//! [output_text]
string msg = (mode == CAPTURING) ? "100/100" :
/*string msg = (mode == CAPTURING) ? "100/100" :
mode == CALIBRATED ? "Calibrated" : "Press 'g' to start";
int baseLine = 0;
Size textSize = getTextSize(msg, 1, 1, 1, &baseLine);
......@@ -416,75 +320,76 @@ int main2(int argc, char* argv[])
putText( view, msg, textOrigin, 1, 1, mode == CALIBRATED ? GREEN : RED);
if( blinkOutput )
bitwise_not(view, view);
bitwise_not(view, view);*/
//! [output_text]
//------------------------- Video capture output undistorted ------------------------------
//! [output_undistorted]
if( mode == CALIBRATED && s.showUndistorsed )
/*if( mode == CALIBRATED && settings_.showUndistorsed )
{
Mat temp = view.clone();
if (s.useFisheye)
if (settings_.useFisheye)
cv::fisheye::undistortImage(temp, view, cameraMatrix, distCoeffs);
else
undistort(temp, view, cameraMatrix, distCoeffs);
}
cv::undistort(temp, view, cameraMatrix, distCoeffs);
}*/
//! [output_undistorted]
//------------------------------ Show image and check for input commands -------------------
//! [await_input]
imshow("Image View", view);
/*imshow("Image View", view);
char key = (char)waitKey(s.inputCapture.isOpened() ? 50 : s.delay);
if( key == ESC_KEY )
break;
if( key == 'u' && mode == CALIBRATED )
s.showUndistorsed = !s.showUndistorsed;
s.showUndistorsed = !s.showUndistorsed;*/
if( s.inputCapture.isOpened() && key == 'g' )
/*if( s.inputCapture.isOpened() && key == 'g' )
{
mode = CAPTURING;
imagePoints.clear();
}
}*/
//! [await_input]
if (mode == CALIBRATED) break;
}
// -----------------------Show the undistorted image for the image list ------------------------
//! [show_results]
if( s.inputType == Settings::IMAGE_LIST && s.showUndistorsed )
{
Mat view, rview, map1, map2;
if (mode != CALIBRATED) return false;
if (s.useFisheye)
Mat view, rview;
if (settings_.useFisheye)
{
Mat newCamMat;
fisheye::estimateNewCameraMatrixForUndistortRectify(cameraMatrix, distCoeffs, imageSize,
Matx33d::eye(), newCamMat, 1);
fisheye::initUndistortRectifyMap(cameraMatrix, distCoeffs, Matx33d::eye(), newCamMat, imageSize,
CV_16SC2, map1, map2);
CV_16SC2, map1_[cam], map2_[cam]);
}
else
{
initUndistortRectifyMap(
cameraMatrix, distCoeffs, Mat(),
getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, 1, imageSize, 0), imageSize,
CV_16SC2, map1, map2);
CV_16SC2, map1_[cam], map2_[cam]);
}
return true;
}
for(size_t i = 0; i < s.imageList.size(); i++ )
{
view = imread(s.imageList[i], IMREAD_COLOR);
if(view.empty())
continue;
remap(view, rview, map1, map2, INTER_LINEAR);
imshow("Image View", rview);
char c = (char)waitKey();
if( c == ESC_KEY || c == 'q' || c == 'Q' )
break;
bool Calibrate::undistort(cv::Mat &l, cv::Mat &r) {
local_->get(l,r);
if (!calibrated_) return false;
if (l.empty()) return false;
remap(l, l, map1_[0], map2_[0], INTER_LINEAR);
if (local_->isStereo()) remap(r, r, map1_[1], map2_[1], INTER_LINEAR);
return true;
}
bool Calibrate::rectified(cv::Mat &l, cv::Mat &r) {
return undistort(l,r);
}
//! [show_results]
return 0;
bool Calibrate::isCalibrated() {
return calibrated_;
}
//! [compute_errors]
......@@ -523,20 +428,20 @@ static double computeReprojectionErrors( const vector<vector<Point3f> >& objectP
//! [compute_errors]
//! [board_corners]
static void calcBoardCornerPositions(Size boardSize, float squareSize, vector<Point3f>& corners,
Settings::Pattern patternType /*= Settings::CHESSBOARD*/)
Calibrate::Settings::Pattern patternType /*= Settings::CHESSBOARD*/)
{
corners.clear();
switch(patternType)
{
case Settings::CHESSBOARD:
case Settings::CIRCLES_GRID:
case Calibrate::Settings::CHESSBOARD:
case Calibrate::Settings::CIRCLES_GRID:
for( int i = 0; i < boardSize.height; ++i )
for( int j = 0; j < boardSize.width; ++j )
corners.push_back(Point3f(j*squareSize, i*squareSize, 0));
break;
case Settings::ASYMMETRIC_CIRCLES_GRID:
case Calibrate::Settings::ASYMMETRIC_CIRCLES_GRID:
for( int i = 0; i < boardSize.height; i++ )
for( int j = 0; j < boardSize.width; j++ )
corners.push_back(Point3f((2*j + i % 2)*squareSize, i*squareSize, 0));
......@@ -546,7 +451,7 @@ static void calcBoardCornerPositions(Size boardSize, float squareSize, vector<Po
}
}
//! [board_corners]
static bool runCalibration( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat& distCoeffs,
static bool runCalibration( Calibrate::Settings& s, Size& imageSize, Mat& cameraMatrix, Mat& distCoeffs,
vector<vector<Point2f> > imagePoints, vector<Mat>& rvecs, vector<Mat>& tvecs,
vector<float>& reprojErrs, double& totalAvgErr, vector<Point3f>& newObjPoints,
float grid_width, bool release_object)
......@@ -613,13 +518,15 @@ static bool runCalibration( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat
}
// Print camera parameters to the output file
static void saveCameraParams( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat& distCoeffs,
static void saveCameraParams( Calibrate::Settings& s, Size& imageSize, Mat& cameraMatrix, Mat& distCoeffs,
const vector<Mat>& rvecs, const vector<Mat>& tvecs,
const vector<float>& reprojErrs, const vector<vector<Point2f> >& imagePoints,
double totalAvgErr, const vector<Point3f>& newObjPoints )
{
FileStorage fs( s.outputFileName, FileStorage::WRITE );
LOG(INFO) << "Saving calibration to " << s.outputFileName;
time_t tm;
time( &tm );
struct tm *t2 = localtime( &tm );
......@@ -731,7 +638,7 @@ static void saveCameraParams( Settings& s, Size& imageSize, Mat& cameraMatrix, M
}
//! [run_and_save]
bool runCalibrationAndSave(Settings& s, Size imageSize, Mat& cameraMatrix, Mat& distCoeffs,
bool runCalibrationAndSave(Calibrate::Settings& s, Size imageSize, Mat& cameraMatrix, Mat& distCoeffs,
vector<vector<Point2f> > imagePoints, float grid_width, bool release_object)
{
vector<Mat> rvecs, tvecs;
......@@ -744,6 +651,8 @@ bool runCalibrationAndSave(Settings& s, Size imageSize, Mat& cameraMatrix, Mat&
cout << (ok ? "Calibration succeeded" : "Calibration failed")
<< ". avg re projection error = " << totalAvgErr << endl;
//return ok;
if (ok)
saveCameraParams(s, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs, reprojErrs, imagePoints,
totalAvgErr, newObjPoints);
......
......@@ -68,6 +68,67 @@ LocalSource::LocalSource(const string &vid): timestamp_(0.0) {
}
}
bool LocalSource::left(cv::Mat &l) {
if (!camera_a_) return false;
if (!camera_a_->grab()) {
LOG(ERROR) << "Unable to grab from camera A";
return false;
}
// Record timestamp
timestamp_ = duration_cast<duration<double>>(
high_resolution_clock::now().time_since_epoch()).count();
if (camera_b_ || !stereo_) {
if (!camera_a_->retrieve(l)) {
LOG(ERROR) << "Unable to read frame from camera A";
return false;
}
} else {
Mat frame;
if (!camera_a_->retrieve(frame)) {
LOG(ERROR) << "Unable to read frame from video";
return false;
}
int resx = frame.cols / 2;
l = Mat(frame, Rect(0,0,resx,frame.rows));
}
return true;
}
bool LocalSource::right(cv::Mat &r) {
if (camera_b_ && !camera_b_->grab()) {
LOG(ERROR) << "Unable to grab from camera B";
return false;
}
// Record timestamp
timestamp_ = duration_cast<duration<double>>(
high_resolution_clock::now().time_since_epoch()).count();
if (camera_b_ || !stereo_) {
if (camera_b_ && !camera_b_->retrieve(r)) {
LOG(ERROR) << "Unable to read frame from camera B";
return false;
}
} else {
Mat frame;
if (!camera_a_) return false;
if (!camera_a_->retrieve(frame)) {
LOG(ERROR) << "Unable to read frame from video";
return false;
}
int resx = frame.cols / 2;
r = Mat(frame, Rect(resx,0,frame.cols-resx,frame.rows));
}
return true;
}
bool LocalSource::get(cv::Mat &l, cv::Mat &r) {
if (!camera_a_) return false;
......@@ -102,7 +163,7 @@ bool LocalSource::get(cv::Mat &l, cv::Mat &r) {
int resx = frame.cols / 2;
l = Mat(frame, Rect(0,0,resx,frame.rows));
r = Mat(frame, Rect(resx,0,frame.cols,frame.rows));
r = Mat(frame, Rect(resx,0,frame.cols-resx,frame.rows));
}
return true;
......
......@@ -13,7 +13,7 @@ using cv::Mat;
static vector<string> OPTION_peers;
static vector<string> OPTION_channels;
static string OPTION_calibration_config;
static string OPTION_calibration_config = FTL_CONFIG_ROOT "/calibration.xml";
static string OPTION_config;
static bool OPTION_display = false;
static bool OPTION_calibrate = false;
......@@ -73,6 +73,8 @@ int main(int argc, char **argv) {
Calibrate calibrate(lsrc, OPTION_calibration_config);
if (!calibrate.isCalibrated()) calibrate.recalibrate();
while (true) {
Mat l, r;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment