13 #include <opencv2/imgproc.hpp>
14 #include <opencv2/imgcodecs.hpp>
25 std::string computerInfos,
26 std::string calibDataPath,
27 std::string imageOutputPath,
30 _camSizeIndex(camSizeIndex),
31 _mirroredH(mirroredH),
32 _mirroredV(mirroredV),
34 _calibParamsFileName(
"calib_in_params.yml"),
35 _exception(
"Undefined error", 0, __FILE__),
36 _computerInfos(computerInfos),
37 _calibDataPath(calibDataPath),
52 ss <<
"Image output directory does not exist: " << imageOutputPath;
89 else if (
_calibrationTask.wait_for(std::chrono::milliseconds(1)) == std::future_status::ready)
94 Utils::log(
"SLProject",
"Calibration succeeded.");
99 Utils::log(
"SLProject",
"Calibration failed.");
119 bool foundPrecisely =
false;
122 std::vector<cv::Point2f> preciseCorners2D;
123 int flags = CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE;
135 TermCriteria(TermCriteria::EPS + TermCriteria::COUNT,
144 catch (std::exception& e)
157 return foundPrecisely;
166 std::vector<cv::Mat> rvecs, tvecs;
167 vector<float> reprojErrs;
184 if (!rvecs.empty() || !reprojErrs.empty())
185 _numCaptured = (int)std::max(rvecs.size(), reprojErrs.size());
192 _calibration = std::make_unique<SENSCalibration>(cameraMat,
209 catch (std::exception& e)
227 cv::Mat& cameraMatrix,
229 const vector<vector<cv::Point2f>>& imagePoints,
230 std::vector<cv::Mat>& rvecs,
231 std::vector<cv::Mat>& tvecs,
232 vector<float>& reprojErrs,
237 bool useReleaseObjectMethod)
240 cameraMatrix = cv::Mat::eye(3, 3, CV_64F);
243 if (flag & CALIB_FIX_ASPECT_RATIO)
244 cameraMatrix.at<
double>(0, 0) = 1.0;
247 distCoeffs = cv::Mat::zeros(8, 1, CV_64F);
249 vector<vector<cv::Point3f>> objectPoints(1);
255 objectPoints.resize(imagePoints.size(), objectPoints[0]);
259 int iFixedPoint = -1;
260 if (useReleaseObjectMethod)
261 iFixedPoint = boardSize.width - 1;
263 double rms = cv::calibrateCameraRO(objectPoints,
274 double rms = cv::calibrateCamera(objectPoints,
287 Utils::log(
"SLProject",
"Re-projection error reported by calibrateCamera: %f", rms);
289 bool ok = cv::checkRange(cameraMatrix) && cv::checkRange(distCoeffs);
303 const vector<vector<cv::Point2f>>& imagePoints,
304 const std::vector<cv::Mat>& rvecs,
305 const std::vector<cv::Mat>& tvecs,
306 const cv::Mat& cameraMatrix,
307 const cv::Mat& distCoeffs,
308 vector<float>& perViewErrors)
310 std::vector<cv::Point2f> imagePoints2;
311 size_t totalPoints = 0;
312 double totalErr = 0, err;
313 perViewErrors.resize(objectPoints.size());
315 for (
size_t i = 0; i < objectPoints.size(); ++i)
317 cv::projectPoints(objectPoints[i],
324 err = norm(imagePoints[i], imagePoints2, NORM_L2);
326 size_t n = objectPoints[i].size();
327 perViewErrors[i] = (float)std::sqrt(err * err / n);
328 totalErr += err * err;
332 return std::sqrt(totalErr / totalPoints);
341 fs.open(fullCalibIniFile, FileStorage::READ);
344 Utils::log(
"SLProject",
"Could not open the calibration parameter file: %s", fullCalibIniFile.c_str());
349 fs[
"numInnerCornersWidth"] >>
_boardSize.width;
350 fs[
"numInnerCornersHeight"] >>
_boardSize.height;
359 std::stringstream ss;
361 cv::imwrite(ss.str(), imageGray);
370 if (grabFrame && found)
386 if (
_calibrationTask.wait_for(std::chrono::milliseconds(1)) == std::future_status::ready)
410 if (
_calibrationTask.wait_for(std::chrono::milliseconds(1)) == std::future_status::ready)
417 Utils::log(
"SLProject",
"Calibration succeeded.");
422 Utils::log(
"SLProject",
"Calibration failed.");
444 if (grabFrame && found)
463 const cv::Mat& imageGray,
467 assert(!imageGray.empty() &&
468 "SENSCalibrationEstimator::findChessboard: imageGray is empty!");
469 assert(!imageColor.empty() &&
470 "SENSCalibrationEstimator::findChessboard: imageColor is empty!");
472 "SENSCalibrationEstimator::findChessboard: _boardSize is not set!");
474 cv::Size imageSize = imageColor.size();
476 cv::Mat imageGrayExtract = imageGray;
479 bool doScale =
false;
480 int targetExtractWidth = 640;
481 if (imageSize.width > targetExtractWidth)
484 scale = (double)imageSize.width / (
double)targetExtractWidth;
485 cv::resize(imageGray, imageGrayExtract, cv::Size(), 1 / scale, 1 / scale);
488 std::vector<cv::Point2f> corners2D;
489 bool found = cv::findChessboardCorners(imageGrayExtract,
492 cv::CALIB_CB_FAST_CHECK);
499 cv::bitwise_not(imageColor, imageColor);
507 for (cv::Point2f& pt : corners2D)
513 cv::drawChessboardCorners(imageColor,
536 std::vector<cv::Point3f>& objectPoints3D)
540 objectPoints3D.clear();
541 for (
int y = boardSize.height - 1; y >= 0; --y)
542 for (
int x = 0; x < boardSize.width; ++x)
543 objectPoints3D.push_back(cv::Point3f((
float)x * squareSize,
544 (
float)y * squareSize,
special exception that informs about errors during calibration process
std::future< bool > _calibrationTask
future object for calculation of calibration in async task
cv::Mat _currentImgToExtract
void saveImage(cv::Mat imageGray)
std::string _calibImgOutputDir
float _boardSquareMM
Size of chessboard square in mm.
std::string _calibDataPath
std::unique_ptr< SENSCalibration > _calibration
estimated calibration
bool calculate()
Initiates the final calculation.
void updateOnlyCapture(bool found, bool grabFrame, cv::Mat imageGray)
SENSCalibrationEstimatorException _exception
int _numOfImgsToCapture
NO. of images to capture.
@ BusyExtracting
Estimator is busy extracting the corners of a frame.
@ DoneCaptureAndSave
All images are captured in.
@ Streaming
Estimator waits for new frames.
@ Done
Estimator finished.
@ Calculating
Estimator is currently calculating the calibration.
std::string _calibParamsFileName
name of calibration paramters file
bool _calibrationSuccessful
~SENSCalibrationEstimator()
cv::Size _imageSize
Input image size in pixels (after cropping)
float _reprojectionError
Reprojection error after calibration.
SENSCalibrationEstimator(SENSCalibrationEstimatorParams params, int camSizeIndex, bool mirroredH, bool mirroredV, SENSCameraType camType, std::string computerInfos, std::string calibDataPath, std::string imageOutputPath, std::string exePath)
std::string _computerInfos
void updateExtractAndCalc(bool found, bool grabFrame, cv::Mat imageGray)
SENSCalibrationEstimatorParams _params
cv::Size _boardSize
NO. of inner chessboard corners.
bool calibrationSuccessful()
static double calcReprojectionErrors(const vector< vector< cv::Point3f >> &objectPoints, const vector< vector< cv::Point2f >> &imagePoints, const std::vector< cv::Mat > &rvecs, const std::vector< cv::Mat > &tvecs, const cv::Mat &cameraMatrix, const cv::Mat &distCoeffs, vector< float > &perViewErrors)
Calculates the reprojection error of the calibration.
bool updateAndDecorate(cv::Mat imageColor, const cv::Mat &imageGray, bool grabFrame, bool drawCorners=true)
< Finds the inner chessboard corners in the given image
bool loadCalibParams()
Loads the chessboard calibration pattern parameters.
int _numCaptured
NO. of images captured.
static void calcBoardCorners3D(const cv::Size &boardSize, float squareSize, std::vector< cv::Point3f > &objectPoints3D)
Calculates the 3D positions of the chessboard corners.
vector< vector< cv::Point2f > > _imagePoints
2D vector of corner points in chessboard
static bool calcCalibration(cv::Size &imageSize, cv::Mat &cameraMatrix, cv::Mat &distCoeffs, const vector< vector< cv::Point2f >> &imagePoints, std::vector< cv::Mat > &rvecs, std::vector< cv::Mat > &tvecs, vector< float > &reprojErrs, float &totalAvgErr, cv::Size &boardSize, float squareSize, int flag, bool useReleaseObjectMethod)
Calculates the calibration with the given set of image points.
Parameterset for the SENSCalibrationEstimator.
bool useReleaseObjectMethod
string findFile(const string &filename, const vector< string > &pathsToCheck)
Tries to find a filename on various paths to check.
string getDateTime2String()
Returns local time as string like "20190213-154611".
string unifySlashes(const string &inputDir, bool withTrailingSlash)
Returns the inputDir string with unified forward slashes, e.g.: "dirA/dirB/".
bool dirExists(const string &path)
Returns true if a directory exists.
bool makeDir(const string &path)
Creates a directory with given path.
void log(const char *tag, const char *format,...)
logs a formatted string platform independently