본문 바로가기

Computer Vision by OpenCV

CommandLineParser: 명령행 인수의 처리, Command line arguments

반응형






ㅇ 명령행 인수 (Command line argument)


  - 예를 들어, 어떤 프로그램이 실행될 때 사용자가 파일 이름을 주면
  - 그 파일을 열어 작업한다고 가정하자. 
  - 이름을 넘겨주는 가장 쉬운 방법은 파일 이름을 소스코드에 하드코딩하는 것인데,
  - 단점은 이름을 바꿀 때 마다 프로그램 빌드를 다시 해야 하기 때문에 불편하다. 
  - 더 쉬운 방법은 실행할 때마다 '인수 (argument)'로 주는 것이다.
  - 예를 들어 'text.exe'라는 프로그램이 있다고 하고, 실행할 때, 아래와 같이 입력하여 인수를 넘겨줄 수 있다. 

>> test.exe image1 image2 -help -N=10.0

  - 위 명령어 라인을 하나하나 분석해 보면,
  - 실행파일 이름은 test.exe이고,
  - 여기에 인수로 image1, image2, -help, -N=10.0 등을 넘겨준다는 뜻이다.
  - 이렇게 실행명령과 함께 주어지는 인수들을 '명령행 인수 (command line argument)'라고 한다.
  - 그러면 프로그램은 이들 인수들을 인식해서,
  - 첫 번째와 두 번째 인수는 각각 image1과 image2이고,
  - -help라는 인수가 주어졌으며,
  - -N 인수로 지정되는 값은 10.0이라는 것을 알아햐 한다. 
  - 이러한 인식을 프로그래밍하는 것은 어렵지는 않지만 문자열 처리를 해야해서 귀찮기만 한다.
  - 하지만, 희소식이 있다.

ㅇ OpenCV에서는 이러한 처리를 위해 CommandLineParser 클래스를 제공하는데,

  - 사용하는 법은, 이 클래스에 미리 어떠한 인수들이 들어올 수 있는지를 알려주면
  - 실제로 입력된 인수들 중에 해당하는 것들을 추출해 준다.
  - 우선, 가능한 인수들이 어떤 것들인지 지정하는 방식에 대해서는 아래 설명을 보자

ㅇ 인수처리를 지정하는 방법

  - 아래 설명하는 포맷에 따라 지정하는데, 다소 복잡하니, 
  - 우선 예부터 살펴보자.
"{@imageName1| fruits.jpg|input image file} \\
{@imageName2| fruits.jpg|input image file} \\
{N count |1.0|this is double value} \\
{help h ?||this is help}"
  - @imageName1과 @imageName2는 첫 번째와 두 번째 입력되는 인수와 매칭되며,
  - 만약 입력이 안되면 fruits.jpg의 값을 default로 갖는다.
  - 그리고 'input image file'은 이 인수에 대한 설명으로 help 메시지에 의해 출력된다.
  - 인수 N과 count는 서로 같은 것이고, 
  - 명령행에서 입력될 때는 앞에 dash ('-')를 반드시 붙여서, -N=1.0 혹은 -count=1.0과 같이 입력해야 한다.
  - 특히, 여기서는 -N (혹은 -count)가 입력되지 않아도 -N=1.0이 입력된 것으로 처리된다.
  - 인수 help, h, ?는 help message 출력과 관계가 있고, 
  - 명령행에서  -help, -h, -?는 모두 동일하며, 
  - 이 인수의 경우 default value가 없으나, 
  - 이 인수가 입력되면  자동으로 생성되는 인수별 설명을 출력하는 함수 printMessage()를 출력하는 것이 일반적이다.
  - 이러한 help인수가 입력되었는지를 알기 위해서는 함수 has()를 이용하여
  - 예를 들어, has("help"), has("h"), has("?") 의 반환값이 true인지를 확인하면 된다.

ㅇ 인수처리 지정방법 

  - 이제 포맷을 살펴보면서 전체적으로 이해해 보자
  - 지정내용은 큰 따옴표 (")로 둘러쳐진 문자열로 표현되는데,
  - 각 인수들은 중괄호 ({  })로 구분된다.
  - 그리고 중괄호 내부는 vertical bar(|)에 의해 3부분으로 구분되는데,
  - 첫 번째 부분은 '인수 이름', 두 번째 부분은 'default value',  세 번째 부분은 설명이다.
  - default value라는 것은 인수를 입력하지 않았을 경우에 그 인수의 값이 된다.
  - 설명이라는 것은, 그 인수에 대한 설명으로 이것은 help 메시지에 의해 자동 출력된다.
  - 인수이름 중에서 @으로 시작하는 것은 인수 위치와 관련된 것으로
  - 가장 앞에 있는 인수는 첫 번째 나타나느 @이름의 인수가 되는 것이다.
  - 인수이름에 여러 개의 이름을 공백으로 구분하여 입력할 수 있는데, 이들은 모두 동일한 인수를 가리킨다. 
  - 그리고 @이름이 아닌 인수이름은 명령행에서 입력할 때 -이름으로 입력된다.
  - 인수지정의 한 예는 아래 그림과 같다.

ㅇ CommandLineParser 클래스의 메소드들

  - 지정된 인수내용에 따라 보다 쉽게 인수들을 구분해 낼 수 있고,
  - 보기 편한 help message를 자동생성하기 위해서,
  - 이 클래스는 다음과 같은 메소드들을 제공한다.
  - help message는 인수사용방법을 설명하는 출력문을 말한다.
  - 이에 대해서는 앞에서 간략히 설명했었고, 뒤의 예에서는 실제 help message가 어떻게 나오는지 볼 수 있다.
  - 우선 help message 생성에 관한 메소드들부터 살펴보면,

ㅇ 메소드 about(string msg) of CommandLineParser

  - 이 메소드를 이용하면, 
  - help 메시지를 출력할 때 보이는 초반부의 설명 메시지를 설정할 수 있으며,
  - 이것은 아래 실행 예에 나와 있다.

ㅇ 메소드 printMessage() of CommandLineParser

  - 각 인수에 대한 설명을 자동으로 생성하여 출력하는 메소드로,
  - 각 인수별로 지정한 설명들과 default value가 설명에 포함된다. 

ㅇ 메소드 get<type>() of CommandLineParser 

  - 입력된 인수 중에서 특정 인수값을 추출할 때 사용되며
  - 예를 들어, get<double>("N")은
  - -N=100.0 이라면,  인수 N에 의해 설정된 인수 100.0을 반환한다.
  - '<double>'은 추출된 값의 data type을 말한다.
  - 요약하자면, 이 메소드는 명령행에 입력된 문자열에서 인수들의 값을 추출하는 역할을 하게 된다.

ㅇ 예제 프로그램

   - 명령행에서 다음과 같은 인수들을 입력했다고 가정하자

- 1) 첫 번째 인수이고 값은 test.jpg
- 2) 두 번째 인수이고, 값은 test2.jpg
- 3) 세 번째 인수는 --help 로 이는 -help와 같다.

  
  - 이러한 인수를 처리하는 프로그램은 아래와 같다.
    . line 12- 15: 처리하는 인수에 대한 지정 문자열
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int init_brightness = 100;
int init_contrast = 100;

Mat image;

const char* keys = { "{@imageName1| fruits.jpg|input image file} \\
{@imageName2| fruits.jpg|input image file} \\
{N | 1.0 | this is double value} \\
{help h ? | | this is help}" };


int main(int argc, char** argv)
{
	CommandLineParser parser(argc, argv, String(keys));
	parser.about("This is test program for commandlineparser of opencv by kyungkoo jun");
	string inputImage1 = parser.get<string>("@imageName1");
	string inputImage2 = parser.get<string>("@imageName2");

	cout << "argument1 is : " << inputImage1 << endl;
	cout << "argument2 is : " << inputImage2 << endl;
	cout << "argument N is : " << parser.get<double>("N") << endl;

	if (parser.has("help") == true)
	{
		cout << "have help" << endl;
		parser.printMessage();
	}
	else
	{
		cout << "no help" << endl;
	}
	return 0;
}

ㅇ 위 프로그램의 실행결과
- 1) line 22, 23에서 추출한 두 개의 인수를 출력
- 2) 인수 N은 입력되지 않았지만, default value로 1이 지정
- 3) --help가 입력되었고 (line 29)
- 4) 자동생성되는 help 메시지는 각 인수별 설명을 자동으로 만들어 낸다.
특히, 메시지의 초반부에는 line 21에서 메소드 about()로 설정한 문자열이 출력된다.







반응형