to get the file
Transkrypt
to get the file
Zaawansowane przetwarzanie obrazów Instrukcja 3 Temat: Obsługa kamer, stosowanie filtrów, rozpoznawanie wzorców w obrazie w czasie rzeczywistym Przygotował: mgr inż. Tomasz Michno 1 1 2 3 Wstęp CvCapture ∗ c a p t u r e = cvCreateCameraCapture ( 0 ) ; i f ( c a p t u r e==NULL) { p e r r o r ( " Blad . " ) ; r e t u r n 1 ; } I p l I m a g e ∗ frame ; 4 5 6 7 while (1) { frame = cvQueryFrame ( c a p t u r e ) ; i f ( ! frame ) break ; 8 cvShowImage ( " P rzy kla d − kamera " , frame ) ; 9 10 c h a r c = cvWaitKey ( 3 3 ) ; i f ( c == 27 ) break ; 11 12 13 } 14 15 c v R e l e a s e C a p t u r e ( &c a p t u r e ) ; Listing 1: Obsługa kamery - odczyt i wyświetlanie klatek w oknie Obsługa obrazu z kamery w bibliotece OpenCV jest bardzo zbliżona do obsługi zwykłych obrazów. Jednocześnie możliwe jest obsługiwanie wielu kamer. Programista tworzy urządzenie, które będzie odczytywało ramki (klatki, funkcja cvCreateCameraCapture, linia 1), a następnie w pętli pobiera kolejne klatki z użyciem funkcji cvQueryFrame (linia 5). Wszystkie ramki są typu IplImage, co pozwala na przetwarzanie ich w identyczny sposób, co zwykłe obrazy. CvCapture* cvCreateCameraCapture( int index ) gdzie: index - numer kamery, która ma być obsługiwana; w przypadku posiadania tylko jednej kamery lub w celu wybrania dowolnej można użyć wartości -1 IplImage* cvQueryFrame( CvCapture* capture ) gdzie: capture - wskaźnik na zmienną typu CvCapture, utworzoną za pomocą cvCreateCameraCapture 1 W listingu 1 warto zwrócić uwagę na sposób obsługi klawiatury (linie 10 i 11) - w linii 10 odczytujemy kod ASCII wciśniętego klawisza, a następnie w linii 11 sprawdzamy jego kod. W przypadku wciśnięcia klawisza ESC kończymy pętlę. Na koniec należy zwolnić zasoby przydzielone urządzeniu rejestrującemu za pomocą funkcji cvReleaseCapture (linia 14). Biblioteka OpenCV posiada zaimplementowane funkcje służące do rozpoznawania wzorców. Najprostszą z nich jest cvMatchTemplate(), niestety posiada ona poważną wadę którą jest czas wykonania. Z tego względu warto skorzystać z funkcji FastMatchTemplate dostępnej dla języka C++ pod adresem http://opencv.willowgarage.com/wiki/FastMatchTemplate. Jest ona bardzo szybka oraz pozwala wykrywać wiele wystąpień dane wzorca w jednym wykonaniu. Wymaga dodania pliku nagłówkowego vector. bool FastMatchTemplate( const IplImage& source, const IplImage& target, vector<CvPoint>* foundPointsList, vector<double>* confidencesList, int matchPercentage = 70, bool findMultipleTargets = true, int numMaxima = 5, int numDownPyrs = 2, int searchExpansion = 15 ); Najważniejsze parametry: source, target - obrazek źródłowy oraz wzorzec foundPointsList - wektor zawierający znalezione punkty, w których znajduje się wzorzec confidencesList - wektor zawierający stopnień pewności dla każdego znalezionego wystąpienia (0-100) matchPercentage - minimalny poziom rozpoznania wzorca findMultipleTargets - wartość true oznacza wyszukiwanie wielu wystąpień 1 2 3 4 5 6 7 I p l I m a g e ∗ marker = cvLoadImage ( " marker . png" ) ; v e c t o r <CvPoint> f o u n d P o i n t s L i s t ; v e c t o r <double> c o n f i d e n c e s L i s t ; i f ( ! FastMatchTemplate ( ∗ image , ∗ marker , &f o u n d P o i n t s L i s t , &c o n f i d e n c e s L i s t , 5 0 , t r u e , 15 ) ) { 2 p r i n t f ( " \nERROR: Fast match t e m p l a t e f a i l e d . \ n" ) ; return 3; 8 9 10 11 12 13 14 } f o r ( i n t i =0; i <f o u n d P o i n t s L i s t . s i z e ( ) ; i ++){ cout<<"x="<<f o u n d P o i n t s L i s t [ i ] . x<<" , y="<<f o u n d P o i n t s L i s t [ i ] . y<<e n d l ; c v C i r c l e ( image , f o u n d P o i n t s L i s t [ i ] , 6 4 , CV_RGB( 2 5 5 , 0 , 0 ) ) ; } Listing 2: Rozpoznawanie wzorców W Listingu 2 używana jest również funkcja cvCircle rysująca okrąg: void cvCircle(CvArr* img, CvPoint center, int radius, CvScalar color, int thickness=1, int lineType=8, int shift=0) gdzie: img - obrazek na którym zostanie narysowany okrąg center - środek okręgu radius - promień okręgu color - kolor linii (można użyć funkcji CV_RGB(r,g,b)) thickness - grubość linii (jeśli wartość ujemna, okrąg jest wypełniany) lineType - typ linii ( dozwolone typy: 8, 4, CV_AA ) shift - liczba bitów ułamkowych w punkcie środka okręgu i promieniu 2 Zadania 1. Napisz program, który będzie wyświetlał obraz z kamery na ekranie. 2. Do powyższego programu dodaj 4 dowolne przekształcenia, wyświetlając je w osobnych oknach. 3. W osobnym oknie odwróć fragment obrazu lub cały obraz z użyciem bezpośredniego dostępu do pikseli (np. podobnie jak w instrukcji nr 1). 4. Napisz program, który będzie rozpoznawał dowolną liczbę 4 wzorców (uproszczony rysunek) na obrazie wczytanym z dysku. W miejscu rozpoznania powinien być rysowany obrazek w pełnej jakości (nieuproszczony), za pomocą cvGet2D() i cvSet2D(). 3