Klasyfikator Haar`a

Transkrypt

Klasyfikator Haar`a
Klasyfikator Haar’a
Sterowniki robotów – projekt
Wojciech Matkowski
Filip Sobczak
29 maja 2012
Prowadzący:
Mgr inż. Jan Kędzierski
1
1. Opis projektu
Celem projektu było zapoznanie się z częścią pakietu OpenCV, która pozwala na
szybkie rozpoznawanie obiektów. Zawarte są tam narzędzia pozwalające na
trenowanie klasyfikatorów. Nie będziemy tu opisywali dokładnie algorytmów
wykorzystujących cechy Haar’a oraz algorytmów uczących się, które również są
wykorzystywane, opiszemy jednak co jest potrzebne i jak stworzyć działający
klasyfikator. W całej metodzie tworzenia klasyfikatora ważne są: cechy Haar’a, obraz
całkowy pozwalający na szybkie wykrywanie cech, algorytm AdaBoost, oraz
klasyfikator kaskadowy.
Rysunek 1 - zestaw przykładowych cech haropodobnych
2. Narzędzia
Systemy operacyjne na których pracowaliśmy to Windows Vista i Windows 7.
Potrzebne (używane przez nas) narzędzia to:
- OpenCV 2.1 ( http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.1/ ),
- emulator terminala Cygwin ( http://cygwin.com/install.html ),
- Strawberry Perl 5.14.2.1 ( http://strawberryperl.com/ ),
- Windows Movie Maker 2.6,
- Windows Office Picture Manager
- imageclipper20081114 ( http://code.google.com/p/imageclipper/downloads/list )
3. Przygotowanie danych
Na tym etapie postanowiliśmy, że pierwszy obiekt dla, którego stworzymy
klasyfikator Haar’a musi być prosty, tzn. jego geometria musi być możliwie prosta
oraz kolor jednolity. Zdecydowaliśmy, że obiektem tym będzie czarna filiżanka do
kawy. Kierowaliśmy się tym, że jest to w pewnym sensie faza próbna i uczenie
takiego klasyfikatora oraz przygotowanie danych do niego nie może trwać zbyt długo.
2
Poniżej zostaną opisane kolejne kroki etapu przygotowania danych.
PRZYGOTOWANIE DANYCH:
- wykonanie zdjęć obiektu, im więcej próbek tym lepiej, tutoriale w Internecie radzą
by próbek tych było ok. 7000, dla filiżanki jako, że jest to prosty obiekt zostało
wykonane 410 zdjęć. Zostały nakręcone filmy filiżanki tak by była ona ujęta z
różnych perspektyw oraz zostały wykonane również zdjęcia. Ważne jest by filmy bądź
zdjęcia zrobić w różnych warunkach tzn. przy różnym oświetleniu, w różnym
otoczeniu. Filmy i zdjęcia zostały wykonane aparatem cyfrowym klasy średniej.
- wycięcie klatek z filmu w naszym przypadku wycinaliśmy konkretne wybrane przez
nas klatki w programie Windows Movie Maker, można to zrobić w dowolny sposób
bądź automatycznie w jakimś innym programie.
- przekonwertowanie wszystkich zdjęć do jednego formatu w naszym przypadku był
to format JPG, oraz nadanie zdjęciom określonych nazw wg bliżej nieokreślonych
norm: image0001.jpg, image0002.jpg, image0003.jpg itd. Trzeba również zmienić ich
rozmiar. My ustawiliśmy 160x120.
- zdjęcia w takiej formie należy umieścić w katalogu ‘positive’, są to już
przygotowane do dalszej obróbki zdjęcia pozytywne
- stworzenie pliku positive.txt, potrzebny jest również plik z danymi, opisującymi
zdjęcia. Jego forma przedstawia się następująco:
image0001.jpg 1 43 31 75 58
image0002.jpg 1 24 37 79 56
[…]
W pierwszej kolejności jest nazwa pliku ze zdjęciem, następnie jest liczba, która
określa ilość obiektów na zdjęciu, kolejne dwie liczby opisują jego położenie x, y
patrząc od lewego górnego rogu ekranu, a kolejne dwie liczby długości po x i po y.
Przykład: image0001.jpg 1 43 31 75 58 – jeden obiekt, x=43 dł. po x=75 (w prawo),
y=31, dł. po y=58 (w dół).
Stworzenie pliku positive.txt można w części zautomatyzować, jednak nie można
uniknąć dokładnego zaznaczenia obiektu na zdjęciu. W tym celu wchodzimy do
katalogu wcześniej ściągniętego programu imageclipper20081114 i kopiujemy tam
wszystkie nasze zdjęcia na których chcemy zaznaczyć nasz obiekt. Następnie
odpalamy plik imageclipper.exe i zaznaczamy nasz obiekt na zdjęciach. Tak wycięte
obiekty zapisują się w folderze imageclipper z odpowiednimi nazwami które określają
położenie obiektów. Gdy już zaznaczyliśmy obiekt na wszystkich zdjęciach możemy
stworzyć plik positive.txt w tym celu korzystamy ze skryptu „haartrainingformat.pl” (
http://imageclipper.googlecode.com/svn/trunk/haartrainingformat.pl ), wywołujemy
go w Cygwinie poleceniem:
3
$ \ls imageclipper/*_*_* | perl haartrainingformat.pl -ls --trim --basename | tee positive.txt
W ten sposób stworzony został plik positive.txt
- stworzenie pliku negative.txt. Oprócz pozytywnych próbek potrzeba również jeszcze
więcej zdjęć negatywnych tzn. zdjęć, na których dany obiekt się nie znajduje – zdjęć
tła. My do filiżanki użyliśmy 440 takich zdjęć, które umieszcza się w katalogu
„negative”.
Bazy zdjęć dostępne są w Internecie np. takie bazy tematyczne można znaleźć na
stronie http://pascallin.ecs.soton.ac.uk/challenges/VOC/databases.html#VOC2005_1 ,
podobnie jak dla pozytywnych próbek należy zdjęciom nadać odpowiednie nazwy,
przekonwertować do odpowiedniego formatu np. JPG oraz zmienić rozmiary na np.
160x120. Następnie by stworzyć plik negative.txt należy wpisać w linie poleceń w
Cygwinie:
$ echo *.jpg > negative.txt
W ten sposób stworzony został plik negative.txt
Mamy przygotowane dwa foldery: „positive”, w którym znajdują się zdjęcia obiektu
oraz plik positive.txt oraz „negative”, w którym znajdują się zdjęcia tła oraz plik
negative.txt
STWORZENIE PROBEK
Po zainstalowaniu OpenCV 2.1 na dysku, w OpenCV2.1/bin/ umieszczony jest plik
wykonywalny opencv_createsamples.exe. W celu stworzenia wektora próbek
wywołujemy go poleceniem:
$ opencv_createsamples -info positive/positive.txt -vec
data/positive.vec -bg negative/negative.txt -num 410 bgcolor 0 -w 30 -h 30
Usage: C:\Windows\system32\opencv_createsamples.exe
[-info <collection_file_name>]
[-img <image_file_name>]
[-vec <vec_file_name>]
[-bg <background_file_name>]
[-num <number_of_samples = 1000>]
[-bgcolor <background_color = 0>]
[-inv] [-randinv] [-bgthresh <background_color_threshold =
80>]
[-maxidev <max_intensity_deviation = 40>]
[-maxxangle <max_x_rotation_angle = 1.100000>]
[-maxyangle <max_y_rotation_angle = 1.100000>]
[-maxzangle <max_z_rotation_angle = 0.500000>]
[-show [<scale = 4.000000>]]
[-w <sample_width = 24>]
[-h <sample_height = 24>]
4
4. Trening
Jest to etap, który trwa zdecydowanie najdłużej, trening klasyfikatora. Trening
odpalamy poleceniem:
$ opencv_haartraining -data data/cascade -vec
data/positive.vec -bg negative/negative.txt -npos 410 nneg 440 -nstages 30 -nsplits 2 -mem 2000 -nonsym -w 30 h 30
Usage: C:\Windows\system32\opencv_haartraining.exe
-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.995000>]
[-maxfalsealarm <max_false_alarm_rate = 0.500000>]
[-weighttrimming <weight_trimming = 0.950000>]
[-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>]
Czas treningu klasyfikatora dla filiżanki wynosił ok. 30 godzin na procesorze z
zegarem taktowanym 1,8 GHz.
Ważną informacją jest to, że trening można w dowolnej chwili przerwać, a później go
kontynuować od ostatniej sceny, która została wytrenowana. Dla filiżanki zostało
wytrenowane 21 scen. Na początku czas trenowania scen jest niedługi i wynosi od
kilku do kilkunastu minut dla naszych danych, dla kolejnych scen czas ten się
znacznie wydłuża.
Można śledzić na bieżąco czy trening zakończy się sukcesem. Poniżej przykładowy
log z jednego z treningów odpalonego od pewnego momentu:
5
$ opencv_haartraining -data data_tmp/cascade -vec samples.vec -bg
negative4/negative4.txt -npos 7000 -nneg 2800 -nstages 30 -nsplits 2 -mem 1000 nonsym -w 20 -h 20 -mode ALL
Data dir name: data_tmp/cascade
Vec file name: samples.vec
BG file name: negative4/negative4.txt, is a vecfile: no
Num pos: 7000
Num neg: 2800
Num stages: 30
Num splits: 2 (tree as weak classifier)
Mem: 1000 MB
Symmetric: FALSE
Min hit rate: 0.995000
Max false alarm rate: 0.500000
Weight trimming: 0.950000
Equal weights: FALSE
Mode: ALL
Width: 20
Height: 20
Applied boosting algorithm: GAB
Error (valid only for Discrete and Real AdaBoost): misclass
Max number of splits in tree cascade: 0
Min number of positive samples per cluster: 500
Required leaf false alarm rate: 9.31323e-010
Stage 0 loaded
Stage 1 loaded
Stage 2 loaded
Stage 3 loaded
Stage 4 loaded
Stage 5 loaded
Stage 6 loaded
Stage 7 loaded
Stage 8 loaded
Stage 9 loaded
Stage 10 loaded
Stage 11 loaded
Stage 12 loaded
Stage 13 loaded
Stage 14 loaded
Stage 15 loaded
Stage 16 loaded
Stage 17 loaded
Stage 18 loaded
Stage 19 loaded
Tree Classifier
Stage
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0---1---2---3---4---5---6---7---8---9--10--11--12--13--14--15--16--17--18--19
Number of features used : 125199
Parent node: 19
*** 1 cluster ***
POS: 6344 7000 0.906286
NEG: 2537 1.94285e-005
BACKGROUND PROCESSING TIME: 3348.81
Precalculation time: 4.17
+----+----+-+---------+---------+---------+---------+
| N |%SMP|F| ST.THR |
HR
|
FA
| EXP. ERR|
+----+----+-+---------+---------+---------+---------+
|
1|100%|-|-0.316790| 1.000000| 1.000000| 0.324513|
+----+----+-+---------+---------+---------+---------+
|
2|100%|-|-0.532588| 1.000000| 1.000000| 0.337349|
+----+----+-+---------+---------+---------+---------+
|
3| 91%|-|-0.715612| 1.000000| 1.000000| 0.394663|
+----+----+-+---------+---------+---------+---------+
|
4| 88%|-|-0.854334| 0.996217| 0.982263| 0.343092|
+----+----+-+---------+---------+---------+---------+
|
5| 88%|-|-0.911590| 0.996847| 0.983839| 0.346132|
+----+----+-+---------+---------+---------+---------+
|
6| 84%|-|-0.981059| 0.995113| 0.973591| 0.308524|
+----+----+-+---------+---------+---------+---------+
6
Interpretacja:
- w pierwszej kolejności są wypisane parametry danego treningu, takie jak np. ilość
próbek pozytywnych - Num pos: 7000 , ilość próbek negatywnych - Num neg: 2800
etc.
- następnie jest informacja o załadowanych już wcześniej wyuczonych scenach,
widać, że sceny od 0 do 19 zostały załadowane.
-następnie wypisane są dwie najważniejsze informacje:
POS: 6344 7000 0.906286
NEG: 2537 1.94285e-005
Trzeci parametr POS powinien być jak najbliższy jedynce w tym przypadku równy
jest 0.906286, drugi parametr NEG powinien być jak najbliższy zera, w tym
przypadku równy jest 1.94285e-005. Klasyfikator jest użyteczny gdy wartość NEG
spadnie poniżej 5e-006. Opis pozostałych parametrów:
N – nr cechy dodanej do sceny
%SMP – procent użytych próbek
F – przyjmuje wartość „-„ gdy próbki nie są symetryczne względem osi y
ST.THR – wartość progowa dla sceny
HR – współczynnik wykrywalność obiektu
FA – współczynnik fałszywego wykrycia obiektu (fals alarm rate domyślnie
ustawiony na 0.5)
EXP. ERR – współczynnik błędu klasyfikacji algorytmu AdaBoost
Gdy trening się zakończy, bądź gdy mamy podejrzenie, że można go przetestować w
praktyce, można przejść do kolejnego etapu.
5. Konwersja do formatu XML
$ ./convert_cascade.exe --size="30x30" data/cascade text.xml
Po takim wywołaniu powstanie plik text.xml i wytrenowany klasyfikator będzie w
użytecznym formacie xml. Gdy posiadamy już plik text.xml można przejść do
kolejnego etapu.
6. Detekcja
$ ./facedetect.exe --cascade="text.xml"
$ facedetect --cascade=<xml_file> [nazwa_pliku(obraz | video)|index_kamery]
Dla kamery USB index_kamery =0 tak więc odpalenie facedetect jak powyżej jest poprawne.
7
7. Wnioski
Wytrenowanie użytecznego klasyfikatora jest procesem niełatwym i przed wszystkim
bardzo czasochłonnym, samo przygotowanie narzędzi i danych zajmuje sporo czasu.
Trening i testy zajmują jeszcze więcej czasu. Dlatego przed przystąpieniem do
tworzenie klasyfikatora należy dokładnie przeanalizować treści dostępne w Internecie
(których swoją drogą nie jest specjalnie dużo), pomocna jest również powstała grupa
na
Yahoo.
Najlepszym
źródłem
wiedzy
jest
strona:
http://note.sonots.com/SciSoftware/haartraining.html chociaż i tak jest kilka błędów
takich jak niezgodności środowiska etc. Zostanie to opisane poniżej w punkcie
„Dodatek”
Stworzony przez nas klasyfikator dla czarnej filiżanki nie jest idealny – czasami
wykrywane są przedmioty o zbliżonym kolorze (czarny) i kształcie. W otoczeniu jest
wiele przedmiotów czarnych, małych w przekroju zbliżonych do kwadratu z
zaokrągleniami bądź do koła np. źrenice, cienie powstające na fałdach koszuli, ciemne
włosy na głowie etc. Tak czy inaczej projekt uważamy za udany, a trenowanie
klasyfikatorów jeszcze nie jest skończone – więcej w punkcie „Dodatek”.
8. Dodatek
Po wytrenowaniu klasyfikatora dla czarnej filiżanki, widząc problemy oraz lepiej
znając temat, podjęliśmy próbę wytrenowania jeszcze jednego klasyfikatora dla
obiektu bardziej charakterystycznego niż czarna filiżanka. Tym obiektem jest
czerwony samochód Ferrari F40 (niestety model w skali 1:24). Zostało wykonane
1330 zdjęć obiektu, lecz pozytywnych próbek potrzeba więcej czyli ok.7000.
Jak zrobić 7000 próbek z 1330 zdjęć?
Zostało to opisane na stronie: http://note.sonots.com/SciSoftware/haartraining.html
Jest tam parę błędów, dlatego też opiszemy tutaj jak namnożyć ilość próbek
(sensownych).
1) W pierwszym kroku musimy zmienić system bo pod Windows Vista i Windows 7
nie uda nam się tego zrobić. My zmieniliśmy system na Ubuntu 11.04,
przypuszczalnie jakakolwiek odmiana Linux’a będzie ok..
2) Następnie należy zainstalować bibliotekę OpenCV – w tym celu ściągamy
OpenCV przeznaczone na nasz system, następnie musimy ją skompilować,
procesu komplikacji nie będziemy opisywać, jest on opisany krok po kroku np. na
stronie: http://opencv.willowgarage.com/wiki/InstallGuide%20%3A%20Debian
3) Zakładając że mamy już przygotowane zdjęcia pozytywne i negatywne tworzymy
pliki positive.dat i negative.dat. Tworzymy je poleceniem:
8
$ find ../../negative/ -name '*.jpg' > negative.dat
$ find ../../positive/ -name '*.jpg' > positive.dat
Gdzie ../../ to odpowiednie ścieżki do katalogów z nazwami zdjęć pozytywnych i
negatywnych.
4) Potrzebny jest również skrypt i program pana Naotoshi Seo
(http://note.sonots.com/About.html) .
Należy
pobrać
kod
mergevec.cpp
ze
strony:
http://tutorialhaartraining.googlecode.com/svn/trunk/HaarTraining/src/mergevec.cpp , następnie
musimy go skompilować. Kompilowany kod musi znajdować się w katalogu
haartraining/ w katalogach OpenCV gdzie są kody źródłowe. Przed kompilacją, w
kodzie należy poprawić:
#include <cvhaartraining.h>
#include <_cvhaartraining.h> na:
#include “cvhaartraining.h”
#include “_cvhaartraining.h”
Kompilacja:
$ g++ `pkg-config --cflags opencv` `pkg-config --libs
opencv` -o mergevec mergevec.cpp cvboost.cpp
cvcommon.cpp cvsamples.cpp cvhaarclassifier.cpp
cvhaartraining.cpp
Należy również pobrać skrypt createtrainsamples.pl ze strony: http://tutorialhaartraining.googlecode.com/svn/trunk/HaarTraining/bin/createtrainsamples.pl
Gdy mamy już skompilowany mergevec.cpp i skrypt createtrainsamples.pl
tworzymy próbki:
$ perl createtrainsamples.pl positive.dat negative.dat
samples 7000 "./createsamples -bgcolor 0 -bgthresh 0 maxxangle 1.1 -maxyangle 1.1 maxzangle 0.5 -maxidev 40
-w 20 -h 20"
$ find samples/ -name '*.vec' > samples.dat
$ ./mergevec samples.dat samples.vec
W ten sposób z 1330 próbek Ferrari F40 zrobiliśmy 7000 próbek które są w pliką
Samales.vec. Zdjęć negatywych jest 2800 (może się okazać, że za mało(???)).
Następnie odpaliliśmy trening na tym samym komputerze co trening filiżanki.
Trening trwa nadal w momencie pisania tego tekstu. Czyli trwa już 10 dni z trzema
parogodzinnymi przerwami na obniżenie temperatury komputera. Wytrenowanych
zostało już 20 scen. Log:
Parent node: 19
*** 1 cluster ***
POS: 6344 7000 0.906286
NEG: 2537 1.94285e-005
BACKGROUND PROCESSING TIME: 3348.81
Precalculation time: 4.17
[…][…]
[…][…]
9
Parametr NEG wynosi 1.94285e-005 i zmniejsza się wraz z ilością
wytrenowanych scen, jednak czas trenowania scen jest już bardzo długi np. 19
scena trenowała się 42 godziny.
Przy tak dużej ilości danych do treningu klasyfikatora potrzebna jest dobra maszyna z
szybkim wielordzeniowym procesorem, wtedy można wykorzystać to, że programy z
OpenCV napisane są wielowątkowo, zyskałoby się wtedy również dużą ilość czasu. Na
stronie Naotoshi Seo opisane jest również jak użyć OpenMP (multiprocessing) wraz z Visual
Studio 2005 Professional Edition.
9. Przydatne linki
- http://note.sonots.com/SciSoftware/haartraining.html - tutorial ze sporą ilością
wskazówek, przydatnych skryptów i programów,
- http://opencv.willowgarage.com/wiki/Welcome - stona OpenCV, wiki.
10

Podobne dokumenty