|
|
|
@ -48,60 +48,32 @@ the use of this software, even if advised of the possibility of such damage. |
|
|
|
|
using namespace std; |
|
|
|
|
using namespace cv; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*/ |
|
|
|
|
static void help() { |
|
|
|
|
cout << "Calibration using a ChArUco board" << endl; |
|
|
|
|
cout << "How to Use:" << endl; |
|
|
|
|
cout << "To capture a frame for calibration, press 'c'," << endl; |
|
|
|
|
cout << "If input comes from video, press any key for next frame" << endl; |
|
|
|
|
cout << "To finish capturing, press 'ESC' key and calibration starts." << endl; |
|
|
|
|
cout << "Parameters: " << endl; |
|
|
|
|
cout << "-w <nmarkers> # Number of markers in X direction" << endl; |
|
|
|
|
cout << "-h <nsquares> # Number of squares in Y direction" << endl; |
|
|
|
|
cout << "-sl <squareLength> # Square side lenght (in meters)" << endl; |
|
|
|
|
cout << "-ml <markerLength> # Marker side lenght (in meters)" << endl; |
|
|
|
|
cout << "-d <dictionary> # DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2, " |
|
|
|
|
<< "DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, " |
|
|
|
|
<< "DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12," |
|
|
|
|
<< "DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16" << endl; |
|
|
|
|
cout << "-o <outputFile> # Output file with calibrated camera parameters" << endl; |
|
|
|
|
cout << "[-v <videoFile>] # Input from video file, if ommited, input comes from camera" << endl; |
|
|
|
|
cout << "[-ci <int>] # Camera id if input doesnt come from video (-v). Default is 0" << endl; |
|
|
|
|
cout << "[-dp <detectorParams>] # File of marker detector parameters" << endl; |
|
|
|
|
cout << "[-rs] # Apply refind strategy" << endl; |
|
|
|
|
cout << "[-zt] # Assume zero tangential distortion" << endl; |
|
|
|
|
cout << "[-a <aspectRatio>] # Fix aspect ratio (fx/fy)" << endl; |
|
|
|
|
cout << "[-p] # Fix the principal point at the center" << endl; |
|
|
|
|
cout << "[-sc] # Show detected chessboard corners after calibration" << endl; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*/ |
|
|
|
|
static bool isParam(string param, int argc, char **argv) { |
|
|
|
|
for(int i = 0; i < argc; i++) |
|
|
|
|
if(string(argv[i]) == param) return true; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*/ |
|
|
|
|
static string getParam(string param, int argc, char **argv, string defvalue = "") { |
|
|
|
|
int idx = -1; |
|
|
|
|
for(int i = 0; i < argc && idx == -1; i++) |
|
|
|
|
if(string(argv[i]) == param) idx = i; |
|
|
|
|
if(idx == -1 || (idx + 1) >= argc) |
|
|
|
|
return defvalue; |
|
|
|
|
else |
|
|
|
|
return argv[idx + 1]; |
|
|
|
|
namespace { |
|
|
|
|
const char* about = |
|
|
|
|
"Calibration using a ChArUco board\n" |
|
|
|
|
" To capture a frame for calibration, press 'c',\n" |
|
|
|
|
" If input comes from video, press any key for next frame\n" |
|
|
|
|
" To finish capturing, press 'ESC' key and calibration starts.\n"; |
|
|
|
|
const char* keys = |
|
|
|
|
"{w | | Number of squares in X direction }" |
|
|
|
|
"{h | | Number of squares in Y direction }" |
|
|
|
|
"{sl | | Square side lenght (in pixels) }" |
|
|
|
|
"{ml | | Marker side lenght (in pixels) }" |
|
|
|
|
"{d | | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2," |
|
|
|
|
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, " |
|
|
|
|
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12," |
|
|
|
|
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}" |
|
|
|
|
"{@outfile |<none> | Output file with calibrated camera parameters }" |
|
|
|
|
"{v | | Input from video file, if ommited, input comes from camera }" |
|
|
|
|
"{ci | 0 | Camera id if input doesnt come from video (-v) }" |
|
|
|
|
"{dp | | File of marker detector parameters }" |
|
|
|
|
"{rs | false | Apply refind strategy }" |
|
|
|
|
"{zt | false | Assume zero tangential distortion }" |
|
|
|
|
"{a | | Fix aspect ratio (fx/fy) to this value }" |
|
|
|
|
"{pc | false | Fix the principal point at the center }" |
|
|
|
|
"{sc | false | Show detected chessboard corners after calibration }"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*/ |
|
|
|
|
static bool readDetectorParameters(string filename, aruco::DetectorParameters ¶ms) { |
|
|
|
@ -177,57 +149,67 @@ static bool saveCameraParams(const string &filename, Size imageSize, float aspec |
|
|
|
|
/**
|
|
|
|
|
*/ |
|
|
|
|
int main(int argc, char *argv[]) { |
|
|
|
|
CommandLineParser parser(argc, argv, keys); |
|
|
|
|
parser.about(about); |
|
|
|
|
|
|
|
|
|
if(!isParam("-w", argc, argv) || !isParam("-h", argc, argv) || !isParam("-sl", argc, argv) || |
|
|
|
|
!isParam("-ml", argc, argv) || !isParam("-d", argc, argv) || !isParam("-o", argc, argv)) { |
|
|
|
|
help(); |
|
|
|
|
if(argc < 7) { |
|
|
|
|
parser.printMessage(); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int squaresX = atoi(getParam("-w", argc, argv).c_str()); |
|
|
|
|
int squaresY = atoi(getParam("-h", argc, argv).c_str()); |
|
|
|
|
float squareLength = (float)atof(getParam("-sl", argc, argv).c_str()); |
|
|
|
|
float markerLength = (float)atof(getParam("-ml", argc, argv).c_str()); |
|
|
|
|
int dictionaryId = atoi(getParam("-d", argc, argv).c_str()); |
|
|
|
|
aruco::Dictionary dictionary = |
|
|
|
|
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); |
|
|
|
|
string outputFile = getParam("-o", argc, argv); |
|
|
|
|
int squaresX = parser.get<int>("w"); |
|
|
|
|
int squaresY = parser.get<int>("h"); |
|
|
|
|
float squareLength = parser.get<float>("sl"); |
|
|
|
|
float markerLength = parser.get<float>("ml"); |
|
|
|
|
int dictionaryId = parser.get<int>("d"); |
|
|
|
|
string outputFile = parser.get<string>(0); |
|
|
|
|
|
|
|
|
|
bool showChessboardCorners = isParam("-sc", argc, argv); |
|
|
|
|
bool showChessboardCorners = parser.get<bool>("sc"); |
|
|
|
|
|
|
|
|
|
int calibrationFlags = 0; |
|
|
|
|
float aspectRatio = 1; |
|
|
|
|
if(isParam("-a", argc, argv)) { |
|
|
|
|
if(parser.has("a")) { |
|
|
|
|
calibrationFlags |= CALIB_FIX_ASPECT_RATIO; |
|
|
|
|
aspectRatio = (float)atof(getParam("-a", argc, argv).c_str()); |
|
|
|
|
aspectRatio = parser.get<float>("a"); |
|
|
|
|
} |
|
|
|
|
if(isParam("-zt", argc, argv)) calibrationFlags |= CALIB_ZERO_TANGENT_DIST; |
|
|
|
|
if(isParam("-p", argc, argv)) calibrationFlags |= CALIB_FIX_PRINCIPAL_POINT; |
|
|
|
|
if(parser.get<bool>("zt")) calibrationFlags |= CALIB_ZERO_TANGENT_DIST; |
|
|
|
|
if(parser.get<bool>("pc")) calibrationFlags |= CALIB_FIX_PRINCIPAL_POINT; |
|
|
|
|
|
|
|
|
|
aruco::DetectorParameters detectorParams; |
|
|
|
|
if(isParam("-dp", argc, argv)) { |
|
|
|
|
bool readOk = readDetectorParameters(getParam("-dp", argc, argv), detectorParams); |
|
|
|
|
if(parser.has("dp")) { |
|
|
|
|
bool readOk = readDetectorParameters(parser.get<string>("dp"), detectorParams); |
|
|
|
|
if(!readOk) { |
|
|
|
|
cerr << "Invalid detector parameters file" << endl; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool refindStrategy = false; |
|
|
|
|
if(isParam("-rs", argc, argv)) refindStrategy = true; |
|
|
|
|
bool refindStrategy = parser.get<bool>("rs"); |
|
|
|
|
int camId = parser.get<int>("ci"); |
|
|
|
|
String video; |
|
|
|
|
|
|
|
|
|
if(parser.has("v")) { |
|
|
|
|
video = parser.get<String>("v"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(!parser.check()) { |
|
|
|
|
parser.printErrors(); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
VideoCapture inputVideo; |
|
|
|
|
int waitTime; |
|
|
|
|
if(isParam("-v", argc, argv)) { |
|
|
|
|
inputVideo.open(getParam("-v", argc, argv)); |
|
|
|
|
if(!video.empty()) { |
|
|
|
|
inputVideo.open(video); |
|
|
|
|
waitTime = 0; |
|
|
|
|
} else { |
|
|
|
|
int camId = 0; |
|
|
|
|
if(isParam("-ci", argc, argv)) camId = atoi(getParam("-ci", argc, argv).c_str()); |
|
|
|
|
inputVideo.open(camId); |
|
|
|
|
waitTime = 10; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
aruco::Dictionary dictionary = |
|
|
|
|
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); |
|
|
|
|
|
|
|
|
|
// create charuco board object
|
|
|
|
|
aruco::CharucoBoard board = |
|
|
|
|
aruco::CharucoBoard::create(squaresX, squaresY, squareLength, markerLength, dictionary); |
|
|
|
|