gpt4 book ai didi

c++ - OpenCV CommandLineParser 未指定的参数

转载 作者:太空宇宙 更新时间:2023-11-03 22:54:37 26 4
gpt4 key购买 nike

当使用 cv::CommandLineParser 时,是否可以解析任意长的非标志参数列表?
例如:

> app -a -b=2 a.txt b.txt c.txt ... 

我想访问所有 非标记“位置”args,而不必在keys 规范中定义它们的预定义数量。此号码仅由应用程序的调用者确定。

最佳答案

OpenCV CommandLineParser 无法处理可变数量的位置 参数。您可以:

  1. 传递一个额外的参数(例如-N)指定位置参数的数量;
  2. 将所有不以 - 开头的参数视为位置参数。

然后您可以使用与 cv::CommandLineParser 相同的接口(interface)制作自定义命令行解析器,能够处理可变数量的位置参数。

选项 1

struct CustomCLP
{
CustomCLP(int argc, const char* const argv[], const cv::String& keys, const String& positional_id)
{
String pos_key = "{" + positional_id + "|0|}";
cv::CommandLineParser pos_clp(argc, argv, pos_key);
_N = pos_clp.get<int>(positional_id);

cv::String pos_keys = keys;
for (int i=0; i<_N; ++i)
{
pos_keys += "{@pos" + to_string(i) + "||}";
}

_clp = new CommandLineParser(argc, argv, pos_keys);
}

~CustomCLP()
{
delete _clp;
}

bool check() const {return _clp->check();}
bool has(const cv::String& name) const {return _clp->has(name);}

template<typename T>
T get(const String& name, bool space_delete = true) const
{
return _clp->get<T>(name, space_delete);
}
template<typename T>
T get(int index, bool space_delete = true) const
{
return _clp->get<T>(index, space_delete);
}

int n_positional_args() const { return _N;}

private:
CommandLineParser* _clp;
int _N;
};

您可以指定额外的参数(例如 -N)来指定位置参数的数量。在构造函数中,您解析这个数字,并为每个位置参数创建一个key。然后您就可以像往常一样使用它了。

选项 2

// SO: http://stackoverflow.com/a/17976541/5008845
inline std::string trim(const std::string &s)
{
auto wsfront = std::find_if_not(s.begin(), s.end(), std::isspace);
return std::string(wsfront, std::find_if_not(s.rbegin(), std::string::const_reverse_iterator(wsfront), std::isspace).base());
}

struct CustomCLP2
{
CommandLineParser _clp;
vector<std::string> pos_args;

public:
CustomCLP2(int argc, const char* const argv[], const cv::String& keys) :
_clp(argc, argv, keys)
{
for (int i = 1; i < argc; ++i)
{
std::string s(argv[i]);
s = trim(s);
if (s[0] == '-') continue;

pos_args.push_back(s);
}
}

bool check() const { return _clp.check(); }
bool has(const cv::String& name) const { return _clp.has(name); }

template<typename T>
T get(const String& name, bool space_delete = true) const
{
return _clp.get<T>(name, space_delete);
}

template<typename T>
T get(int index, bool space_delete = true) const
{
stringstream ss;
ss << pos_args[index];
T t;
ss >> t;
return t;
}

template<>
cv::String get(int index, bool space_delete) const
{
return cv::String(pos_args[index]);
}

int n_positional_args() const { return pos_args.size(); }
};

在构造函数中,您保存所有不以 - 开头的参数。然后您可以像往常一样检索它。

用法

注意接口(interface)与CommandLineParser保持一致(aboutgetPathToApplication等几个方法在本例中不可用,但很容易添加到自定义类中).

命令行参数是:

Option 1: -a -b=2 -N=3 a.txt b.txt c.txt
Option 2: -a -b=2 a.txt b.txt c.txt

代码:

#include <opencv2\opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;


struct CustomCLP
{
CustomCLP(int argc, const char* const argv[], const cv::String& keys, const String& positional_id)
{
String pos_key = "{" + positional_id + "|0|}";
cv::CommandLineParser pos_clp(argc, argv, pos_key);
_N = pos_clp.get<int>(positional_id);

cv::String pos_keys = keys;
for (int i=0; i<_N; ++i)
{
pos_keys += "{@pos" + to_string(i) + "||}";
}

_clp = new CommandLineParser(argc, argv, pos_keys);
}

~CustomCLP()
{
delete _clp;
}

bool check() const {return _clp->check();}
bool has(const cv::String& name) const {return _clp->has(name);}

template<typename T>
T get(const String& name, bool space_delete = true) const
{
return _clp->get<T>(name, space_delete);
}
template<typename T>
T get(int index, bool space_delete = true) const
{
return _clp->get<T>(index, space_delete);
}

int n_positional_args() const { return _N;}

private:
CommandLineParser* _clp;
int _N;
};

// SO: http://stackoverflow.com/a/17976541/5008845
inline std::string trim(const std::string &s)
{
auto wsfront = std::find_if_not(s.begin(), s.end(), std::isspace);
return std::string(wsfront, std::find_if_not(s.rbegin(), std::string::const_reverse_iterator(wsfront), std::isspace).base());
}

struct CustomCLP2
{
CommandLineParser _clp;
vector<std::string> pos_args;

public:
CustomCLP2(int argc, const char* const argv[], const cv::String& keys) :
_clp(argc, argv, keys)
{
for (int i = 1; i < argc; ++i)
{
std::string s(argv[i]);
s = trim(s);
if (s[0] == '-') continue;

pos_args.push_back(s);
}
}

bool check() const { return _clp.check(); }
bool has(const cv::String& name) const { return _clp.has(name); }

template<typename T>
T get(const String& name, bool space_delete = true) const
{
return _clp.get<T>(name, space_delete);
}

template<typename T>
T get(int index, bool space_delete = true) const
{
stringstream ss;
ss << pos_args[index];
T t;
ss >> t;
return t;
}

template<>
cv::String get(int index, bool space_delete) const
{
return cv::String(pos_args[index]);
}

int n_positional_args() const { return pos_args.size(); }
};


int main(int argc, char* argv[])
{
String keys =
"{a | | whatever a}"
"{b | 1 | whatever b}";

//CustomCLP clp(argc, argv, keys, "N");
CustomCLP2 clp(argc, argv, keys);

if (clp.has("a")) {
cout << "Has <a>" << endl;
}
else {
cout << "Doesn't have <a>";
}

int b = clp.get<int>("b");
cout << "<b> : " << b << endl;

int N = clp.n_positional_args();

for (int i = 0; i < N; ++i)
{
cout << to_string(i) << ": " << clp.get<cv::String>(i) << endl;
}

return 0;
}

关于c++ - OpenCV CommandLineParser 未指定的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33128801/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com