13 #include <opencv2/imgproc.hpp>
24 const cv::Mat& distortion,
28 float reprojectionError,
30 const std::string& calibrationTime,
35 std::string computerInfos,
37 bool calcUndistortionMaps)
38 : _cameraMat(cameraMat.clone()),
39 _distortion(distortion.clone()),
40 _imageSize(std::move(imageSize)),
41 _boardSize(std::move(boardSize)),
42 _boardSquareMM(boardSquareMM),
43 _reprojectionError(reprojectionError),
44 _numCaptured(numCaptured),
45 _calibrationTime(calibrationTime),
46 _camSizeIndex(camSizeIndex),
47 _isMirroredH(mirroredH),
48 _isMirroredV(mirroredV),
50 _computerInfos(std::move(computerInfos)),
51 _calibFlags(calibFlags)
53 _cameraMatOrig = _cameraMat.clone();
54 _imageSizeOrig = _imageSize;
56 calculateUndistortedCameraMat();
57 calcCameraFovFromUndistortedCameraMat();
58 if (calcUndistortionMaps)
59 buildUndistortionMaps();
60 _state = State::calibrated;
69 std::string computerInfos)
70 : _isMirroredH(mirroredH),
71 _isMirroredV(mirroredV),
73 _computerInfos(std::move(computerInfos))
75 createFromGuessedFOV(imageSize.width, imageSize.height, fovH);
76 _cameraMatUndistorted = _cameraMat.clone();
77 _cameraMatOrig = _cameraMat.clone();
78 _imageSizeOrig = _imageSize;
79 Utils::log(
"SENSCalibration",
"Guessing calibration from fovV: fovH: %f. fovV: %f", _cameraFovHDeg, _cameraFovVDeg);
86 const cv::Size& imageSize,
90 std::string computerInfos)
91 : _isMirroredH(mirroredH),
92 _isMirroredV(mirroredV),
94 _computerInfos(std::move(computerInfos))
97 float devFovH = 2.0f * atan(sensorWMM / (2.0f * focalLengthMM)) *
Utils::RAD2DEG;
98 if (devFovH > 60.0f && devFovH < 70.0f)
100 createFromGuessedFOV(imageSize.width, imageSize.height, devFovH);
101 Utils::log(
"SENSCalibration",
"From physical sensor data: fovH: %f. fovV: %f", _cameraFovHDeg, _cameraFovVDeg);
106 createFromGuessedFOV(imageSize.width, imageSize.height, 65.0);
107 Utils::log(
"SENSCalibration",
"Guessing calibration from fovV: fovH: %f. fovV: %f", _cameraFovHDeg, _cameraFovVDeg);
109 _cameraMatUndistorted = _cameraMat.clone();
110 _cameraMatOrig = _cameraMat.clone();
111 _imageSizeOrig = _imageSize;
115 const cv::Size& imageSize,
119 const std::string& computerInfos)
120 : _imageSize(imageSize),
121 _isMirroredH(mirroredH),
122 _isMirroredV(mirroredV),
124 _computerInfos(computerInfos)
126 _cameraMatUndistorted = intrinsics.clone();
127 _cameraMatOrig = intrinsics.clone();
128 _cameraMat = intrinsics.clone();
129 _imageSizeOrig = imageSize;
131 _distortion = (cv::Mat_<double>(5, 1) << 0, 0, 0, 0, 0);
132 float meanFocalLength = 0.5 * (intrinsics.at<
double>(0, 0) + intrinsics.at<
double>(1, 1));
136 _state = State::guessed;
140 const std::string& calibFileName,
141 bool calcUndistortionMaps)
152 const std::string& calibFileName,
153 bool calcUndistortionMaps)
159 cv::FileStorage fs(fullPathAndFilename, cv::FileStorage::READ);
163 Utils::log(
"SLProject",
"Calib. created : No. Calib. will be estimated");
175 int calibFileVersion = 0;
176 fs[
"CALIBFILEVERSION"] >> calibFileVersion;
204 if (!fs[
"computerInfos"].empty())
208 std::vector<std::string> stringParts;
210 if (stringParts.size() >= 3)
223 if (calcUndistortionMaps)
227 Utils::log(
"SLProject",
"Calib. loaded : %s", fullPathAndFilename.c_str());
239 const std::string& calibFileName)
243 cv::FileStorage fs(fullPathAndFilename, cv::FileStorage::WRITE);
247 Utils::log(
"SLProject",
"Failed to write calib. %s", fullPathAndFilename.c_str());
252 snprintf(buf,
sizeof(buf),
253 "flags:%s%s%s%s%s%s%s",
254 _calibFlags & cv::CALIB_USE_INTRINSIC_GUESS ?
" +use_intrinsic_guess" :
"",
255 _calibFlags & cv::CALIB_FIX_ASPECT_RATIO ?
" +fix_aspectRatio" :
"",
256 _calibFlags & cv::CALIB_FIX_PRINCIPAL_POINT ?
" +fix_principal_point" :
"",
257 _calibFlags & cv::CALIB_ZERO_TANGENT_DIST ?
" +zero_tangent_dist" :
"",
258 _calibFlags & cv::CALIB_RATIONAL_MODEL ?
" +rational_model" :
"",
259 _calibFlags & cv::CALIB_THIN_PRISM_MODEL ?
" +thin_prism_model" :
"",
260 _calibFlags & cv::CALIB_TILTED_MODEL ?
" +tilted_model" :
"");
261 fs.writeComment(buf, 0);
274 fs <<
"calibFixAspectRatio" << (
_calibFlags & cv::CALIB_FIX_ASPECT_RATIO);
275 fs <<
"calibFixPrincipalPoint" << (
_calibFlags & cv::CALIB_FIX_PRINCIPAL_POINT);
276 fs <<
"calibZeroTangentDist" << (
_calibFlags & cv::CALIB_ZERO_TANGENT_DIST);
277 fs <<
"calibRationalModel" << (
_calibFlags & cv::CALIB_RATIONAL_MODEL);
278 fs <<
"calibTiltedModel" << (
_calibFlags & cv::CALIB_TILTED_MODEL);
279 fs <<
"calibThinPrismModel" << (
_calibFlags & cv::CALIB_THIN_PRISM_MODEL);
290 Utils::log(
"SLProject",
"Calib. saved : %s", fullPathAndFilename.c_str());
297 const cv::Mat& distCoeffs,
299 const cv::Mat& newCameraMatrix,
300 const cv::Size& imgSize,
301 cv::Rect_<float>& inner,
302 cv::Rect_<float>& outer)
306 cv::Mat pts(N * N, 2, CV_32F);
307 for (
int y = 0, k = 0; y < N; y++)
309 for (
int x = 0; x < N; x++)
311 pts.at<
float>(k, 0) = (
float)x * imgSize.width / (N - 1);
312 pts.at<
float>(k, 1) = (
float)y * imgSize.height / (N - 1);
317 pts = pts.reshape(2);
318 cv::undistortPoints(pts, pts, cameraMatrix, distCoeffs, R, newCameraMatrix);
319 pts = pts.reshape(1);
321 float iX0 = -FLT_MAX, iX1 = FLT_MAX, iY0 = -FLT_MAX, iY1 = FLT_MAX;
322 float oX0 = FLT_MAX, oX1 = -FLT_MAX, oY0 = FLT_MAX, oY1 = -FLT_MAX;
325 for (
int y = 0, k = 0; y < N; y++)
326 for (
int x = 0; x < N; x++)
328 cv::Point2f p = {pts.at<
float>(k, 0), pts.at<
float>(k, 1)};
344 inner = cv::Rect_<float>(iX0, iY0, iX1 - iX0, iY1 - iY0);
345 outer = cv::Rect_<float>(oX0, oY0, oX1 - oX0, oY1 - oY0);
354 "SENSCalibration::buildUndistortionMaps: No _cameraMatUndistorted available",
372 "initUndistortRectifyMap: %fms",
377 "SENSCalibration::buildUndistortionMaps failed.",
384 cv::Mat& outUndistorted)
const
386 assert(!inDistorted.empty() &&
387 "Input image is empty!");
391 "Undistortion Maps are empty!");
393 cv::remap(inDistorted,
417 float f = (0.5f * imageWidthPX) / tanf(fovH * 0.5f *
Utils::DEG2RAD);
418 float fovV = 2.f * atan(0.5f * imageHeightPX / f) *
Utils::RAD2DEG;
427 float cx = (float)imageWidthPX * 0.5f;
428 float cy = (float)imageHeightPX * 0.5f;
435 _distortion = (cv::Mat_<double>(5, 1) << 0, 0, 0, 0, 0);
458 if (((
float)newSize.width / (float)newSize.height) >
461 float scaleFactor = (float)newSize.width / (
float)
_imageSizeOrig.width;
463 fx = fxOrig * scaleFactor;
464 fy = fyOrig * scaleFactor;
466 float heightDiff = (oldHeightScaled - newSize.height) * 0.5f;
468 cx = cxOrig * scaleFactor;
469 cy = cyOrig * scaleFactor - heightDiff;
473 float scaleFactor = (float)newSize.height / (
float)
_imageSizeOrig.height;
474 fx = fxOrig * scaleFactor;
475 fy = fyOrig * scaleFactor;
477 float widthDiff = (oldWidthScaled - newSize.width) * 0.5f;
479 cx = cxOrig * scaleFactor - widthDiff;
480 cy = cyOrig * scaleFactor;
496 if (calcUndistortionMaps)
504 Utils::exitMsg(
"SLProject",
"SENSCalibration::calculateUndistortedCameraMat: No intrinsic parameter available", __LINE__, __FILE__);
511 bool centerPrinciplePoint =
true;
512 if (centerPrinciplePoint)
524 cv::Rect_<float> inner, outer;
533 double s0 = std::max(std::max(std::max(
cx / (cx0 - inner.x),
534 cy / (cy0 - inner.y)),
535 cx / (inner.x + inner.width - cx0)),
536 cy / (inner.y + inner.height - cy0));
538 double s1 = std::min(std::min(std::min(
cx / (cx0 - outer.x),
539 cy / (cy0 - outer.y)),
540 cx / (outer.x + outer.width - cx0)),
541 cy / (outer.y + outer.height - cy0));
543 double s = s0 * (1 - alpha) +
s1 * alpha;
559 centerPrinciplePoint);
570 Utils::exitMsg(
"SLProject",
"SENSCalibration::calcCameraFovFromSceneCameraMat: No _cameraMatUndistorted available", __LINE__, __FILE__);
High Resolution Timer class using C++11.
float elapsedTimeInMilliSec()
State _state
calibration state enumeration
int _numCaptured
NO. of images captured.
cv::Mat _undistortMapX
Undistortion float map in x-direction.
bool save(const string &calibDir, const string &calibFileName)
Saves the camera calibration parameters to the config file.
cv::Mat _cameraMatOrig
3x3 Matrix for intrinsic camera matrix (original from loading or calibration estimation)
void buildUndistortionMaps()
Builds undistortion maps after calibration or loading.
void createFromGuessedFOV(int imageWidthPX, int imageHeightPX, float fovH)
Calculates camera intrinsics from a guessed FOV angle.
cv::Mat _cameraMatUndistorted
static void getInnerAndOuterRectangles(const cv::Mat &cameraMatrix, const cv::Mat &distCoeffs, const cv::Mat &R, const cv::Mat &newCameraMatrix, const cv::Size &imgSize, cv::Rect_< float > &inner, cv::Rect_< float > &outer)
get inscribed and circumscribed rectangle
int _camSizeIndex
The requested camera size index.
float _reprojectionError
Reprojection error after calibration.
float _cameraFovHDeg
Horizontal field of view in degrees.
@ uncalibrated
The camera is not calibrated (no calibration found)
@ calibrated
The camera is calibrated (mainly this means it has distortion coeffs)
@ guessed
The camera intrinsics where estimated from FOV.
void remap(cv::Mat &inDistorted, cv::Mat &outUndistorted) const
Undistorts the inDistorted image into the outUndistorted.
bool load(const string &calibDir, const string &calibFileName, bool calcUndistortionMaps)
Loads the calibration information from the config file.
cv::Size _imageSize
Input image size in pixels (after cropping)
SENSCalibration(const cv::Mat &cameraMat, const cv::Mat &distortion, cv::Size imageSize, cv::Size boardSize, float boardSquareMM, float reprojectionError, int numCaptured, const string &calibrationTime, int camSizeIndex, bool mirroredH, bool mirroredV, SENSCameraType camType, string computerInfos, int calibFlags, bool calcUndistortionMaps)
creates a fully defined calibration
string _calibrationTime
Time stamp string of calibration.
static const int _CALIBFILEVERSION
Global const file format version.
string calibFileName() const
float _boardSquareMM
Size of chessboard square in mm.
cv::Mat _undistortMapY
Undistortion float map in y-direction.
cv::Size _boardSize
NO. of inner chessboard corners.
void calculateUndistortedCameraMat()
Calculate a camera matrix that we use for the scene graph and for the reprojection of the undistored ...
void adaptForNewResolution(const cv::Size &newSize, bool calcUndistortionMaps)
Adapts an already calibrated camera to a new resolution (cropping and scaling)
float _cameraFovVDeg
Vertical field of view in degrees.
void calcCameraFovFromUndistortedCameraMat()
Calculates the vertical field of view angle in degrees.
bool _isMirroredH
Flag if image must be horizontally mirrored.
cv::Mat _cameraMat
3x3 Matrix for intrinsic camera matrix
cv::Mat _distortion
4x1 Matrix for intrinsic distortion
int _calibFlags
OpenCV calibration flags.
cv::Size _imageSizeOrig
original image size (original from loading or calibration estimation)
bool _isMirroredV
Flag if image must be vertically mirrored.
The SLScene class represents the top level instance holding the scene structure.
float calcFOVDegFromFocalLengthPix(const float focalLengthPix, const int imgLength)
string getDateTime2String()
Returns local time as string like "20190213-154611".
static const float DEG2RAD
string unifySlashes(const string &inputDir, bool withTrailingSlash)
Returns the inputDir string with unified forward slashes, e.g.: "dirA/dirB/".
string getFileNameWOExt(const string &pathFilename)
Returns the filename without extension.
void splitString(const string &s, char delimiter, vector< string > &splits)
Splits an input string at a delimiter character into a string vector.
void exitMsg(const char *tag, const char *msg, const int line, const char *file)
Terminates the application with a message. No leak checking.
static const float RAD2DEG
void log(const char *tag, const char *format,...)
logs a formatted string platform independently