OpenCV命令行输入解析器CommandLineParser使用介绍
OpenCV的语义分割代码里面,随处可见的CommandLineParser类。将不同的模型和配置文件,都单独拎出来,用命令行输入进行配置。因此,需要了解基本的使用方法。
OpenCV中CommandLineParse类主要是命令行解析类。OpenCV中出现此类的主要目:方便用户在命令行使用过程中减少工作量。具体使用方式如下。
我们将从三个方面介绍。首先是CommandLineParser类的构造函数,说明一下这个类的一些常用成员函数;随后介绍如何按需添加和配置参数和变量;最后直接使用Visual Studio 或者生成的exe文件,来按照命令行的方式,输入参数,并运行得到结果。
1. CommandLineParser构造类简介
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 <typename T>
T get(const String& name, bool space_delete = true) const
{
T val = T();
getByName(name, space_delete, ParamType<T>::type, (void*)&val);
return val;
}
template <typename T>
T get(int index, bool space_delete = true) const
{
T val = T();
getByIndex(index, space_delete, ParamType<T>::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;
};
2. CommandLineParser的使用方法
在keys中,添加需要命令行输入的参数,如下,OpenCV的语义分割模块c++代码中的片段。我们需要添加模型文件:model;输入图像:image;输出结果:result;是否展示image:show。
单个参数,是按照如下方式定义的:
“{ arg_name | default number | argument description}”
{输入参数的名称 m | 默认值 | 参数的描述性文字}.
const String keys =
"{help h || Sample app for loading ENet Torch model. "
"The model and class names list can be downloaded here: "
"https://www.dropbox.com/sh/dywzk3gyb12hpe5/AAD5YkUa8XgMpHs2gCRgmCVCa }"
"{model m |./model-cityscapes.net| path to Torch .net model file (model_best.net) }"
"{image i |./car.jpg | path to image file }"
"{result r | out_result.pb | path to save output blob (optional, binary format, NCHW order) }"
"{show s |true | whether to show all output channels or not}"
"{o_blob || output blob's name. If empty, last blob's name in net is used}";
要想直接运行,可以将参数的默认值添加进去。如代码所示,我们将model的名称,model-cityscapes.net添加进去了。将image 设置为car.jpg。我们指定了显示结果,show设置为true。
在下面的代码中,可以直接获取相关参数和变量的值。
int main(int argc, char **argv)
CommandLineParser parser(argc, argv, keys);
if (parser.has("help"))
{
parser.printMessage();
return 0;
}
String modelFile = parser.get<String>("model");
String imageFile = parser.get<String>("image");
if (!parser.check())
{
parser.printErrors();
return 0;
}
3. 实际运行与命令行输入技巧
有两种方式,可以运行代码。
3.1 直接Visual Studio运行
Ctrl+F5 release模型,或者F5,debug模式。
此时,直接将改变的参数,在 String keys里面设置好。就不用输入命令行。跟日常的写代码,调试一样。将配置的模型与参数,直接修改在CommandLineParser的默认值里面,这样方便调试。
3.2 命令行输入
当代码调试好,需要只用使用。此时,需要生成exe文件,然后将不同的image采用命令行的方式,输入给exe,运行并观察结果就行。
首先,需要生成代码的可执行文件,例如,SemanticSeg.exe。 这个文件在./x64/release/ 下面(如果你是release模型生成的exe)。
然后,在Windows的cmd命令行输入里面(Win+R快捷键打开。)
cd到exe文件夹下面。
SemanticSeg.exe -m=…/path/to/modelfile.net -i=…/path/to/image.jpg -s=true
回车,就可以将数据输入到exe里面,并执行。
记住,每个参数,在命令行里面,用等于=赋值。例如:-m=model-cityscapes.net , --image=car.jpg。而不是,python里面的, -m ./path/to/model.net,中间用空格来输入。
例如:下图就是实际案例。使用生成的OpenCVTest.exe,指定了model -m,指定了处理图像 -i。