OpenCV Haar/cascade training 튜토리얼

영상처리 2013. 5. 31. 13:51

OpenCV의 Haar classifier, Cascade classifier를 학습시키기 위한 샘플 데이터 생성법 및 training 방법에 대한 상세 메뉴얼입니다.


Haar training이나 cascade training에 대한 내용은 OpenCV 웹 매뉴얼이나 Naotoshi Seo의 튜토리얼 사이트 등도 있지만 일부 설명이 모호한 부분도 있고 또한 영어로 되어 있기 때문에 우리말로 된 좀더 명확한 사용법을 정리해 보았습니다.


제가 직접 해보니 사용법이 명확하지 않은 부분이 많아서 제대로 다 파악하기 위해서는 시간이 꽤 많이 필요한것 같습니다. 이 글의 내용을 참조하면 이러한 시간을 많이 단축시킬 수 있을 것이라 생각합니다.


0. 내용 목차


1. 관련 리소스

2. OpenCV Haar Training & Cascade Training에 대한 전반적인 내용

3. training 데이터 생성과 관련하여 기본적으로 알고 있어야 할 것

4. opencv_createsamples.exe은 어디에?

5. opencv_createsamples.exe 사용법

6. 멀티 샘플들로부터 확장된 training 데이터 생성하기

7. OpenCV Haar Training 방법

8. OpenCV Cascade Training 방법

9. 학습된 검출기를 이용해서 실제 물체 검출하기

10. Training 과정에서 발생할 수 있는 에러와 해결법

11. Training/샘플링 프로그램



1. 관련 리소스


이 글과 더불어 같이 참조하면 좋은 자료들:

  • OpenCV 웹 매뉴얼: Cascade Classifier Training
  • 대표적인 Haartraining 튜토리얼 사이트: http://note.sonots.com/SciSoftware/haartraining.html
  • Haar & Cascade 논문: [Viola2001] P. Viola and M. J. Jones, "Rapid Object Detection using a Boosted Cascade of Simple Features", CVPR 2001
  • HOG 논문: [Dalal2005] N. Dalal and B. Triggs, "Histograms of oriented gradients for human detection," CVPR 2005.
  • LBP 논문: [Liao2007] S. Liao, X. Zhu, Z. Lei, L. Zhang and S. Z. Li, "Learning Multi-scale Block Local Binary Patterns for Face Recognition," International Conference on Biometrics (ICB), 2007, pp. 828-837.



2. OpenCV Haar Training & Cascade Training에 대한 전반적인 내용


Haar classifier 또는 Cascade classifier는 영상에서 특정 형태의 물체를 찾고자 할 때 사용할 수 있는 대표적인 방법중 하나입니다. 이 방법에 대한 간단한 설명은 영상 보행자 검출 기술(Pedestrian Detection)의 글 내용중 [Viola2001] 논문 설명 부분을 참조하시기 바랍니다.


OpenCV에는 opencv_haartraining.exe를 이용해서 [Viola2001] 논문에 있는 Haar Classifier를 학습시킬 수 있는 방법을 제공합니다.


그런데 이와는 별도로, 기존 Haar Classifier의 cascade 학습 구조는 그대로 유지하되 영상 feature를 추출하는 부분을 독립시켜서 다양한 영상 feature에 대해서 cascade 학습이 가능한 구조로서 Cascade Training 방법을 제공하고 있습니다. OpenCV에서 새로 제공되는 Cascade Training에서는 기존의 Haar feature 뿐만 아니라 LBP feature와 HOG feature를 모두 지원합니다.


따라서, Cascade Training 방법을 사용하면 파라미터 설정만으로, Haar, LBP, HOG를 마음대로 선택해서 학습시킬 수 있기 때문에 굳이 기존의 Haar Training 방법을 사용할 필요는 없어 보입니다. 하지만, training 데이터는 공통으로 사용되기 때문에 학습 방법에 관계없이 opencv_createsamples.exe를 사용해 생성해야 합니다.


또한, OpenCV 웹 페이지 설명에 보면 LBP feature를 사용하는 것이 학습에 걸리는 시간, 검출 수행 시간 모두 Haar feature보다 훨씬 빠르면서 성능은 거의 비슷하기 때문에 Haar feature보다는 LBP feature를 사용하는 것이 좋다고 합니다.


HOG feature와 LBP feature의 비교는 응용에 따라 다를 것으로 생각됩니다. 일단은 HOG는 Haar나 LBP에 비해 속도가 느립니다. 그리고 성능적인 면에서는 HOG는 edge 정보를 이용하고, Haar, LBP는 영역과 영역의 밝기차를 이용하기 때문에 검출하고자 하는 대상의 특성에 따라 성능이 달라질 것으로 생각됩니다.



3. training 데이터 생성과 관련하여 기본적으로 알고 있어야 할 것


Haar/Cascade classifier를 학습시키기 위해서는 positive 샘플과 negative 샘플이 모두 필요합니다. positive 샘플이란 검출하고 하는 대상 물체에 대한 샘플 영상들이며, negative 샘플은 대상 물체가 포함되지 않은 일반 이미지들입니다. classifier 학습(training) 과정은 다양한 수많은 영상 feature들 중에서 positive 샘플과 negative 샘플들을 가장 잘 구분시킬 수 있는 영상 feature들을 찾고 이 feature들을 잘 조합하여 강력한 검출기를 얻는 과정을 말합니다.



4. opencv_createsamples.exe은 어디에?


OpenCV의 Haar training 또는 Cascade training에 필요한 training 데이터를 생성하기 위한 공통 유털러티입니다. OpenCV를 설치한 후, opencv/apps/haartraining/ 에 보면 관련 소스코드들이 존재합니다.


하지만, 기본적으로는 이 유틸러티의 소스코드만 존재할 뿐 실제 실행파일은 존재하지 않기 때문에 cmake를 이용해서 자신이 새로 opencv를 빌드(build)해야 합니다. 이 때, cmake의 옵션들 중에서 BUILD_opencv_apps를 체크해주고 빌드하면 유틸러티가 생성됩니다. 또는 자신이 직접 c++ 프로젝트를 만들어서 관련 소스들을 컴파일해도 됩니다.


opencv_haartraining.exe, opencv_traincascade.exe, opencv_performance.exe 파일들도 모두 마찬가지입니다.



5. opencv_createsamples.exe 사용법


Naotashi Seo 튜토리얼 사이트에도 나와 있지만 이 유틸러티의 사용법은 총 4가지입니다. 파라미터를 어떻게 주느냐에 따라서 전혀 다른 일을 수행합니다. 이러한 내용이 OpenCV 메뉴얼에는 나와 있지 않다는 점이 저 또한 유감입니다. 참고로, opencv/apps/haartraining/createsamples.cpp 파일을 보면 파라미터에 따라 어떻게 사용법이 달라지는지 대략적이나마 파악할 수 있습니다.


이 유틸러티의 파라미터 목록 및 각각의 파라미터에 대한 간략 설명은 다음과 같습니다.


Usage: opencv_createsamples

  [-info <description_file_name>] -> positive 샘플 이미지 목록 및 물체영역 정보를 저장한 파일

  [-img <image_file_name>] -> 단일 positive 샘플 이미지 (물체 영역만 crop한 이미지)

  [-vec <vec_file_name>] -> 생성된 training 데이터를 저장할 파일명 (확장자: vec)

  [-bg <background_file_name>] -> negative 샘플 이미지 목록 파일

  [-num <number_of_samples = 1000>] -> 생성할 training 데이터 개수

  [-bgcolor <background_color = 0>] -> positive 샘플에서 투명색(배경색)으로 처리할 기준 픽셀값

  [-bgthresh <background_color_threshold = 80>] -> [bgcolor-bgthresh, bgcolor+bgthresh] 범위의 색을 투명색(배경색)으로 처리

  [-inv] [-randinv] -> positive 샘플을 일괄적으로 반전 또는 랜덤하게 반전

  [-maxidev <max_intensity_deviation = 40>] -> positive 샘플의 밝기값 변형 범위

  [-maxxangle <max_x_rotation_angle = 1.100000>] -> roll 회전변형 범위

  [-maxyangle <max_y_rotation_angle = 1.100000>] -> yaw 회전변형 범위

  [-maxzangle <max_z_rotation_angle = 0.500000>] -> pitch 회전변형 범위

  [-show [<scale = 4.000000>]] -> 생성되는 training 데이터를 이미지로 보여줄지 여부

  [-w <sample_width = 24>] -> 생성할 training 데이터의 이미지 폭 (픽셀)

  [-h <sample_height = 24>] -> 생성할 training 데이터의 이미지 높이 (픽셀)


-info: info 파라미터에는 positive 샘플 이미지들의 경로명(path)과 이미지 내에서의 대상 물체의 경계사각형 위치정보 목록을 텍스트 파일로 저장하고 이 파일 이름을 파라미터로 입력. 파일내 데이터 포맷은 '이미지경로명 물체수 x y width height [x y width height]'임.

예) plist.txt

d:\positives\img1.jpg 1 140 100 45 45

d:\positives\img2.jpg 2 100 20 50 50 0 30 25 25

d:\positives\img3.jpg 1 0 0 20 20

...


-bg: negative 이미지 목록을 저장한 텍스트 파일 이름을 입력

예) nlist.txt

d:\negatives\img1.jpg

d:\negatives\img2.jpg

...


실행모드 종류


이 파라미터들을 어떻게 조합하느냐 따라서 다음과 같이 총 4가지의 모드로 동작합니다 (각 모드의 이름은 설명의 편의를 위해서 임의로 붙였습니다).

  • [모드1] 단일 확장 training 생성: 하나의 positive 샘플을 다양하게 변형시켜서 내부 training 데이터 포맷으로 저장
  • [모드2] 멀티 고정 training 생성: 입력된 positive 샘플들을 그대로 내부 training 데이터 포맷으로 변환만 해서 저장
  • [모드3] 테스트 이미지 생성: positive 샘플과 negative 이미지들을 결합하여 테스트 이미지들을 생성하고 jpg 파일로 저장
  • [모드4] training 데이터 출력: 내부 training 데이터 포맷으로 저장된 데이터들을 이미지로 보여줌


실행모드 결정 규칙


파라미터들 중 info, img, vec, bg의 명시 여부에 따라 모드가 달라집니다. img와 vec를 모두 명시할 경우에는 모드 1으로 동작하고, info와 vec을 명시하면 모드 2, info, img, bg를 명시하면 모드 3, vec만 명시하면 모드 4로 동작합니다.

createsamples -img p.jpg -vec tr.vec => mode 1

createsamples -info plist.txt -vec tr.vec => mode 2

createsamples -info plist.txt -img p.jpg -bg nlist.txt => mode 3

createsamples -vec tr.vec => mode 4


opencv_createsamples 유틸러티는 각 모드에 따라 사용되는 파라미터가 달라지고 또 동일한 파라미터라 할지라도 그 의미가 조금씩 달라집니다. 각 모드별로 사용되는 파라미터들을 표로 정리하면 다음과 같습니다.



[모드 1] 단일 확장 training 데이터 생성


-img로 입력받은 positive 샘플 이미지 하나를 랜덤하게 변형시켜서 -num 개수만큼의 positive training 데이터를 생성합니다. 생성된 training 데이터들은 -w, -h 크기를 가지며 -vec 파일명으로 저장됩니다.


-bg 파라미터는 선택사항인데, 만일 -bg를 입력하면 negative 이미지 목록에서 랜덤하게 배경영역을 추출한 후 그 위에 변형된 positive 샘플을 덮어 씌워서 training 데이터를 생성합니다. 이 때, positive 샘플에서 [bgcolor-bgthreshd, bgcolor+bgthresh] 범위에 있는 픽셀들은 투명색으로 간주되어 배경색으로 채워집니다. 만일 -bg를 입력하지 않으면 positive 샘플의 투명색 부분과 회전변형에 의한 빈 공간은 -bgcolor로 채워집니다.


입력된 샘플이 하나이기 때문에 이를 다양하게 변형시켜야 하는데, 밝기값 변형은 -maxidev 내에서, 회전 변형은 -maxxangle, -maxyangle, -maxzangle 내에서 랜덤하게 이루어집니다. 회전 변형의 단위는 라디안(radian)이며 기본값은 maxxangle = maxyangle = 1.1 (63도), maxzangle = 0.5 (28.6도) 입니다. 기본값이 크기 때문에, 차량 검출 등 회전 변형이 적은 응용에서는 이 파라미터들의 값을 낮춰져야 합니다.


-maxxangle: roll 회전 변형, 상하 방향으로 물체의 크기가 변화


-maxyangle: yaw 회전 변형, 좌우 방향으로 물체의 크기가 변화


-maxzangle: pitch 회전 변형, 이미지 평면에서의 회전 변화


테스트 삼아서, 이 모드를 사용해서 자신의 얼굴만 잘 검출할 수 있는 검출기를 한 번 구현해 보는 것도 좋을 것 같습니다.



[모드 2] 멀티 고정 training 데이터 생성


-info로 입력받은 positive 샘플 영역들을 그대로 크기만 -w, -h로 바꿔서(resize) -vec 파일로 저장합니다. 샘플수를 늘리기 위한 변형을 가하지 않기 때문에, 생성되는 training 데이터 개수는 max{-num, 실제 positive 샘플 개수} 입니다. 즉, -num을 positive 샘플수보다 작게 주면 -num 개수까지만 training 데이터를 생성하고, 더 크게 주면 실제 샘플수까지만 training 데이터가 생성됩니다.



모드 2 방법은 주어진 샘플들을 그대로 학습 데이터로 사용하기 때문에, 물체에 대한 가능한 다양한 변형을 모두 커버할 수 있을 정도로 충분한 수의 positive 샘플이 있는 경우에 사용해야 합니다.



[모드 3] 테스트 이미지 생성


-img로 입력받은 positive 샘플 이미지에 다양한 변형을 가한 후에, -bg로 입력받은 배경(negative) 이미지 위에 붙여서 테스트 이미지를 생성하고 jpg 파일로 저장합니다 (배경이미지는 목록중에서 랜덤하게 선택되며 -num 개수만큼의 테스트용 jpg 이미지 파일들이 생성됨).



주의할 점은 -info 파라미터를 어떻게 주느냐에 따라서 이 모드의 동작 방식이 약간 달라집니다. 만일 -info에 파일명을 주면 (예. -info testlist.txt), 파일명에 해당하는 텍스트 파일이 새로 생성되고 (주의. 실행 폴더에 동일 이름의 파일이 있었다면 데이터가 날라감) 테스트 이미지 파일몇 및 테스트 이미지 내의 물체 위치가 기록됩니다. 그리고 jpg 파일들은 현재 실행 폴더에 저장됩니다. 그런데, 만일 -info에 경로명을 주면 (예. -info testimages\), 해당 폴더가 생성되고 생성된 폴더 밑에 jpg 파일들이 저장됩니다. 이 경우 이미지 위치정보를 기록한 목록 파일은 생성되지 않습니다. 파일명인지 경로명인지를 구분하는 기준은 이름 끝에 '\' 또는 '/'가 붙었는지 여부입니다.


이 모드를 사용해서 테스트 이미지들을 생성하면 영상 내 물체 위치를 알 수 있다는 장점은 있지만 인위적인 영상이기 때문에 가급적이면 실제 테스트 영상을 이용하는게 좋을 것 같습니다.



[모드 4] training 데이터 보여주기


-vec 파일로 저장되어 있는 training 데이터를 불러와서 하나씩 이미지로 보여줍니다. -w, -h에는 vec 파일에 있는 training 데이터의 저장된 이미지 크기를 입력하고, -scale에는 이미지를 얼마나 확대해서 보여줄 지를 입력합니다.



6. 멀티 샘플들로부터 확장된 training 데이터 생성하기


OpenCV에는 아쉽게도 여러 positive 샘플들을 확장해서 training 데이터를 생성시켜주는 함수는 제공하지 않습니다. 모드 1의 방법으로 각각의 샘플들에 대해 확장된 training 데이터들을 생성한 후에 생성된 vec 파일들을 하나로 합치거나, 아니면 자신이 직접 이러한 기능을 수행하는 함수를 구현해야 합니다.


참고로 Naotashi Seo 튜토리얼 사이트에 보면 vec 파일들을 하나로 합쳐주는 코드(mergevec.cpp)와 모드 1을 positive 이미지 목록에 대해 반복 수행해주는 perl 스크립트(createtrainsamples.pl)가 제공됩니다.


☞ 이러한 기능을 제공하는 프로그램을 직접 구현해 보았습니다. [개발한 것들] - Haar/Cascade Training 프로그램 내용을 참조하기 바랍니다.




7. OpenCV Haar Training 방법


opencv_haartraining.exe 유틸러티를 사용해서 haar classifier를 훈련시키는 방법에 대한 설명입니다. 참고로, 앞서 2절에서 설명했듯이 이 방법 말고 cascade training을 이용해서도 haar classifier를 학습시킬 수 있습니다.


이 유틸러티의 파라미터 목록 및 기본값, 각각의 파라미터에 대한 간략 설명은 다음과 같습니다.

Usage: opencv_haartraining

  -data <dir_name>

  -vec <vec_file_name>

  -bg <background_file_name>

  [-bg-vecfile]

  [-npos <number_of_positive_samples = 2000>]

  [-nneg <number_of_negative_samples = 2000>]

  [-nstages <number_of_stages = 14>]

  [-nsplits <number_of_splits = 1>]

  [-mem <memory_in_MB = 200>]

  [-sym (default)] [-nonsym]

  [-minhitrate <min_hit_rate = 0.995>]

  [-maxfalsealarm <max_false_alarm_rate = 0.5>]

  [-weighttrimming <weight_trimming = 0.95>]

  [-eqw]

  [-mode <BASIC (default) | CORE | ALL>]

  [-w <sample_width = 24>]

  [-h <sample_height = 24>]

  [-bt <DAB | RAB | LB | GAB (default)>]

  [-err <misclass (default) | gini | entropy>]

  [-maxtreesplits <max_number_of_splits_in_tree_cascade = 0>]

  [-minpos <min_number_of_positive_samples_per_cluster = 500>]


사용예.

opencv_haartraining -data result -vec tr.vec -bg nlist.txt -npos 400 -nneg 5000


-data: 이 파라미터는 2가지 역할을 수행함. 하나는 각 cascade 단계(stage)별 classifier가 저장될 디렉토리명이고 다른 하나는 최종 검출기가 저장될 파일 이름임. 예를 들어, '-data result'로 입력하면 현재 실행폴더 밑에 result라는 폴더가 생성되고 result 밑에 cascade classifier들이 저장됨. 또한 현재 실행폴더에 result.xml이라는 이름으로 학습된 최종 검출기가 저장됨.


-vec: positive training 데이터 파일명. 앞서 opencv_createsamples.exe로 생성한 positive 데이터(확장자: vec) 파일을 입력


-bg: negative 이미지 목록이 저장된 파일명을 입력 (앞의 5절 설명 내용 참조). 또는 -bg 파라미터로 .vec 파일을 입력으로 줄 수도 있음(단, negative 이미지들로부터 생성한 vec 파일이어야 함). 만일 -bg에 .vec 파일을 입력할 경우에는 -bg-vecfile 파라미터를 명시해 주어야 함.


-nstages: 학습할 cascade 단계의 수. Cascade 검출기는 일련의 기본 검출기들로 구성되는데, Cascade 검출 방식은 먼저 1단계 classifier로 false들을 걸러내고, 나머지에 대해서는 2단계 classifier로 false들을 걸러내고, ... 이런식으로 해서 최종 단계까지 살아남으면 물체 검출에 성공한 것으로 간주함. -nstages는 이 단계수 즉, 기본 검출기들의 개수를 조절하는 것임. 학습된 각 단계별 기본 검출기들은 result\ 밑에 0, 1, 2, ... 밑에 텍스트 파일 형태로 저장됨.


-npos: 각 cascade 학습 단계(stage)에 사용되는 positive 샘플 개수를 설정. 주의할 점은 .vec 파일에 있는 실제 샘플수를 입력하면 안됨.  npos <= (vec파일에 있는 샘플수 - 100)/(1+(nstages-1)*(1-minhitrate))) 정도로 값을 주기 바람. 자세한 내용은 아래 10절 'training 에러 및 해결법'을 참조하기 바람.


-nneg: 각 cascade 학습 단계(stage)에 사용될 negative 샘플 개수를 설정. -bg로 입력한 negative 이미지들 중에서 랜덤한 위치와 크기로 다양한 위치 및 크기로 negative 샘플들을 뽑기 때문에 실제 negative 이미지 개수와 관계없이 원하는 값을 주면 됨.

=> 사실은 랜덤하게 샘플을 뽑는 것은 아니고 negative 이미지들을 차례대로 스캔(scan)하면서 샘플을 뽑습니다. 그 방식은 고정된 크기의 윈도우를 영상 내에서 일정 간격으로 이동시키면서 샘플을 뽑고 이미지 끝에 도달하면 윈도우의 크기를 변경한후 다시 이미지의 처음 위치부터 스캔, ..., 한 이미지에 대해 가능한 모든 윈도우 크기에 대해 스캔이 끝나면 다음 negative 이미지로 넘어가는 방식으로 샘플을 추출함. 여기서 중요한 점은 negative 이미지에 있는 후보 패치 영역들이 그대로 negative 샘플이 되는 것이 아니라 물체가 아닌데도 물체인 것으로 잘못 검출되는 영역들만 negative 학습 샘플로 활용됩니다. 즉, 이전 단계(stage)까지 학습된 classifier로 negative 이미지 영역들을 쭉 스캔하면서 오검출이 발생하면 해당 영역을 negative 학습 샘플에 추가하고, 이런 식으로 총 nneg 개의 negative 샘플이 확보될 때까지 스캔을 계속합니다. 따라서, 만일 이전 단계까지 학습된 classifier가 오검출율이 매우 낮다면 현재 단계의 negative 학습 샘플을 준비하는데 많은 시간이 소요되게 됩니다.


-minhitrate: 각 cascade 단계의 기본 classifier들에게 요구되는 최소 검출율. 최종 검출기의 검출율은 minhitrate^nstages가 됨. 예를 들어, 기본값을 그대로 사용하면 최소 0.995^14 = 0.932 정도의 검출율을 가지는 detector를 얻을 수 있게 됨. 하지만 이것은 어디까지나 .vec 파일로 입력한 training 데이터에 대한 검출율이기 때문에 실제 일반적인 입력에 대한 검출율은 훨씬 떨어질 수 있음.


-maxfalsealarm: 각 cascade 단계의 기본 classifier들에게 요구되는 오검출율의 상한. 최종 검출기에 대해 예상되는 오검출율은 maxfalsealarm^nstages 임. 기본값을 그대로 사용할 경우, 0.5^14 = 0.0000610 정도의 값이 나옴. 일견 매우 작아보이지만, 입력 영상의 모든 가능한 윈도우 영역에 대해서 이 정도 비율로 오검출이 나온다고 생각해 보면 그렇게 작은 값이 아닐 수 있음. 어쨌든, 각 단계에서 오검출율을 0.5로 한다는 의미는, 입력 후보들 중 50% 이상을 걸러 낼 수 있는 classifier를 찾겠다는 말임. 이러한 단계별 classifier들이 cascade 형태로 연결되면 최종적으로는 대부분의 배경을 걸러낼 수 있는 검출기를 얻게 됨.


☞ minhitrate, maxfalsealarm 파라미터에 대한 보다 상세한 의미에 대해서는 아래 댓글들에 대한 답변 내용을 참고하시면 도움이 되리라 생각됩니다(뚱캔 2013.8.20, neverabandon 2013.12.11).


-mode: BASIC=0, CORE=1, ALL=3의 3가지 값을 가질 수 있으며 기본값은 BASIC임. BASIC은 원래 [Viola2001] 논문에서 사용된 haar feature들로서 아래 그림에서 1a, 1b, 2a, 2c에 해당함. CORE를 선택하면 아래 그림중 1a, 1b, 2a, 2b, 2c, 2d, 3a를 사용하고, ALL을 선택하면 아래의 모든 feature들을 모두 사용해서 training을 수행함. 응용에 따라서, 찾고자 하는 대상 물체의 특성에 따라서 적절히 -mode를 선택해 주면 됨.


-w, -h: .vec 파일에 있는 샘플 데이터의 크기. 샘플 데이터들은 이미지 패치(patch)들인데 이 이미지 폭(w)과 높이(h)를 말함.


-nsplits: 각 단계의 weak classifier로 어떤 binary decision tree를 사용할 것인지를 선택하는 파라미터. -nsplits 1이면 1개의 분기만을 가진 depth 1의 가장 기본적인 이진 stump tree가 사용됨. 2 이상의 값을 주면 해당되는 분기점을 가진 CART(Classification And Regression Tree) classifier가 사용됨.


-mem: training 과정에 사용할 임시 메모리 크기. 자신의 컴퓨터 메모리 용량에 따라 여유가 되는 대로 적절히 조절


-sym, -nonsym: 대상 물체가 사람 얼굴처럼 좌우대칭인지 여부를 설정하는 파라미터. 기본값은 true로 설정되어 있기 때문에 만일 좌우 대칭이 아닌 경우에만 -nonsym을 입력



8. OpenCV Cascade Training 방법


opencv_traincascade.exe 유팉러티를 사용해서 cascade classifier를 훈련시키는 방법에 대한 설명입니다. 기존의 Haar Training 방법을 업그레이드 한 것으로서, Haar feature뿐만 아니라 LBP(Local Binary Patterns), HOG(histogram of oriented gradient) feature까지 사용할 수 있습니다.


또한 opencv_traincascade는 병렬처리 라이브러리인 tbb를 지원하기 때문에 예전 방식보다 훨씬 빠르게 training을 수행할 수 있습니다. 물론 tbb 지원을 위해서는 opencv를 tbb에 맞게 설정을 하고 rebuild해야 합니다.


이 유틸러티의 파라미터 목록 및 기본값, 각각의 파라미터에 대한 간략 설명은 다음과 같습니다.

Usage: opencv_traincascade

  -data <cascade_dir_name>

  -vec <vec_file_name>

  -bg <background_file_name>

  [-numPos <number_of_positive_samples = 2000>]

  [-numNeg <number_of_negative_samples = 1000>]

  [-numStages <number_of_stages = 20>]

  [-precalcValBufSize <precalculated_vals_buffer_size_in_Mb = 256>]

  [-precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb = 256>]

  [-baseFormatSave]

  [-stageType <BOOST(default)>]

  [-featureType <HAAR(default), LBP, HOG>]

  [-w <sampleWidth = 24>]

  [-h <sampleHeight = 24>]

  [-bt <DAB | RAB | LB | GAB (default)>]

  [-minHitRate <min_hit_rate = 0.995>]

  [-maxFalseAlarmRate <max_false_alarm_rate = 0.5>]

  [-weightTrimRate <weight_trim_rate = 0.95>]

  [-maxDepth <max_depth_of_weak_tree = 1>]

  [-maxWeakCount <max_weak_tree_count = 100>]

  [-mode <BASIC (default) | CORE | ALL>]


사용예.

opencv_traincascade -data result -vec tr.vec -bg nlist.txt -numPos 400 -numNeg 5000 -featureType HAAR -mode CORE


대부분의 파라미터는 7절에서 이미 설명하였기에 차이가 있는 부분이나 새로 추가된 몇 가지 주요 파라미터에 대해서만 설명토록 하겠습니다.


-data: 입력 경로명에 해당하는 폴더가 없을 경우 에러가 발생하기 때문에 미리 폴더를 생성한 후에 폴더 경로명을 입력해 주어야 함. 입력한 폴더에 각 cascade 단계별 classifier들과 최종 학습된 classifier가 저장됨. 저장되는 최종 classifier 이름은 cascade.xml임.


-featureType: HAAR, LBP, HOG 세가지 타입의 feature를 선택할 수 있음. 각 feature의 차이에 대해서는 2절의 내용을 참조하기 바람.


-baseFormatSave: -featureType이 HAAR일 경우에만 의미를 가지는 파라미터임. 이 파라미터를 명시해 주면 훈련 결과를 예전의 Haar training 방식의 데이터 포맷으로 저장해줌.



9. 학습된 검출기를 이용해서 실제 물체 검출하기


다른 포스팅 글인 영상 보행자 검출 기술(Pedestrian Detection) - 정보공유에 올려놓은 PedestrianOpenCV.zip 에 있는 코드를 참조하거나 OpenCV에서 제공하는 opencv\samples\c\facedetect.cpp 예제를 참조하시기 바랍니다.



10. Training 과정에서 발생할 수 있는 에러와 해결법


* OpenCV Error: Assertion failed (elements_read == 1) in unknown function


=> positive 샘플 수를 잘못 입력했기 때문에 발생하는 에러임. 파라미터중 -npos, -numPos는 전체 positive 샘플의 개수가 아니라 각 cascade 단계에서 사용할 positive 샘플 개수임. 아래 내용은 이 문제에 대해서 개발자가 답변한 내용임.


The problem is that your vec-file has exactly the same samples count that you passed in command line -numPos 979. Training application used all samples from the vec-file to train 0-stage and it can not get new positive samples for the next stage training because vec-file is over. The bug of traincascade is that it had assert() in such cases, but it has to throw an exception with error message for a user. It was fixed in r8913. -numPose is a samples count that is used to train each stage. Some already used samples can be filtered by each previous stage (ie recognized as background), but no more than (1 - minHitRate) * numPose on each stage. So vec-file has to contain >= (numPose + (numStages-1) * (1 - minHitRate) * numPose) + S, where S is a count of samples from vec-file that can be recognized as background right away. I hope it can help you to create vec-file of correct size and chose right numPos value


정리하면, npos <= (vec파일에 있는 샘플수 - S)/(1+(nstages-1)*(1-minhitrate)))가 되도록 -npos나 -numPos 값을 주라는 말임. S는 vec 파일에 있는 positive들 중에서 검출기로는 정말 찾기 힘들 것 같은 것들의 수임 (그래서 classifier가 negative라고 간주해 버릴 수 있는 것들). S가 좀 모호함;; 일단 S = 100 정도 줘 보고 혹시 에러나면 S를 좀 높이면 될 듯 함.


* training 도중 세그멘테이션 폴트(segmentation fault)가 날 경우


=> opencv_haartraining.exe를 병렬처리 기능인 OpenMP를 활성화시킨 상태에서 돌리면 이런 현상이 나타날 수 있다고 함. 그 이유는 opencv_haartraining 유틸러티가 워낙 낡아서(?) 요즘 opencv 컴퓨팅 환경과 맞지 않기 때문이라고 함. 이러한 경우에는 조금 느리더라도 OpenMP를 비활성화시킨 상태에서 opencv_haartraining.exe를 컴파일해서 사용하거나, 아니면 최신 버전의 유틸러티인 opencv_traincascade.exe를 사용해야 함.


* Cascade 학습 도중 무한루프에 빠지는 경우


=> opencv_traincascade.exe를 사용할 경우, int negCount = fillPassedSamples( posCount, proNumNeg, false, negConsumed ); 수행중 fillPassedSamples 함수 내부의 f(;;) 루프에서 무한 루프에 빠질 수 있습니다. negative 배경 이미지들로부터 if( predict( i ) == 1.0F )를 만족하는 negative 샘플을 negNum 만큼 확보하지 못하면 발생하는 것 같습니다. 한 해결법은 이곳을 참조하세요. 다른 해결법은 negative 이미지들을 모두 조사했는지를 체크하는 루틴을 삽입해서 모두 조사했는데도 불구하고 아직 샘플을 찾지 못한 경우에는 break로 for(;;) 문을 빠져나가도록 하면 됩니다.


=> 무한루프 해결에 관한 구체적인 방법을 별도 글로 포스팅하였습니다. OpenCV Haar/cascade training 무한루프 방지(http://darkpgmr.tistory.com/112) 글을 참조하세요.



11. Training/샘플링 프로그램


Training 샘플 데이터 생성 및 Haar Training, Cascade Training (Haar feature, LBP feature, HOG feature), 그리고 실제 영상에서의 물체인식 테스트까지 할 수 있는 통합 프로그램을 구현해 보았습니다. [개발한 것들] - Haar/Cascade Training 프로그램에서 다운로드 받을 수 있습니다.


또한, positive training 샘플을 만들 때 사용할 수 있는 프로그램으로 [개발한 것들] - Ground Truth 편집 프로그램을 활용하시면 좋습니다. 원래는 비디오 파일에서 물체의 경계사각형을 따기 위한 목적으로 개발한 것인데, 최근에 이미지 목록에서도 작업이 가능하도록 프로그램을 수정하였습니다.



by 다크 프로그래머


'영상처리' 카테고리의 다른 글

TOF 카메라의 원리  (20) 2013.06.24
영상인식과 색상모델(Gray,RGB,HSV,YCbCr)  (57) 2013.05.17
[영상추적#2] TLD - 추적하면서 학습한다  (14) 2013.05.16