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