mirror of
https://github.com/opencv/opencv.git
synced 2025-06-12 20:42:53 +08:00
Save Frames option for interactive calibration tool
The option to save all frames that contribute to final calibration result. Useful for dataset collection and further offline tuning.
This commit is contained in:
parent
14754deb21
commit
533bb035cf
@ -45,6 +45,8 @@ namespace calib
|
|||||||
double totalAvgErr;
|
double totalAvgErr;
|
||||||
cv::Size imageSize;
|
cv::Size imageSize;
|
||||||
|
|
||||||
|
std::vector<cv::Mat> allFrames;
|
||||||
|
|
||||||
std::vector<std::vector<cv::Point2f> > imagePoints;
|
std::vector<std::vector<cv::Point2f> > imagePoints;
|
||||||
std::vector< std::vector<cv::Point3f> > objectPoints;
|
std::vector< std::vector<cv::Point3f> > objectPoints;
|
||||||
|
|
||||||
@ -91,6 +93,7 @@ namespace calib
|
|||||||
cv::Size cameraResolution;
|
cv::Size cameraResolution;
|
||||||
int maxFramesNum;
|
int maxFramesNum;
|
||||||
int minFramesNum;
|
int minFramesNum;
|
||||||
|
bool saveFrames;
|
||||||
|
|
||||||
captureParameters()
|
captureParameters()
|
||||||
{
|
{
|
||||||
@ -100,6 +103,7 @@ namespace calib
|
|||||||
minFramesNum = 10;
|
minFramesNum = 10;
|
||||||
fps = 30;
|
fps = 30;
|
||||||
cameraResolution = cv::Size(IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT);
|
cameraResolution = cv::Size(IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT);
|
||||||
|
saveFrames = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <opencv2/calib3d.hpp>
|
#include <opencv2/calib3d.hpp>
|
||||||
#include <opencv2/imgproc.hpp>
|
#include <opencv2/imgproc.hpp>
|
||||||
|
#include <opencv2/imgcodecs.hpp>
|
||||||
|
|
||||||
double calib::calibController::estimateCoverageQuality()
|
double calib::calibController::estimateCoverageQuality()
|
||||||
{
|
{
|
||||||
@ -212,6 +213,9 @@ void calib::calibDataController::filterFrames()
|
|||||||
}
|
}
|
||||||
showOverlayMessage(cv::format("Frame %zu is worst", worstElemIndex + 1));
|
showOverlayMessage(cv::format("Frame %zu is worst", worstElemIndex + 1));
|
||||||
|
|
||||||
|
if(mCalibData->allFrames.size())
|
||||||
|
mCalibData->allFrames.erase(mCalibData->allFrames.begin() + worstElemIndex);
|
||||||
|
|
||||||
if(mCalibData->imagePoints.size()) {
|
if(mCalibData->imagePoints.size()) {
|
||||||
mCalibData->imagePoints.erase(mCalibData->imagePoints.begin() + worstElemIndex);
|
mCalibData->imagePoints.erase(mCalibData->imagePoints.begin() + worstElemIndex);
|
||||||
mCalibData->objectPoints.erase(mCalibData->objectPoints.begin() + worstElemIndex);
|
mCalibData->objectPoints.erase(mCalibData->objectPoints.begin() + worstElemIndex);
|
||||||
@ -239,6 +243,11 @@ void calib::calibDataController::setParametersFileName(const std::string &name)
|
|||||||
|
|
||||||
void calib::calibDataController::deleteLastFrame()
|
void calib::calibDataController::deleteLastFrame()
|
||||||
{
|
{
|
||||||
|
if(!mCalibData->allFrames.empty())
|
||||||
|
{
|
||||||
|
mCalibData->allFrames.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
if( !mCalibData->imagePoints.empty()) {
|
if( !mCalibData->imagePoints.empty()) {
|
||||||
mCalibData->imagePoints.pop_back();
|
mCalibData->imagePoints.pop_back();
|
||||||
mCalibData->objectPoints.pop_back();
|
mCalibData->objectPoints.pop_back();
|
||||||
@ -269,6 +278,7 @@ void calib::calibDataController::rememberCurrentParameters()
|
|||||||
|
|
||||||
void calib::calibDataController::deleteAllData()
|
void calib::calibDataController::deleteAllData()
|
||||||
{
|
{
|
||||||
|
mCalibData->allFrames.clear();
|
||||||
mCalibData->imagePoints.clear();
|
mCalibData->imagePoints.clear();
|
||||||
mCalibData->objectPoints.clear();
|
mCalibData->objectPoints.clear();
|
||||||
mCalibData->allCharucoCorners.clear();
|
mCalibData->allCharucoCorners.clear();
|
||||||
@ -280,6 +290,10 @@ void calib::calibDataController::deleteAllData()
|
|||||||
|
|
||||||
bool calib::calibDataController::saveCurrentCameraParameters() const
|
bool calib::calibDataController::saveCurrentCameraParameters() const
|
||||||
{
|
{
|
||||||
|
|
||||||
|
for(size_t i = 0; i < mCalibData->allFrames.size(); i++)
|
||||||
|
cv::imwrite(cv::format("calibration_%zu.png", i), mCalibData->allFrames[i]);
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if(mCalibData->cameraMatrix.total()) {
|
if(mCalibData->cameraMatrix.total()) {
|
||||||
cv::FileStorage parametersWriter(mParamsFileName, cv::FileStorage::WRITE);
|
cv::FileStorage parametersWriter(mParamsFileName, cv::FileStorage::WRITE);
|
||||||
|
@ -266,6 +266,7 @@ CalibProcessor::CalibProcessor(cv::Ptr<calibrationData> data, captureParameters
|
|||||||
static_cast<float>(mCalibData->imageSize.width * mCalibData->imageSize.width)) / 20.0;
|
static_cast<float>(mCalibData->imageSize.width * mCalibData->imageSize.width)) / 20.0;
|
||||||
mSquareSize = capParams.squareSize;
|
mSquareSize = capParams.squareSize;
|
||||||
mTemplDist = capParams.templDst;
|
mTemplDist = capParams.templDst;
|
||||||
|
mSaveFrames = capParams.saveFrames;
|
||||||
|
|
||||||
switch(mBoardType)
|
switch(mBoardType)
|
||||||
{
|
{
|
||||||
@ -291,10 +292,14 @@ CalibProcessor::CalibProcessor(cv::Ptr<calibrationData> data, captureParameters
|
|||||||
cv::Mat CalibProcessor::processFrame(const cv::Mat &frame)
|
cv::Mat CalibProcessor::processFrame(const cv::Mat &frame)
|
||||||
{
|
{
|
||||||
cv::Mat frameCopy;
|
cv::Mat frameCopy;
|
||||||
|
cv::Mat frameCopyToSave;
|
||||||
frame.copyTo(frameCopy);
|
frame.copyTo(frameCopy);
|
||||||
bool isTemplateFound = false;
|
bool isTemplateFound = false;
|
||||||
mCurrentImagePoints.clear();
|
mCurrentImagePoints.clear();
|
||||||
|
|
||||||
|
if(mSaveFrames)
|
||||||
|
frame.copyTo(frameCopyToSave);
|
||||||
|
|
||||||
switch(mBoardType)
|
switch(mBoardType)
|
||||||
{
|
{
|
||||||
case Chessboard:
|
case Chessboard:
|
||||||
@ -322,6 +327,10 @@ cv::Mat CalibProcessor::processFrame(const cv::Mat &frame)
|
|||||||
mCalibData->allCharucoCorners.size()));
|
mCalibData->allCharucoCorners.size()));
|
||||||
if(!showOverlayMessage(displayMessage))
|
if(!showOverlayMessage(displayMessage))
|
||||||
showCaptureMessage(frame, displayMessage);
|
showCaptureMessage(frame, displayMessage);
|
||||||
|
|
||||||
|
if(mSaveFrames)
|
||||||
|
mCalibData->allFrames.push_back(frameCopyToSave);
|
||||||
|
|
||||||
mCapuredFrames++;
|
mCapuredFrames++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -50,6 +50,7 @@ protected:
|
|||||||
double mMaxTemplateOffset;
|
double mMaxTemplateOffset;
|
||||||
float mSquareSize;
|
float mSquareSize;
|
||||||
float mTemplDist;
|
float mTemplDist;
|
||||||
|
bool mSaveFrames;
|
||||||
|
|
||||||
bool detectAndParseChessboard(const cv::Mat& frame);
|
bool detectAndParseChessboard(const cv::Mat& frame);
|
||||||
bool detectAndParseChAruco(const cv::Mat& frame);
|
bool detectAndParseChAruco(const cv::Mat& frame);
|
||||||
|
@ -40,6 +40,7 @@ const std::string keys =
|
|||||||
"{vis | grid | Captured boards visualisation (grid, window)}"
|
"{vis | grid | Captured boards visualisation (grid, window)}"
|
||||||
"{d | 0.8 | Min delay between captures}"
|
"{d | 0.8 | Min delay between captures}"
|
||||||
"{pf | defaultConfig.xml| Advanced application parameters}"
|
"{pf | defaultConfig.xml| Advanced application parameters}"
|
||||||
|
"{save_frames | false | Save frames that contribute to final calibration}"
|
||||||
"{help | | Print help}";
|
"{help | | Print help}";
|
||||||
|
|
||||||
bool calib::showOverlayMessage(const std::string& message)
|
bool calib::showOverlayMessage(const std::string& message)
|
||||||
|
@ -89,6 +89,7 @@ bool calib::parametersController::loadFromParser(cv::CommandLineParser &parser)
|
|||||||
mCapParams.captureDelay = parser.get<float>("d");
|
mCapParams.captureDelay = parser.get<float>("d");
|
||||||
mCapParams.squareSize = parser.get<float>("sz");
|
mCapParams.squareSize = parser.get<float>("sz");
|
||||||
mCapParams.templDst = parser.get<float>("dst");
|
mCapParams.templDst = parser.get<float>("dst");
|
||||||
|
mCapParams.saveFrames = parser.has("save_frames");
|
||||||
|
|
||||||
if(!checkAssertion(mCapParams.squareSize > 0, "Distance between corners or circles must be positive"))
|
if(!checkAssertion(mCapParams.squareSize > 0, "Distance between corners or circles must be positive"))
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user