Improved external calibration argument parser

This commit is contained in:
Thomas FORGIONE 2015-04-21 14:41:53 +02:00
parent a3428fa81c
commit ab2fef9147
5 changed files with 87 additions and 139 deletions

View File

@ -3,4 +3,4 @@ file(GLOB EXTERN_SRC
)
add_executable(ExternalCalibration ${EXTERN_SRC})
target_link_libraries(ExternalCalibration ${OpenCV_LIBS})
target_link_libraries(ExternalCalibration ${OpenCV_LIBS} ${Boost_LIBRARIES})

View File

@ -51,7 +51,7 @@ bool Camera::init( std::string calibFilename )
if( !fs.open(calibFilename, cv::FileStorage::READ))
{
std::cerr << "Cannot open calib file" << std::endl;
return -1;
return false;
}
@ -71,8 +71,8 @@ bool Camera::init( std::string calibFilename )
fs["image_width"] >> imageSize.width;
fs["image_height"] >> imageSize.height;
std::cout << matK << std::endl;
std::cout << distCoeff << std::endl;
// std::cout << matK << std::endl;
// std::cout << distCoeff << std::endl;
return true;
}

View File

@ -61,15 +61,14 @@ bool ChessboardCameraTracker::process( cv::Mat &img, cv::Mat &pose, const Camera
// of the image.
//******************************************************************/
cv::undistort(img, undistorted_img, cam.matK, cam.distCoeff);
cv::imshow("Image View", undistorted_img);
cv::waitKey(-1);
// cv::imshow("Image View", undistorted_img);
//******************************************************************/
// detect the chessboard
//******************************************************************/
found = detectChessboard(undistorted_img, corners, boardSize);
// cout << ( (!found ) ? ( "No " ) : ("") ) << "chessboard detected!" << endl;
cv::drawChessboardCorners(undistorted_img, boardSize, corners, found);
// cv::drawChessboardCorners(undistorted_img, boardSize, corners, found);
//******************************************************************/
// if a chessboard is found estimate the homography and rectify the image

View File

@ -31,181 +31,130 @@
#include "Extern/ChessboardCameraTracker.hpp"
#include "Extern/utility.hpp"
#include <boost/program_options.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>
#include <string.h>
#include <fstream>
#include <iostream>
#include <time.h>
// Display the help for the programm
void help( const char* programName );
// parse the input command line arguments
bool parseArgs( int argc, char**argv, cv::Size &boardSize, std::string &inputFilename );
// Return a pair of boolean
// - the first one is true if the execution must go on
// - the second one is false if there was a problem (main must return non-0 value)
std::pair<bool, bool> parseArgs(int argc, char**argv, cv::Size &boardSize, std::string &inputFilename, std::string& calibFilename, bool& displayImage, std::string& outputFilename)
{
namespace po = boost::program_options;
try
{
po::options_description desc("Allowed options");
desc.add_options()
("help", "procude help message")
("calib,c", po::value<std::string>(&calibFilename)->required(), "path to the calibration file")
("width,w", po::value<int>(&boardSize.width)->required(), "number of corners per line in the chessboard")
("height,h", po::value<int>(&boardSize.height)->required(), "number of corners per coloumn in the chessboard")
("image,i", po::value<std::string>(&inputFilename)->required(), "image to calibrate")
("output,o", po::value<std::string>(&outputFilename), "path to the output file (stdout if not specified)")
("show-image,s", "show the reference system in augmented reality on the picture");
po::positional_options_description p;
p.add("image", -1);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
po::notify(vm);
displayImage = vm.count("show-image");
if (vm.count("help"))
{
std::cout << desc << "\n";
return {false, true};
}
}
catch (std::exception const& e)
{
std::cerr << "Unable to parse : " << e.what() << std::endl;
return {false, false};
}
return {true, true};
}
int main( int argc, char** argv )
{
/******************************************************************/
/* CONSTANTS to use */
/******************************************************************/
std::string calibFilename, outputFilename;
bool displayImage;
// the name of the window
const std::string WINDOW_NAME = "Image View";
/******************************************************************/
/* VARIABLES TO use */
/******************************************************************/
cv::Mat view; // it will contain the original image loaded from file
Camera cam;
cam.init("/home/thomas/Paella/Code/data/xml/calib.xml");
ChessboardCameraTracker tracker;
cv::Mat pose;
std::vector<cv::Point2f> pointbuf; // it will contain the detected corners on the chessboard
// it will contain the size in terms of corners (width X height) of the chessboard
cv::Size boardSize;
// it will contains the filename of the image file
std::string inputFilename;
// Parse the arugments
auto pair = parseArgs(argc, argv, boardSize, inputFilename, calibFilename, displayImage, outputFilename);
/******************************************************************/
/* READ THE INPUT PARAMETERS - DO NOT MODIFY */
/******************************************************************/
if( !parseArgs( argc, argv, boardSize, inputFilename) )
if (!pair.second)
{
std::cerr << "Aborting..." << std::endl;
return EXIT_FAILURE;
}
if (!pair.first)
{
return EXIT_SUCCESS;
}
/******************************************************************/
/* PART TO DEVELOP */
/******************************************************************/
/******************************************************************/
// create a window to display the image --> see namedWindow
/******************************************************************/
cv::namedWindow(WINDOW_NAME, CV_WINDOW_AUTOSIZE );
/******************************************************************/
// read the input image from file into "view" --> see imread
/******************************************************************/
if (!cam.init(calibFilename))
{
return EXIT_FAILURE;
}
view = cv::imread(inputFilename, CV_LOAD_IMAGE_COLOR);
//Measure the execution time, get time before function call
// double t = (double)cv::getTickCount();
/******************************************************************/
// call the function that detects the chessboard on the image
// found = detectChessboard...
/******************************************************************/
// found = detectChessboard(view, pointbuf, boardSize, pattern);
// // get time after function call and display info
// t = ((double)cv::getTickCount() - t)/cv::getTickFrequency();
// std::cout << ( (!found ) ? ( "No " ) : ("") ) << "chessboard detected!" << std::endl;
// std::cout << "Chessboard detection took " << t*1000 << "ms" << std::endl;
// /******************************************************************/
// // if the chessboard is found draw the cornerns on top of it
// // --> see drawChessboardCorners
// /******************************************************************/
// cv::drawChessboardCorners(view, boardSize, pointbuf, found);
if(tracker.process(view, pose, cam, boardSize))
{
std::cout << "Drawing Reference system"<< std::endl;
drawReferenceSystem(view,cam,pose,1,200,false );
std::cout << "Process worked correctly !"<< std::endl;
if (displayImage)
{
const std::string WINDOW_NAME = "External calibration";
cv::namedWindow(WINDOW_NAME, CV_WINDOW_AUTOSIZE );
drawReferenceSystem(view,cam,pose,1,200,false );
cv::imshow(WINDOW_NAME, view);
cv::waitKey( -1 );
}
}
else
{
std::cout << "Unable to process" << std::endl;
return EXIT_FAILURE;
}
/******************************************************************/
// show the image inside the window --> see imshow
/******************************************************************/
// cv::resize(view, view, cv::Size{view.cols/5, view.rows/5});
cv::imshow(WINDOW_NAME, view);
// wait for user input before ending --> see waitKey
cv::waitKey( -1 );
if (outputFilename == "")
{
std::cout << "External matrix is \n" << pose << std::endl;
}
else
{
std::ofstream file{outputFilename};
file << pose << std::endl;
}
return EXIT_SUCCESS;
}
// Display the help for the programm
void help( const char* programName )
{
std::cout << "Detect a chessboard in a given image" << std::endl
<< "Usage: " << programName << std::endl
<< " -w <board_width> # the number of inner corners per one of board dimension" << std::endl
<< " -h <board_height> # the number of inner corners per another board dimension" << std::endl
<< " [-pt <pattern=[circles|acircles|chess]>] # the type of pattern: chessboard or circles' grid" << std::endl
<< " <image file> " << std::endl
<< std::endl;
}
// parse the input command line arguments
bool parseArgs( int argc, char**argv, cv::Size &boardSize, std::string &inputFilename )
{
// check the minimum number of arguments
if( argc < 3 )
{
help( argv[0] );
return false;
}
// Read the input arguments
for( int i = 1; i < argc; i++ )
{
const char* s = argv[i];
if( strcmp( s, "-w" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.width ) != 1 || boardSize.width <= 0 )
{
std::cerr << "Invalid board width" << std::endl;
return false;
}
}
else if( strcmp( s, "-h" ) == 0 )
{
if( sscanf( argv[++i], "%u", &boardSize.height ) != 1 || boardSize.height <= 0 )
{
std::cerr << "Invalid board height" << std::endl;
return false;
}
}
else if( s[0] != '-' )
{
inputFilename.assign(s);
}
else
{
std::cerr << "Unknown option " << s << std::endl;
return false;
}
}
return true;
}

View File

@ -250,7 +250,7 @@ void decomposeHomography( const cv::Mat &H, const cv::Mat& matK, cv::Mat& poseMa
// std::cout << "----------------------------" << std::endl;
// std::cout << r1 << std::endl;
// std::cout << "----------------------------" << std::endl;
std::cout << poseMat << std::endl;
// std::cout << poseMat << std::endl;
// std::cout << "----------------------------" << std::endl;
}