CommandLineParser这个类,那么这个类到底有什么作用呢,从命名大概可以猜出这是个命令行解析类。因为我们知道opencv是一个开源库,所以其很少有图形操作方面的api,基本上还是基于命令行执行的。那么这个类的出现主要是方便用户在命令行使用过程中减少工作量。
大概可以看出来用这个类的好处就是很方便,因为以前版本没这个类时,如果要运行带参数的.exe,必须在命令行中输入文件路径以及各种参数,并且输入的参数格式要与代码中的if语句判断内容格式一样,一不小心就输错了,很不方便。另外如果想要更改输入格式的话在主函数文件中要相应更改很多地方。现在有了这个类,只需要改keys里面的内容就可以了,并且运行时可以直接在vs下用F5,不需要cmd命令行带参运行。最后这个类封装了很多函数,可以直接用,只不过这个本来就是类结构的优点。
class CV_EXPORTS CommandLineParser
{
public:
/*
* 函数功能:构造函数
* 参数:
* [in] argc main函数中的第一参数,即运行程序中获得指令的个数
* [in] argv main函数中的第二个参数,即运行程序中指令的内容
* [in] key_map 当启动程序是没有输入任何指令,则使用key_map中默认的指指令。
* 备注:
* key_map中的格式:
* "{ s| 123asd |string parameter}
* { d| 100 |digit parameter }
* { @c| false |without camera }
* { 1| some text |help }
* { 2| 333 |another help }"
*参数or指令名称|指令or参数内容 |指令说明
*
*
* 运行程序输入指令的方式如下:(例如程序名称为extest.exe)
* extest.exe -s=123asdd -d=1000 -@c=10
* 注意:指令名称前面需要加一个“-”,或“--”。当输入指令后面没有参数,默认为true
* 另外,前面加@的指令可以不输入指令名称,直接设置指令内容即可。
* 没有输入的指令,则使用key_map中的默认值
*/
CommandLineParser(int argc, const char* const argv[], const String& keys);
CommandLineParser(const CommandLineParser& parser);
CommandLineParser& operator = (const CommandLineParser& parser);
~CommandLineParser();
String getPathToApplication() const;
/*
* 函数功能:获得指令名称的参数值
* 参数:
* [in] name 指令名称,注意此处不要加"-"
* [in] space_delete 此参数默认为true,把参数内容中的头尾的空格去掉。
*/
template
T get(const String& name, bool space_delete = true) const
{
T val = T();
getByName(name, space_delete, ParamType::type, (void*)&val);
return val;
}
template
T get(int index, bool space_delete = true) const
{
T val = T();
getByIndex(index, space_delete, ParamType::type, (void*)&val);
return val;
}
/*
* 函数功能:查看是否有此指令名称,如果没有此指令名称报错;若果有此指令,并且此指令有值,则返回true
* 参数:
* [in] keys 指令名称
* 返回值
* 含有返回true
* 备注:
* 此函数本质上是检查两个东西:
* 1、此指令是否存在
* 2、此指令对应的指令内容存在;
* 以上二者都存在,返回true;
* 所以,只要在命令行输入此值令,并且指令存在,一定返回ture.(因为如果不指定参数内容,系统会默认true)
* 但是,在构造函数key_map中,如果指令参数没有填写。即使key_map中存在此指令,也会返回false。(因为没有参数内容)(另外;前提是命令行没有输入此指令)
*/
bool has(const String& name) const;
/*
* 函数功能:检查输入的指令是否有有错误,即无法解析
* 参数:
* [in]
* 返回值:
* 没有错误返回true,有错误返回false
*/
bool check() const;
void about(const String& message);
void printMessage() const;
void printErrors() const;
protected:
void getByName(const String& name, bool space_delete, int type, void* dst) const;
void getByIndex(int index, bool space_delete, int type, void* dst) const;
struct Impl;
Impl* impl;
};
* 运行程序输入指令的方式如下:(例如程序名称为extest.exe)
* extest.exe -s=123asdd -d=1000 -@c=10
keys指针
#include
#include
#include
using namespace std;
// OpenCV includes
#include "opencv2/core.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
// OpenCV command line parser functions
// Keys accecpted by command line parser
const char* keys =
{
"{help h usage ? | | print this message}"
"{@video | | Video file, if not defined try to use webcamera}"
};
int main( int argc, const char** argv )
{
CommandLineParser parser(argc, argv, keys);
parser.about("Chapter 2. v1.0.0");
//If requires help show
if (parser.has("help"))
{
parser.printMessage();
return 0;
}
String videoFile= parser.get(0);
// Check if params are correctly parsed in his variables
if (!parser.check())
{
parser.printErrors();
return 0;
}
VideoCapture cap; // open the default camera
if(videoFile != "")
cap.open(videoFile);
else
cap.open(0);
if(!cap.isOpened()) // check if we succeeded
return -1;
namedWindow("Video",1);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
imshow("Video", frame);
if(waitKey(30) >= 0) break;
}
// Release the camera or video cap
cap.release();
return 0;
}
前面加@的指令可以不输入指令名称,直接设置指令内容即可前面加@的指令可以不输入指令名称,直接设置指令内容即可
注释的几条函数为常用函数:
1、构造函数------接收命令行输入的指令
* 运行程序输入指令的方式如下:(例如程序名称为extest.exe)
* extest.exe -s=123asdd -d=1000 -@c=10
2、get-----获得指定的参数的内容
3、has----在get之前可以先检查是否含有此指令
4、check---在使用这些参数之前,检查是否有解析错误的现象;
int main( int argc, char** argv )
{
cv::CommandLineParser parser(argc, argv,
"{help||}{w|8|}{h|11|}{pt|chessboard|}{n|10|}{d|1000|}{s|20|}{o|out_camera_data.yml|}"
"{op||}{oe||}{zt||}{a|1|}{p||}{v||}{V|0|}{su|1|}"
"{@input_data|0|}"); //
if (parser.has("help"))
{
help();
return 0;
}
boardSize.width = parser.get( "w" );
boardSize.height = parser.get( "h" );
if ( parser.has("pt") )
{
string val = parser.get("pt");
if( val == "circles" )
pattern = CIRCLES_GRID;
else if( val == "acircles" )
pattern = ASYMMETRIC_CIRCLES_GRID;
else if( val == "chessboard" )
pattern = CHESSBOARD;
else
return fprintf( stderr, "Invalid pattern type: must be chessboard or circles\n" ), -1;
}
squareSize = parser.get("s");
nframes = parser.get("n");
aspectRatio = parser.get("a");
delay = parser.get("d");
writePoints = parser.has("op");
writeExtrinsics = parser.has("oe");
if (parser.has("a"))
flags |= CALIB_FIX_ASPECT_RATIO;
if ( parser.has("zt") )
flags |= CALIB_ZERO_TANGENT_DIST;
if ( parser.has("p") )
flags |= CALIB_FIX_PRINCIPAL_POINT;
flipVertical = parser.has("v");
videofile = parser.has("V");
if ( parser.has("o") )
outputFilename = parser.get("o");
showUndistorted = parser.has("su");
if ( isdigit(parser.get("@input_data")[0]) )
cameraId = parser.get("@input_data");
else
inputFilename = parser.get("@input_data");
if (!parser.check())
{
help();
parser.printErrors();
return -1;
}