sobota, 19 marca 2011

OpenCV - instalacja i pierwszy przykład w Ubuntu

Już od dłuższego czasu przymierzałem się, aby więcej czasu poświęcić systemom interaktywnym, a w szczególności problematyce analizy ruchu. Zagadnieniami wizualizacji i przetwarzania obrazów medycznych oczywiście nie przestaje się dalej zajmować, jednakże opisywanie tej tematyki na blogu nie dość, że było i jest bardzo wymagające czasowo, to niestety interesuje tylko bardzo małą grupę osób. Natomiast analiza ruchu ma wiele różnych zastosowań - nie tylko tych naukowych, ale również rozrywkowych. Podobnie z punktu widzenia nauki przetwarzania informacji obrazowej, dla wielu młodych osób ciekawsze wydaje się analizowanie obrazu z kamerki na żywo, zamiast analizy statycznych obrazów medycznych.

Tym wpisem rozpoczynam serię poradników dotyczących właśnie analizy ruchu. Głównym narzędziem (biblioteką) jak będzie używana będzie OpenCV, o którym pisałem ponad 2 lata temu na tym blogu. Dzisiaj chciałbym opisać proces instalacji tej biblioteki w Ubuntu i pokazać prosty przykład z użyciem kamerki internetowej.

Instalacja z repozytorium

Aby zainstalować OpenCV z repozytorium wpisujemy następujące polecenie w okienku terminala:
sudo apt-get install libcv-dev libcvaux-dev libhighgui-dev

Patrząc na tą komendę można zauważyć, że instalowane są tylko pakiety programistyczne. A co z bibliotekami? Zainstalują się one oczywiście same jako zależności wyżej wymienionych pakietów. Takie podejście jest oczywiście bardziej uniwersalne w przypadku instalacji OpenCV, ponieważ biblioteki te mają dodaną końcówkę 2.1 (np. libcv2.1), a tak nie będzie zawsze. Dla przykładu na stronie projektu jest już dostępna wersja 2.2.

Instalacja ze źródeł

Tak jak wspomniałem powyżej, wersja, która znajduje się w repozytorium nie jest najświeższa i osobom, którym szczególnie zależy, aby pracować na ostatniej wersji tej biblioteki polecam samodzielną kompilację ze źródeł. Nie jest ona skomplikowana, dlatego również zostanie opisana w tym poradniku.

Najnowszą stabilną wersję źródeł OpenCV można pobrać z portalu SourceForge, a dokładnie ze strony: http://sourceforge.net/projects/opencvlibrary/files/opencv-unix/. Można pobrać ją również bezpośrednio z repozytorium, aby mieć dostęp do aktualnie wprowadzanych funkcji. W tym celu wystarczy wpisać w konsoli następujące polecenie:
svn co https://code.ros.org/svn/opencv/trunk

Ja osobiście polecam wersję stabilną. Obecnie jest to wersja 2.2.

Teraz kiedy mamy pobrane już źródła biblioteki OpenCV, możemy przystąpić do jej kompilacji. Wykonujemy w tym celu następujące kroki:
  • Utworzenie katalogu build i uruchomienie w nim graficznej nakładki na CMake:
    mkdir build
    cd build
    cmake-gui ../
  • Przy pierwszej kompilacji najlepiej nie ustawiać zbyt wiele opcji, aby mieć pewność że podstawowa wersja się skompiluje. Ja ustawiłem tylko typ kompilacji na „Release
    CMAKE_BUILD_TYPE                 Release
  • Uruchomienie kompilacji. Jeśli mamy wiecej niż jeden rdzeń warto z tego skorzystać stosując przełącznik j:
    make -j2
  • Jeśli wszystko dobrze się skompiluje można wówczas uruchomić kolejne przebiegi kompilacji z włączonymi następującymi opcjami:
    BUILD_EXAMPLES                   ON
    BUILD_NEW_PYTHON_SUPPORT         ON
    OPENCV_BUILD_3RDPARTY_LIBS       ON
    Oczywiście tych opcji jest dużo więcej, dlatego polecam samodzielne testowanie pozostałych, chociaż te o których napisałem powinny w zupełności wystarczyć.
Jeśli pojawiły się jakieś niespodziewane błędy podczas kompilacji polecam zajrzeć na stronę:
http://opencv.willowgarage.com/wiki/InstallGuide w celu znalezienia rozwiązania.

Pierwsze testy

Na początek warto przetestować przykłady załączone w katalogu samples. Po kompilacji odpowiadające im wersje binarne powinny znaleźć się w katalogu: build/bin/. Ja sprawdziłem wszystkie i od razu mogę podpowiedzieć, że z kamerką działają te z nich:
  • adaptiveskindetector
  • bgfg_codebook
  • bgfg_segm
  • camshiftdemo
  • fback
  • fback_c
  • laplace
  • lkdemo
  • motempl
  • segment_objects
Pomimo tego, że nie są one szczególnie złożone, na początek warto zacząć od jeszcze prostszych przykładów.

Wyświetlanie obrazu z kamery

Jednym z pierwszych przykładów, które warto przeanalizować i uruchomić w OpenCV jest pobieranie obrazu z kamery i wyświetlenie go na ekranie monitora. Nie jest to oczywiście trudne, ale wymaga znajomości kilku elementarnych funkcji takich jak:
  • cvCaptureFromCAM - inicjalizacja kamery,
  • cvQueryFrame - pobranie pojedynczej klatki obrazu,
  • cvShowImage - wyświetlenie obrazka we wskazanym oknie.
Cały przykład wygląda następująco:
#include "opencv/highgui.h"

int main() 
{
  CvCapture *cam = cvCaptureFromCAM(-1);
  
  const char *window = "Example 1";
  cvNamedWindow(window, CV_WINDOW_AUTOSIZE);
  
  while (cvWaitKey(4) == -1) {
    IplImage *frame = cvQueryFrame(cam);
    cvShowImage(window, frame);
  }
  
  cvDestroyAllWindows();
  cvReleaseCapture(&cam);
  
  return 0;
}

Aby go skompilować wystarczy uruchomić:
gcc camera1.cpp -o camera1 -lhighgui

Ten sam przykład po nowemu

Przykład przedstawiony powyżej działa zarówno w bieżącej wersji OpenCV jak i w wersjach poprzednich. Jednakże własnie od wersji bieżącej 2.2 biblioteka ta została uporządkowana i podzielona na moduły. Dodatkowo zostały wprowadzone nowe funkcje i został zaproponowany bardziej obiektowy model programowania. Wszystkie te zmiany mają za zadanie ułatwić programowanie, ale nie pozwalają już na kompilację nowych programów tam gdzie jest stara wersja biblioteki. Program po zmianach wg nowych zaleceń wygląda tak:

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;

int main(int, char**)
{
  VideoCapture cap(0);
  if( !cap.isOpened() ) return -1;
  
  Mat frame;
  
  const char *window = "Example 2";
  namedWindow(window, CV_WINDOW_AUTOSIZE);
  
  while (cvWaitKey(4) == -1) {
    cap >> frame;
    imshow(window, frame);
  }
  
  return 0;
}

Kompilacja tak napisanego programu w konsoli nie jest już taka trywialna jak poprzednio. W takiej sytuacji najlepiej będzie skorzystać z narzędzia CMake, które jest podstawą budowania całej biblioteki OpenCV. W katalogu ze źródłami omawianych aplikacji tworzymy nowy plik CMakeLists.txt. Powinien on zawierać taką treść:

PROJECT(opencv_example)

cmake_minimum_required(VERSION 2.8)

FIND_PACKAGE( OpenCV REQUIRED )

# Declare the target (an executable)
ADD_EXECUTABLE(camera1 camera1.cpp)
TARGET_LINK_LIBRARIES(camera1 ${OpenCV_LIBS})

ADD_EXECUTABLE(camera2 camera2.cpp)
TARGET_LINK_LIBRARIES(camera2 ${OpenCV_LIBS})

Teraz już kompilacja sprowadza się do wpisania w konsoli:

mkdir build
cd build
cmake-gui ../

i określenia w parametrach CMake ścieżki do katalogu gdzie mamy zbudowany OpenCV. U mnie wygląda to tak:

OpenCV_DIR   /home/rafal/installed/opencv/OpenCV-2.2.0/build

Teraz już wystarczy wpisać make i oba programy zostaną skompilowane.

W ten sposób udało nam się przygotować dwie aplikacje, które niby nie robią wiele, ale stanowią szkielet większości aplikacji interaktywnych w OpenCV.

6 komentarze:

Dashrek 1 pisze...

Właśnie dzięki panu zainstalowałem openCV na Linuxie. Mam nadzieję, że ma pan już ten doktorat. Z innych rzeczy, czy można wybierać sposób zapisu pliku pomiędzy ascii, a binarnym w plikach ppm i pgm, tak jak w gimpie.

Rafał Petryniak pisze...

Na wszelki wypadek przesyłam również linka do oficjalnej dokumentacji z opisem instalacji w Linuksie: http://docs.opencv.org/3.2.0/d7/d9f/tutorial_linux_install.html.

Jeśli chodzi o sposób zapisu do ppm lub pgm to nie za bardzo jestem w stanie pomóc, bo sam nie korzystam z tych formatów.

Dashrek 1 pisze...

Jakby ktoś kiedyś potrzebował to odpowiadam.
Potrzebny wektor obecnie działa przez std:: na początku, bo widzę że kiedyś nie trzeba było tego tak używać, wystarczyło samo vector

#include

std::vector params;
params.push_back(CV_IMWRITE_PXM_BINARY);
params.push_back(0);

imwrite( "Image.ppm/lub pgm/lub pbm", gray_image, params );

Dlaczego pytam się o ten niewykorzystywany format?
Bo nie ma on żadnego zapisu kodu procesora, czy windows kodu jak bmp. Obraz ma bezpośrednie wartości pikseli r g b, zapisane liczbami od 0 do 255, fakt jest przez to duży, ale zapisany jako obraz tymczasowy daje niesamowite możliwości przekształceń dla programisty, np. filtr Kuwahara, zaś forma obrazu to tablica G[3*i+k][j], gdzie 3 to ilość kolorów, k to numer koloru, i,j to numer komórki.

Rafał Petryniak pisze...

Dzięki za rozpisanie tego. Może komuś się przyda :-)

Dashrek 1 pisze...

Mam taki lekki problem z CMake. Mój stary program został podzielony na dwa, ze względu na dużą liczbę funkcji, zwykły makefile wyglądał tak
a.out: main.o funkcje.o
gcc main.o funkcje.o -lm

main.o: main.c funkcje.h
gcc -c main.c

funkcje.o: funkcje.c funkcje.h
gcc -c funkcje.c
To był program pod konsolę. Zwykłe pytanie, bo przerabiam ten program pod GTK i OpenCV, jak skompilować ten program w cmake? Coś widzę w tych tutorialach tworzenie dwóch oddzielnych folderów, trzech cmakelist, ale niezbyt mi to wychodzi :-(

Rafał Petryniak pisze...

Proszę o kontakt na maila (podany w sekcji "O mnie") to podeślę przykład plików konfiguracyjnych.

Prześlij komentarz