Skip to content

OpenCV command line parser

Tomoaki Teshima edited this page Nov 14, 2017 · 3 revisions

abstract

Let's decide the program parameter at the run-time and don't hard-code the values

Now, there are several ways to set different behaviour for a single program

  1. Hard code the value and modify the source code and then build again.
  2. Specify some parameter from highgui window, i.e. keyboard input and mouse click
  3. Pass command line parameter such as --help or --type=edge and so on

Now option #1 is not changing the behaviour, so I won't discuss about this here. The option #2 is much useful for choosing the point, and making interaction, and so-on. On the other hand, mouse clicking isn't really suitable for telling program to "change the edge detection algorithm" or "detect face based on frame difference" and so-on. Changing the behaviour is

Passing option is quite common way to change the behaviour of the program.

Now, from the program side, you'll get the list of strings, which you have to parse them in the prgoram

cv::CommandLineParser

There is a cv::CommandLineParser in OpenCV, which helps you to parse the strings to parameters. There are already many articles which describes about this class, but once again, I'd like to write it down here.

defining

Let's see how it works. There are plenty of examples in the sample code in OpenCV. Here's the part from samples\cpp\letter_recog.cpp

    cv::CommandLineParser parser(argc, argv, "{data|../data/letter-recognition.data|}{save||}{load||}{boost||}"
            "{mlp||}{knn knearest||}{nbayes||}{svm||}");
    data_filename = parser.get<string>("data");
    if (parser.has("save"))
        filename_to_save = parser.get<string>("save");
    if (parser.has("load"))
        filename_to_load = parser.get<string>("load");
    if (parser.has("boost"))
        method = 1;
    else if (parser.has("mlp"))
        method = 2;
    else if (parser.has("knearest"))
        method = 3;
    else if (parser.has("nbayes"))
        method = 4;
    else if (parser.has("svm"))
        method = 5;

I think it's quite clean and neat enough for a simple parser, at least to prevent the "re-invention of the wheel" How to use, you need to define the parameters that the program will accept That's defined in the following lines

    cv::CommandLineParser parser(argc, argv, "{data|../data/letter-recognition.data|}{save||}{load||}{boost||}"
            "{mlp||}{knn knearest||}{nbayes||}{svm||}");

Each parameters are separated by {} in the text of the last option. So the following text

"{data|../data/letter-recognition.data|}{save||}{load||}{boost||}{mlp||}{knn knearest||}{nbayes||}{svm||}"

Tells that this program accepts data, save,load,boost, mlp, knn, nbayes and svm. Also, knn knearset stands that bothknn and knearest stands for same option. This kind of alias is usefull for -h and --help to act same way.

Each parameters has to have a name. Thus, headlike options, i.e. head -20 main.cpp which shows the first 20 lines from main.cpp, isn't acceptable. Second, you can specify default value for each parameter. In the following example, data option has default value ../data/letter-recognition.data And the last part defines the explanation of the parameter. It's supposed to be outputted when help is requested.

Of course, don't forget to pass the argv and argc to the CommandLineParser

retrieving

Now the program accepts command line option. Let's read it from the program. To read the parameter, you need to specify the name and the type of the parameter.

data_filename = parser.get<string>("data");

This shows how to get the data option from the command line You specify "data" and the type as string. For another example, you can retrieve your threshold as following

threshold = parser.get<double>("threshold");

or if you wish the type to be int,

threshold = parser.get<int>("threshold");

this will work.

passing

Now from the command line, you need to specify the option in either of following

  • -h
  • --help
  • --threshold=20

For some linux-like command, option specify such as ls -ltr which is equal to ls -l -t -r is acceptable. Unofrtunately, this type of option is not accepted in OpenCV. If you specify -ltr for the option, it will be parsed as "ltr" and not separated. Also, if a value is passed to option, it has to be express using =. For instance, -n=20 will pass 20 to option "n" but -20 option will not work.

Clone this wiki locally