mirror of
https://github.com/opencv/opencv.git
synced 2024-11-24 03:00:14 +08:00
added aruco pattern into stereo_calibration.cpp
This commit is contained in:
parent
f5a92cb43f
commit
fa5c5f4105
@ -24,6 +24,7 @@
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/objdetect/charuco_detector.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@ -40,21 +41,31 @@ using namespace std;
|
||||
static int print_help(char** argv)
|
||||
{
|
||||
cout <<
|
||||
" Given a list of chessboard images, the number of corners (nx, ny)\n"
|
||||
" on the chessboards, and a flag: useCalibrated for \n"
|
||||
" Given a list of chessboard or ChArUco images, the number of corners (nx, ny)\n"
|
||||
" on the chessboards and the number of squares (nx, ny) on ChArUco,\n"
|
||||
" and a flag: useCalibrated for \n"
|
||||
" calibrated (0) or\n"
|
||||
" uncalibrated \n"
|
||||
" (1: use stereoCalibrate(), 2: compute fundamental\n"
|
||||
" matrix separately) stereo. \n"
|
||||
" Calibrate the cameras and display the\n"
|
||||
" rectified results along with the computed disparity images. \n" << endl;
|
||||
cout << "Usage:\n " << argv[0] << " -w=<board_width default=9> -h=<board_height default=6> -s=<square_size default=1.0> <image list XML/YML file default=stereo_calib.xml>\n" << endl;
|
||||
cout << "Usage:\n " << argv[0] << " -w=<board_width default=9> -h=<board_height default=6>"
|
||||
<<" -t=<pattern type: chessboard or charucoboard default=chessboard> -s=<square_size default=1.0> -ms=<marker size default=0.5>"
|
||||
<<" -ad=<predefined aruco dictionary name default=DICT_4X4_50> -adf=<aruco dictionary file default=None>"
|
||||
<<" <image list XML/YML file default=stereo_calib.xml>\n" << endl;
|
||||
cout << "Available Aruco dictionaries: DICT_4X4_50, DICT_4X4_100, DICT_4X4_250, "
|
||||
<< "DICT_4X4_1000, DICT_5X5_50, DICT_5X5_100, DICT_5X5_250, DICT_5X5_1000, "
|
||||
<< "DICT_6X6_50, DICT_6X6_100, DICT_6X6_250, DICT_6X6_1000, DICT_7X7_50, "
|
||||
<< "DICT_7X7_100, DICT_7X7_250, DICT_7X7_1000, DICT_ARUCO_ORIGINAL, "
|
||||
<< "DICT_APRILTAG_16h5, DICT_APRILTAG_25h9, DICT_APRILTAG_36h10, DICT_APRILTAG_36h11\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
StereoCalib(const vector<string>& imagelist, Size boardSize, float squareSize, bool displayCorners = false, bool useCalibrated=true, bool showRectified=true)
|
||||
StereoCalib(const vector<string>& imagelist, Size inputBoardSize, string type, float squareSize, float markerSize, cv::aruco::PredefinedDictionaryType arucoDict, string arucoDictFile, bool displayCorners = false, bool useCalibrated=true, bool showRectified=true)
|
||||
{
|
||||
if( imagelist.size() % 2 != 0 )
|
||||
{
|
||||
@ -75,6 +86,37 @@ StereoCalib(const vector<string>& imagelist, Size boardSize, float squareSize, b
|
||||
imagePoints[1].resize(nimages);
|
||||
vector<string> goodImageList;
|
||||
|
||||
Size boardSizeInnerCorners, boardSizeUnits;
|
||||
if (type == "chessboard") {
|
||||
//chess board pattern boardSize is given in inner corners
|
||||
boardSizeInnerCorners = inputBoardSize;
|
||||
boardSizeUnits.height = inputBoardSize.height+1;
|
||||
boardSizeUnits.width = inputBoardSize.width+1;
|
||||
}
|
||||
else if (type == "charucoboard") {
|
||||
//ChArUco board pattern boardSize is given in squares units
|
||||
boardSizeUnits = inputBoardSize;
|
||||
boardSizeInnerCorners.width = inputBoardSize.width - 1;
|
||||
boardSizeInnerCorners.height = inputBoardSize.height - 1;
|
||||
}
|
||||
else {
|
||||
std::cout << "unknown pattern type " << type << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
cv::aruco::Dictionary dictionary;
|
||||
if (arucoDictFile == "None") {
|
||||
dictionary = cv::aruco::getPredefinedDictionary(arucoDict);
|
||||
}
|
||||
else {
|
||||
cv::FileStorage dict_file(arucoDictFile, cv::FileStorage::Mode::READ);
|
||||
cv::FileNode fn(dict_file.root());
|
||||
dictionary.readDictionary(fn);
|
||||
}
|
||||
cv::aruco::CharucoBoard ch_board(boardSizeUnits, squareSize, markerSize, dictionary);
|
||||
cv::aruco::CharucoDetector ch_detector(ch_board);
|
||||
std::vector<int> markerIds;
|
||||
|
||||
for( i = j = 0; i < nimages; i++ )
|
||||
{
|
||||
for( k = 0; k < 2; k++ )
|
||||
@ -99,8 +141,19 @@ StereoCalib(const vector<string>& imagelist, Size boardSize, float squareSize, b
|
||||
timg = img;
|
||||
else
|
||||
resize(img, timg, Size(), scale, scale, INTER_LINEAR_EXACT);
|
||||
found = findChessboardCorners(timg, boardSize, corners,
|
||||
CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE);
|
||||
|
||||
if (type == "chessboard") {
|
||||
found = findChessboardCorners(timg, boardSizeInnerCorners, corners,
|
||||
CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE);
|
||||
}
|
||||
else if (type == "charucoboard") {
|
||||
ch_detector.detectBoard(timg, corners, markerIds);
|
||||
found = corners.size() == (size_t) (boardSizeInnerCorners.height*boardSizeInnerCorners.width);
|
||||
}
|
||||
else {
|
||||
cout << "Error: unknown pattern " << type << "\n";
|
||||
return;
|
||||
}
|
||||
if( found )
|
||||
{
|
||||
if( scale > 1 )
|
||||
@ -116,7 +169,7 @@ StereoCalib(const vector<string>& imagelist, Size boardSize, float squareSize, b
|
||||
cout << filename << endl;
|
||||
Mat cimg, cimg1;
|
||||
cvtColor(img, cimg, COLOR_GRAY2BGR);
|
||||
drawChessboardCorners(cimg, boardSize, corners, found);
|
||||
drawChessboardCorners(cimg, boardSizeInnerCorners, corners, found);
|
||||
double sf = 640./MAX(img.rows, img.cols);
|
||||
resize(cimg, cimg1, Size(), sf, sf, INTER_LINEAR_EXACT);
|
||||
imshow("corners", cimg1);
|
||||
@ -128,9 +181,11 @@ StereoCalib(const vector<string>& imagelist, Size boardSize, float squareSize, b
|
||||
putchar('.');
|
||||
if( !found )
|
||||
break;
|
||||
cornerSubPix(img, corners, Size(11,11), Size(-1,-1),
|
||||
TermCriteria(TermCriteria::COUNT+TermCriteria::EPS,
|
||||
30, 0.01));
|
||||
if (type == "chessboard") {
|
||||
cornerSubPix(img, corners, Size(11, 11), Size(-1, -1),
|
||||
TermCriteria(TermCriteria::COUNT + TermCriteria::EPS,
|
||||
30, 0.01));
|
||||
}
|
||||
}
|
||||
if( k == 2 )
|
||||
{
|
||||
@ -153,8 +208,8 @@ StereoCalib(const vector<string>& imagelist, Size boardSize, float squareSize, b
|
||||
|
||||
for( i = 0; i < nimages; i++ )
|
||||
{
|
||||
for( j = 0; j < boardSize.height; j++ )
|
||||
for( k = 0; k < boardSize.width; k++ )
|
||||
for( j = 0; j < boardSizeInnerCorners.height; j++ )
|
||||
for( k = 0; k < boardSizeInnerCorners.width; k++ )
|
||||
objectPoints[i].push_back(Point3f(k*squareSize, j*squareSize, 0));
|
||||
}
|
||||
|
||||
@ -342,17 +397,49 @@ static bool readStringList( const string& filename, vector<string>& l )
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Size boardSize;
|
||||
Size inputBoardSize;
|
||||
string imagelistfn;
|
||||
bool showRectified;
|
||||
cv::CommandLineParser parser(argc, argv, "{w|9|}{h|6|}{s|1.0|}{nr||}{help||}{@input|stereo_calib.xml|}");
|
||||
cv::CommandLineParser parser(argc, argv, "{w|9|}{h|6|}{t|chessboard|}{s|1.0|}{ms|0.5|}{ad|DICT_4X4_50|}{adf|None|}{nr||}{help||}{@input|stereo_calib.xml|}");
|
||||
if (parser.has("help"))
|
||||
return print_help(argv);
|
||||
showRectified = !parser.has("nr");
|
||||
imagelistfn = samples::findFile(parser.get<string>("@input"));
|
||||
boardSize.width = parser.get<int>("w");
|
||||
boardSize.height = parser.get<int>("h");
|
||||
inputBoardSize.width = parser.get<int>("w");
|
||||
inputBoardSize.height = parser.get<int>("h");
|
||||
string type = parser.get<string>("t");
|
||||
float squareSize = parser.get<float>("s");
|
||||
float markerSize = parser.get<float>("ms");
|
||||
string arucoDictName = parser.get<string>("ad");
|
||||
string arucoDictFile = parser.get<string>("adf");
|
||||
|
||||
cv::aruco::PredefinedDictionaryType arucoDict;
|
||||
if (arucoDictName == "DICT_4X4_50") { arucoDict = cv::aruco::DICT_4X4_50; }
|
||||
else if (arucoDictName == "DICT_4X4_100") { arucoDict = cv::aruco::DICT_4X4_100; }
|
||||
else if (arucoDictName == "DICT_4X4_250") { arucoDict = cv::aruco::DICT_4X4_250; }
|
||||
else if (arucoDictName == "DICT_4X4_1000") { arucoDict = cv::aruco::DICT_4X4_1000; }
|
||||
else if (arucoDictName == "DICT_5X5_50") { arucoDict = cv::aruco::DICT_5X5_50; }
|
||||
else if (arucoDictName == "DICT_5X5_100") { arucoDict = cv::aruco::DICT_5X5_100; }
|
||||
else if (arucoDictName == "DICT_5X5_250") { arucoDict = cv::aruco::DICT_5X5_250; }
|
||||
else if (arucoDictName == "DICT_5X5_1000") { arucoDict = cv::aruco::DICT_5X5_1000; }
|
||||
else if (arucoDictName == "DICT_6X6_50") { arucoDict = cv::aruco::DICT_6X6_50; }
|
||||
else if (arucoDictName == "DICT_6X6_100") { arucoDict = cv::aruco::DICT_6X6_100; }
|
||||
else if (arucoDictName == "DICT_6X6_250") { arucoDict = cv::aruco::DICT_6X6_250; }
|
||||
else if (arucoDictName == "DICT_6X6_1000") { arucoDict = cv::aruco::DICT_6X6_1000; }
|
||||
else if (arucoDictName == "DICT_7X7_50") { arucoDict = cv::aruco::DICT_7X7_50; }
|
||||
else if (arucoDictName == "DICT_7X7_100") { arucoDict = cv::aruco::DICT_7X7_100; }
|
||||
else if (arucoDictName == "DICT_7X7_250") { arucoDict = cv::aruco::DICT_7X7_250; }
|
||||
else if (arucoDictName == "DICT_7X7_1000") { arucoDict = cv::aruco::DICT_7X7_1000; }
|
||||
else if (arucoDictName == "DICT_ARUCO_ORIGINAL") { arucoDict = cv::aruco::DICT_ARUCO_ORIGINAL; }
|
||||
else if (arucoDictName == "DICT_APRILTAG_16h5") { arucoDict = cv::aruco::DICT_APRILTAG_16h5; }
|
||||
else if (arucoDictName == "DICT_APRILTAG_25h9") { arucoDict = cv::aruco::DICT_APRILTAG_25h9; }
|
||||
else if (arucoDictName == "DICT_APRILTAG_36h10") { arucoDict = cv::aruco::DICT_APRILTAG_36h10; }
|
||||
else if (arucoDictName == "DICT_APRILTAG_36h11") { arucoDict = cv::aruco::DICT_APRILTAG_36h11; }
|
||||
else {
|
||||
cout << "incorrect name of aruco dictionary \n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!parser.check())
|
||||
{
|
||||
parser.printErrors();
|
||||
@ -366,6 +453,6 @@ int main(int argc, char** argv)
|
||||
return print_help(argv);
|
||||
}
|
||||
|
||||
StereoCalib(imagelist, boardSize, squareSize, false, true, showRectified);
|
||||
StereoCalib(imagelist, inputBoardSize, type, squareSize, markerSize, arucoDict, arucoDictFile, false, true, showRectified);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user