Programowanie
OpenCV – systemy wizyjne
58
październik 2009
Programowanie
OpenCV – systemy wizyjne
59
www.lpmagazine.org
lin
ux
@
so
ftw
ar
e.
co
m
.p
l
OpenCV
– systemy wizyjne
Systemy monitoringu, urządzenia automatycznie liczące klientów w centrach handlowych, aparaty cyfrowe
z wyzwalaczem aktywowanym uśmiechem, inteligentne pociski rakietowe – wszystkie z tych urządzeń
korzystają z dobrodziejstw cyfrowego przetwarzania obrazów i rozpoznawania wzorców. Jeszcze do
niedawna, wykorzystanie podstawowych algorytmów z tej dziedziny wymagało od programisty dobrej
znajomości podstaw matematycznych oraz zagadnień związanych z cyfrowym przetwarzaniem sygnałów
(ang. DSP – Digital Signal Processing). Sytuacja ta uległa jednak zmianie wraz z opracowaniem biblioteki
OpenCV, implementującej wszystkie najważniejsze algorytmy. Zapraszam do lektury!
Rafał Kułaga
Ż
yjemy w czasach, gdy postęp automatyzacji co-
raz to większej liczby dziedzin życia jest nie-
unikniony. Wynika to nie tylko z wysokich kosz-
tów ludzkiej pracy, lecz również z ułomności na-
szych zmysłów – głównie wzroku i słuchu. Nie jesteśmy w
stanie zauważyć migotania diody jeżeli odbywa się ono ze
zbyt dużą częstotliwością, nasz zmysł wzroku reaguje na
bardzo ograniczoną szerokość pasma fal elektromagnetycz-
nych. Podobnie jest ze słuchem – nie słyszymy dźwięków o
bardzo wysokiej częstotliwości (powyżej 20 kHz – ultradź-
więków), ani drgań o niskiej częstotliwości (poniżej 20 Hz
– infradźwięków), mimo iż oddziaływują one bardzo nieko-
rzystnie na nasze zdrowie i samopoczucie.
Znacznie większe możliwości w tym zakresie daje nam
sprzęt elektroniczny. Rozmaite urządzenia pozwalają na reje-
strację zjawisk, które zachodzą bardzo szybko lub bardzo po-
woli, albo w ogóle nie są odbierane przez ludzkie zmysły. Nie
ulegają one zmęczeniu, mogą pracować w bardzo ciężkich
warunkach (pod warunkiem, że zostaną do nich odpowiednio
przystosowane) oraz, na dłuższą metę, są znacznie tańsze.
Niestety, okazuje się, że realizacja zadań charaktery-
stycznych dla ludzkiego mózgu za pomocą sprzętu elek-
tronicznego jest niezwykle trudna w realizacji. Wynika to
głównie z faktu, iż przetwarzanie w komórkach nerwowych
i mózgu odbywa się w sposób ogromnie zrównoleglony
– nie mamy nawet świadomości, jak potężnym i złożonym
narzędziem obliczeniowym jest nasz umysł.
W tym artykule zajmiemy się przechwytywaniem, prze-
twarzaniem oraz analizą obrazów. Z pewnością zauważysz,
że zastosowanie omawianych technik powoduje wiele po-
ważnych problemów natury technicznej. Sytuacja ulega jed-
nak systematycznej poprawie, wraz z postępami badań w
dziedzinach takich jak sztuczna inteligencja (sieci neurono-
we), cyfrowe przetwarzanie sygnałów (DSP) oraz przetwa-
rzanie równoległe. Techniki, których zastosowanie uprasz-
cza biblioteka OpenCV, znalazły swoje zastosowanie w inte-
ligentnych systemach uzbrojenia, przemyśle, robotyce, han-
dlu oraz systemach monitoringu.
Systemy wizyjne
Zanim przejdziemy do dalszej części artykułu, w której zaj-
miemy się praktyczną realizacją funkcji związanych z syste-
mami wizyjnymi przy użyciu biblioteki OpenCV, warto za-
dać sobie pytanie, czym tak naprawde są systemy wizyjne?
Programowanie
OpenCV – systemy wizyjne
58
październik 2009
Programowanie
OpenCV – systemy wizyjne
59
www.lpmagazine.org
Budowa systemu wizyjnego
Systemem wizyjnym nazywamy zespół urzą-
dzeń, wykorzystywanych w celu badania oto-
czenia w sposób podobny do tego, w jaki reali-
zowane jest to przez nasz mózg, tzn. przy pomo-
cy odbieranego światła. Typowy system wizyj-
ny składa się z następujących elementów:
• Urządzenia rejestrującego obraz – w każ-
dym systemie wizyjnym musi znajdować
się urządzenie odpowiedzialne za rejestro-
wanie obrazu i przesyłanie go do urządzenia
przetwarzającego. W większości systemów
wizyjnych jest to kamera cyfrowa podłączo-
na za pomocą odpowiedniego interfejsu lub
karta frame grabber, służaca do przechwyty-
wania obrazu z urządzenia analogowego;
• Urządzenia przetwarzającego z odpowied-
nim oprogramowaniem – często jest to
standardowy komputer PC z zainstalowa-
nym odpowiednim oprogramowaniem. W
części systemów wizyjnych (szczególnie
tych oferowanych jako gotowe rozwiąza-
nia), element ten jest zbudowany w opar-
ciu o systemy wbudowane – dzięki po-
stępowi technologii wielordzeniowej we
współczesnych układach scalonych SoC
(ang. System-on-Chip), możliwa stała się
realizacja nawet bardzo skomplikowanych
algorytmów.
W większości przypadków, systemowi wizyj-
nemu towarzyszą dodatkowe urządzenia, takie
jak aktuatory, służące do zmiany stanu otocze-
nia. Niekiedy konieczne jest również zastoso-
wanie dodatkowych czujników (np. ultradźwię-
kowych czujników odległości) w celu zwięk-
szenia możliwości systemu wizyjnego lub za-
bezpieczeniem przed błędami, które mogłyby
być katastrofalne w skutkach.
Zastosowanie systemów
wizyjnych i przetwarzania obrazów
Systemy wizyjne oraz algorytmy przetwarzania
i analizy obrazów znajdują obecnie bardzo wiele
zastosowań. Warto jednak zastanowić się, jakie
możliwości daje ich zastosowanie, tzn. co mo-
żemy zrobić dalej z wynikami działania algoryt-
mów w nich wykorzystywanych?
Bardzo często, szczególnie w zastosowa-
niach przemysłowych, działanie systemu wizyj-
nego prowadzi do podjęcia konkretnej decyzji,
np. sprawdzany produkt jest wadliwy. Od osoby
projektującej system zależy, czym będzie skut-
kowała taka decyzja. W większości wdrożeń
przemysłowych, systemy wizyjne są dodatkowo
wspierane danymi pochodzącymi z czujników.
Efektem działania algorytmów wizyjnych mo-
że być również inny, przetworzony obraz wraz
ze zbiorem dodatkowych danych (np. położe-
niem interesujących nas cech). Przykładem ta-
kiego zastosowania biblioteki OpenCV jest roz-
wiązanie zastosowane przez firmę Google w ce-
lu odpowiedniego dopasowania danych pocho-
dzących z systemu Google Maps do obrazów
satelitarnych, wykorzystywanych w programie
Google Earth.
Następnym przykładem są aplikacje gra-
ficzne, w których algorytmy analizy i przetwa-
rzania obrazu wykorzystywane są do korekcji
zdjęć oraz nowoczesne interfejsy, pozwalające
na obsługę aplikacji przy użyciu gestów.
Coraz większe znaczenie zyskują również
pojazdy bezzałogowe, sterowane przy wykorzy-
staniu danych pochodzących z kamery. Bez ich
wykorzystania, niemożliwa byłaby eksploaracja
kosmosu, w tym większość misji mających na
celu badanie planety Mars. Możesz zastanawiać
się, dlaczego w takich przypadkach nie używa się
zdalnego sterowania, które jest przecież znacznie
bardziej niezawodne. Decyzja taka jest spowodo-
wana bardzo dużą odległością, którą fala elektro-
magnetyczna przebywa w czasie tak długim, iż
uniemożliwia to skuteczne sterowanie.
Bardzo ważną dziedziną, w której syste-
my wizyjne odnalazły swoje zastosowanie, jest
przemysł zbrojeniowy. Zaawansowane techniki
analizy, przetwarzania obrazu i rozpoznawania
cech, pozwalają na automatyczne naprowadza-
nie pocisków rakietowych tak, aby trafiały do-
kładnie w cel. Odbywa się to poprzez budowę
modelu celu, a następnie jego odnajdywanie (za
pomocą odpowiednich algorytmów) w obrazie
pochodzącym z kamer.
Listing 1.
Pierwszy program korzystający z bi-
blioteki OpenCV
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
int
main
(
int
argc
,
char
*
argv
[])
{
IplImage
*
img
;
if
(
argc
!=
2
)
{
printf
(
"Uzycie: hw <nazwa
pliku>\n"
);
return
1
;
}
//wczytanie pliku
img
=
cvLoadImage
(
argv
[
1
]);
//prosta transformacja -
wygładzanie
cvSmooth
(
img
,
img
,
CV_GAUSSIAN
,
3
,
3
);
//otwarcie okna
cvNamedWindow
(
"OpenCV Hello
World!"
,
CV_WINDOW_AUTOSIZE
);
//wyświetlenie obrazu
cvShowImage
(
"OpenCV Hello
World!"
,
img
);
//oczekiwanie na naciśnięcie
klawisza
cvWaitKey
();
//zakończenie
cvReleaseImage
(
&
img
);
cvDestroyWindow
(
"OpenCV Hello
World!"
);
return
0
;
}
Rysunek 1.
Pierwsza aplikacja w bibliotece OpenCV
60
październik 2009
Programowanie
OpenCV – systemy wizyjne
61
www.lpmagazine.org
Programowanie
OpenCV – systemy wizyjne
Problemy i ograniczenia
Niestety, szerokie zastosowanie systemów wi-
zyjnych nadal napotyka wiele problemów. Wy-
nikają one głównie z modelu przetwarzania da-
nych, wykorzystywanych we współczesnych
procesorach i mikrokontrolerach.
Jeżeli zastanowisz się chwilę nad większo-
ścią znanych Ci algorytmów, to z pewnością za-
uważysz, iż opierają się one na ściśle określo-
nym wykorzystaniu danych wejściowych w ce-
lu otrzymania ostatecznego wyniku. Wszyscy
znamy algorytmy takie jak sito Eratostenesa,
poszukiwanie największego wspólnego dziel-
nika dwóch liczb, czy chociażby sortowanie bą-
belkowe. Nie ulega wątpliwości, iż są one ści-
słe. Co więcej – jednym z podstawowych kryte-
riów poprawności każdego algorytmu jest wła-
śnie jego ścisłość i możliwość wielokrotnego za-
stosowania dla dowolnych danych wejściowych
(spełniających konkretne założenia).
W analizie obrazów trudno jest jednak
wskazać proste sposoby określania chociażby
podstawowych cech ogólnych obrazu. Można
to łatwo wytłumaczyć – czy znasz prosty sposób
ścisłego określenia wyglądu pingwina? Z pew-
nością nie. Szczególnie dużym problemem jest
fakt, iż nie chodzi to o opis typu: dwie nogi, krót-
kie skrzydła, kolor czarno-biały, lecz o określe-
nie matematycznych zależności pomiędzy po-
szczególnymi pikselami! Zwróć również uwa-
gę, że pingwin może przyjmować wiele póz,
może być częściowo zasłonięty, lub poprostu
może to być dwuwymiarowa fotografia. Widać,
że istnieje wiele problemów, z których część
wynika z samego faktu przedstawienia trójwy-
miarowego świata w postaci dwuwymiarowej
– wiadomo bowiem, że obiekt z przestrzeni trój-
wymiarowej może mieć, przynajmniej teore-
tycznie, nieskończenie wiele prawidłowych re-
prezentacji w przestrzeni dwuwymiarowej.
W celu rozwiązania tych problemów wy-
korzystuje się, oprócz standardowych algoryt-
mów, sieci neuronowe oraz inne, bardziej skom-
plikowane klasyfikatory. Algorytmy z dziedziny
przetwarzania sygnałów cechują się dużym wy-
korzystaniem mocy obliczeniowej oraz pamięci,
co ogranicza ich wykorzystanie w aplikacjach
czasu rzeczywistego. Sieci neuronowe, pomimo
iż nie odzwierciedlają w sposób dokładny bu-
dowy ludzkiego mózgu, w wielu przypadkach
okazują się dobrym rozwiązaniem. Ich zastoso-
wanie wymaga czasochłonnego procesu ucze-
nia, jednak samo użycie w celu przetwarzania
danych jest już bardzo szybkie.
Biblioteka OpenCV
Własnoręczna implementacja algorytmów z
dziedziny przetwarzania i analizy obrazów mo-
że być bardzo trudna, szczególnie dla mniej do-
świadczonych programistów. W celu umożli-
wienia szerokiemu gronu użytkowników dostę-
pu do omawianych technik, została opracowa-
na biblioteka OpenCV, której zastosowanie jest
głównym tematem tego artykułu.
Historia biblioteki OpenCV
Historia biblioteki OpenCV sięga roku 1999,
kiedy to w firmie Intel podjęto decyzję o roz-
poczęciu rozwju biblioteki, której celem było-
by usystematyzowanie znanych algorytmów z
dziedziny przetwarzania i analizy obrazów. Pro-
jekt ten był częścią większego działania, mają-
cego na celu popularyzację wykorzystania al-
gorytmów i technik wymagających dużej mo-
cy obliczeniowej.
Po upływie pewnego czasu, Intel zdecydo-
wał się udostępnić projekt OpenCV społeczno-
ści. W roku 2006 ukazała się wersja 1.0 biblio-
teki. Obecnie bliblioteka OpenCV dostępna jest
na licencji BSD, która pozwala na jej dowol-
ne wykorzystanie, również w celach komer-
cyjnych, bez konieczności upubliczaniania ko-
du źródłowego.
Możliwości i algorytmy
Biblioteka OpenCV zawiera wiele algoryt-
mów, pozwalających na przetwarzanie obrazu
oraz wydobywanie cech. Składa się z następu-
jących modułów:
• CXCORE – podstawowa część biblioteki,
odpowiedzialna za definicje podstawowych
struktur i algorytmów, funkcje związane z
rysowaniem figur oraz obsługę XML;
• CV – główna część biblioteki, zawierająca
algorytmy z dziedziny przetwarzania obra-
zów oraz algorytmy wizyjne;
• MLL – część biblioteki odpowiedzialna za
funkcje klasy machine learning, między in-
nymi klasyfikatory statystyczne;
• HighGUI – część biblioteki odpowiedzial-
na za obsługę interfejsu użytkownika, ope-
racje wejścia i wyjścia oraz obsługę plików
wideo i urządzeń wejściowych, takich jak
kamery.
Listing 2.
Aplikacja odtwarzająca pliki wideo
#include <stdio.h>
#include <highgui.h>
int
main
(
int
argc
,
char
*
argv
[])
{
IplImage
*
currentFrame
;
CvCapture
*
video
;
char
key
;
if
(
argc
!=
2
)
{
printf
(
"Uzycie: vid <nazwa pliku>\n"
);
return
1
;
}
cvNamedWindow
(
"Wideo"
,
CV_WINDOW_AUTOSIZE
);
//otwieramy plik wideo
video
=
cvCreateFileCapture
(
argv
[
1
]);
while
(
1
)
//główna pętla
{
//odczytujemy następną klatkę
currentFrame
=
cvQueryFrame
(
video
);
//czy to koniec pliku?
if
(
!
currentFrame
)
break
;
//wyświetlamy klatkę
cvShowImage
(
"Wideo"
,
currentFrame
);
//odpowiednia ilość FPS
key
=
cvWaitKey
(
35
);
if
(
key
==
27
)
break
;
}
cvReleaseImage
(
&
currentFrame
);
cvReleaseCapture
(
&
video
);
cvDestroyWindow
(
"Wideo"
);
return
0
;
}
60
październik 2009
Programowanie
OpenCV – systemy wizyjne
61
www.lpmagazine.org
Programowanie
OpenCV – systemy wizyjne
Łącznie, biblioteka OpenCV zawiera ponad 500
algorytmów z dziedziny systemów wizyjnych
oraz pokrewnych. Co więcej, dzięki zastoso-
waniu technik machine learning oraz prostych
sieci neuronowych, OpenCV stanowi świetną
podstawę zarówno dla profesjonalnych syste-
mów wizyjnych, badań naukowych, jak i ama-
torskich projektów.
Obsługiwane architektury
W profesjonalnych systemach wizyjnych, w ce-
lu przetwarzania danych pochodzących z kamery,
bardzo często wykorzystywane są urządzenia nie-
zgodne z architekturą x86. Biblioteka OpenCV,
pomimo iż oficjalnie nie obsługuje takich urzą-
dzeń, może zostać wykorzystana na wielu innych
architekturach, w tym tzw. inteligentnych kame-
rach, zawierających zintegrowane mikroproceso-
ry, umożliwiające realizację prostych zadań zwią-
zanych z wizją komputerową.
Więcej informacji na temat możliwości
uruchomienia programów wykorzystujących bi-
bliotekę OpenCV na alternatywnych architektu-
rach, znajdziesz w internecie na stronach wy-
mienionych w ramce W Sieci.
Instalacja
Przejdźmy teraz do instalacji biblioteki
OpenCV. Jest ona dostępna na stronie http:
//sourceforge.net/projects/opencvlibrary/. Pole-
cam Ci ściągnięcie wersji 1.1pre1 – jest to naj-
nowsza, wspierana wersja biblioteki. Oczywi-
ście, możesz skorzystać z repozytoriów CVS
– bardzo rzadko w dostępnych tam wersjach
znajdują się błędy. My jednak dopiero zaczyna-
my przygodę z biblioteką OpenCV, więc nie są
nam potrzebne wszystkie nowości.
Zanim przejdziemy do właściwej instalacji
biblioteki OpenCV, warto upewnić się, że w na-
szym systemie zostały zainstalowane wszystkie
niezbędne biblioteki, a wśród nich: gtk2+, libpng,
libtiff, libjpeg, libjasper, zlib. Pamiętaj, że musisz
dysponować pakietami w wersji dev – w prze-
ciwnym wypadku nie będzie możliwe ich wy-
korzystanie przez OpenCV. Po zainstalowaniu
wszystkich niezbędnych pakietów (dokładną listę
znajdziesz na OpenCV Wiki), możesz przejść do
pobrania i instalacji biblioteki OpenCV.
Po pobraniu pliku z źródłami, wypakuj je
do nowego katalogu za pomocą polecenia:
tar -xvzf nazwa_archiwum.tar.gz
Następnie, po przejściu do katalogu z wypako-
wanymi danymi, wydaj polecenie:
autoreconf
-i --force
. Dla zachowania porządku, bibliote-
kę skompilujemy w nowym katalogu – w tym ce-
lu utworzymy nowy katalog za pomocą polecenia
mkdir install
i z jego poziomu wydamy po-
lecenie
../configure --prefix=/usr/local/
.
Zwróć uwagę na podsumowanie konfiguracji bi-
blioteki HighGUI, a szczególnie konfigurację in-
terfejsu okien – niewykrycie biblioteki gtk2+ spo-
woduje, że wywołanie dowolnej funkcji związa-
nej z obsługą okien zakończy się błędem. Warto
również sprawdzić, czy zostały wykryte zainsta-
lowane przez nas biblioteki graficzne.
Jeżeli nie zauważysz żadnych nieprawidło-
wości w wyniku działania skryptu
configure
,
możesz rozpocząć kompilacje przy użyciu pole-
cenia
make
. Po jej zakończeniu, jeżeli dysponu-
jesz uprawnieniami użytkownika root, możesz
dokonać instalacji przy pomocy polecenia
ma-
ke install
. Ostatnim krokiem jest wywołanie
programu
ldconfig
.
Pierwszy program w OpenCV
Zanim przejdziemy do dalszej części artykułu,
warto upewnić się, że biblioteka OpenCV została
zainstalowana poprawnie. W tym celu napiszemy
prosty program, wczytujący obraz z pliku, doda-
jący efekt rozmycia (Gaussian Blur), a następnia
wyświetlający obraz w oknie (Rysunek 1).
Kod źródłowy programu znajduje się na Li-
stingu 1. Jak widzisz, wszystkie operacje na ob-
razie sprowadzają się do wywołania odpowied-
nich funkcji. Przy wykorzystaniu OpenCV wy-
świetlenie nowego okna nie wymaga znajomo-
ści żadnych dodatkowych bibliotek.
Nasz pierwszy program sprawdza, czy przy
wywołaniu została podana nazwa pliku do wy-
świetlenienia – jeżeli nie, wyświetla odpowied-
ni komunikat i kończy działanie. W przeciwnym
przypadku, przy pomocy funkcji
cvLoadIma-
ge()
plik zostaje wczytany do struktury
IplI-
mage
(powiemy o niej więcej za chwilę), służą-
cej do przechowywania informacji o obrazie.
Następnie, w celu wygładzenia obrazu, wywo-
łujemy funkcje
cvSmooth()
, podając, że chce-
my aby wygładzanie odbyło się przy użyciu me-
tody Gaussa, na obszarze 3x3 pikseli.
Następnie, przy wykorzystaniu funkcji
cvNamedWindow()
, należącej do HighGUI, two-
rzymy nowe okno o rozmiarze automatycznie
dopasowującym się do wyświetlanego obrazu
(
CV_WINDOW_AUTOSIZE
). W HighGUI, etykieta
wyświetlana na pasku tytułowym jest jednocze-
śnie nazwą okna, którą wykorzystujemy w doty-
czących jej wywołaniach – z tego względu nie
powinniśmy stosować w niej polskich znaków
diakrytycznych. Po utworzeniu okna, wyświetla-
my w nim obrazu, zapisany w strukturze
IplI-
mage,
przy użyciu funkcji
cvShowImage()
.
Program kończy pracę po naciśnięciu do-
wolnego klawisza przez użytkownika, co reali-
zujemy za pomocą funkcji
cvWaitKey()
, któ-
ra oczekuje na naciśnięcie klawisza, a następnie
zwraca jego kod. Przed zakończeniem działania
programu wywołujemy kolejno funkcje
cvRe-
leaseImage()
i
cvDestroyWindow()
, zwalnia-
jąc wykorzystywaną pamięć. Program kompilu-
jemy i linkujemy przy pomocy polecenia:
g++ hw.cpp -o hw -I /usr/local/
include/opencv -L /usr/local/lib -lm
-lcv -lhighgui -lcvaux
Jeżeli proces kompilacji zakończył się powo-
dzeniem, możesz uruchomić program przy po-
mocy polecenia:
./hw plik.jpeg
.
Listing 3.
Aplikacja wyświetlająca obraz z ka-
mery internetowej
#include <stdio.h>
#include <highgui.h>
int
main
()
{
IplImage
*
currentFrame
;
CvCapture
*
cam
;
char
key
;
cvNamedWindow
(
"Kamera"
,
CV_
WINDOW_AUTOSIZE
);
//rozpoczynamy pobieranie
obrazu z kamery
cam
=
cvCreateCameraCapture
(
0
);
while
(
1
)
//główna pętla
{
//odczytujemy następną
klatkę
currentFrame
=
cvQueryFrame
(
cam
);
//wyświetlamy klatkę
cvShowImage
(
"Kamera"
,
currentFrame
);
//odpowiednia ilość FPS
key
=
cvWaitKey
(
35
);
if
(
key
==
27
)
break
;
}
cvReleaseImage
(
&
currentFrame
);
cvReleaseCapture
(
&
cam
);
cvDestroyWindow
(
"Kamera"
);
return
0
;
}
Listing 4.
Sposób wywołania funkcji cvSave-
Image()
#include <highgui.h>
// Do struktury img został
wczytany odpowiedni obraz
// ptr wskazuje na ciąg znaków
– nazwę pliku docelowego
cvSaveImage
(
ptr
,
image
);
62
październik 2009
Programowanie
OpenCV – systemy wizyjne
63
www.lpmagazine.org
Programowanie
OpenCV – systemy wizyjne
Urządzenia wejściowe
Nasz pierwszy program działa bez zarzutów,
zajmijmy się więc bardziej zaawansowanymi
aspektami wykorzystania biblioteki OpenCV.
Najpierw jednak skonfigurujemy urządzenia,
za pomocą których będziemy rejestrować ob-
raz: kamery internetowe, karty frame grabber
lub kamery podłączone za pomocą interfejsu
FireWire.
Kamery internetowe
Jednym z najczęściej stosowanych w ama-
torskich systemach wizyjnych urządzeń są
zwykłe kamery internetowe. Ich niewąt-
pliwą zaletą jest łatwość instalacji i obsłu-
gi, a także niska cena. Przed zakupem ko-
niecznie zapoznaj się jednak ze stroną http:
//opencv.willowgarage.com/wiki/, na której
znajduje się lista urządzeń, które są obsługi-
wane przez bibliotekę OpenCV. Brak urządze-
nia na liście nie oznacza jednak, że nie będzie
ono wspierane przez OpenCV.
Jeżeli wybrałeś jedno z popularnych urzą-
dzeń, to po podłączeniu sprzętu do komputera
powienieneś już mieć możliwość rozpoczęcia
wykorzystania urządzenia w bibliotece OpenCV.
Działanie kamery internetowej możesz spraw-
dzić przy użyciu aplikacji camorama, dostępnej
na stronie http://camorama.fixedgear.org/. Jeżeli
możesz zobaczyć obraz z kamery, to znaczy, że
została ona poprawnie zainstalowana i jej wy-
korzystanie w bibliotece OpenCV nie powinno
sprawiać najmniejszych problemów.
Jeżeli moduł sterownika danej kamery nie
zostaje wczytany automatycznie, oznacza to, że
nie ma go w systemie. Należy w takim razie od-
czytać ID urządzenia przy pomocy polecenia
lsusb
, a następnie poszukać odpowiednich ste-
rowników w internecie (zakładając, że nie do-
starcza ich producent).
Dla większości popularnych urządzeń zna-
nych firm dostępnych jest wiele szczegółowych
opisów instalacji. Niekiedy jednak możesz na-
trafić na znaczne problemy, szczególnie w przy-
padku kamer z dalekiego wschodu, których pro-
ducenci nie dbają o wsparcie produktu przez
systemy spod znaku pingwina.
Kamery FireWire
Oprócz standardowych kamer internetowych,
wykorzystujących interfejs USB, dostępne są
bardziej zaawansowane urządzenia, zazwyczaj
korzystające z interfejsu FireWire.
W systemie Linux, obsługa urządzeń opar-
tych na tym interfejsie odbywa się przy po-
mocy API video4linux (v4l). Więcej informa-
cji na jego temat znajdziesz na stronie http:
//linux.bytesex.org/v4l2/.
Karty frame grabber
W zastosowaniach profesjonalnych, bardzo czę-
sto spotyka się karty frame grabber, służące do
konwertowania obrazu z postaci analogowej na
cyfrową. W przeciwieństwie do kamer interne-
towych, w których obraz konwertowany jest
przez urządzenie, karty frame grabber pozwala-
ją na uzyskanie znacznie lepszej jakości obrazu.
Wynika to z faktu, iż kamery analogowe dyspo-
nują znacznie lepszej jakości układami optycz-
nymi, zaś sygnał jest konwertowany przy użyciu
wyspecjalizowanych układów scalonych.
Obsługa kart frame grabber również odby-
wa się przy użyciu interfejsu video4linux. Dla
większości amatorskich zastosowań, wystarcza-
jące okaże się zastosowanie standardowej karty
telewizyjnej jako urządzenia przychwytującego
obraz z kamery.
Odtwarzanie plików wideo
Zanim przejdziemy do wyświetlania i transfor-
macji obrazu z kamery internetowej, napiszemy
program służący do odtwarzania plików wideo.
Kod programu znajduje się na Listingu 2.
Podobnie jak w pierwszym programie, zaczyna-
my od sprawdzenia liczby parametrów wywo-
łania. Następnie, otwieramy okno przy pomo-
cy funkcji
cvNamedWindow()
i otwieramy plik
wideo przy pomocy funkcji
cvCreateFileCap-
ture()
. Dostęp do pliku odbywa się poprzez
strukturę
CvCapture
, którą omówimy szerzej za
chwilę. Kolejne klatki pliku wideo pobieramy w
pętli przy użyciu funkcji
cvQueryFrame()
, za-
pisując je w już nam znanej strukturze
IplIma-
ge
, której zawartość wyświetlamy w oknie przy
użyciu funkcji
cvShowImage()
. Odpowiedni
odstęp czasowy pomiędzy poszczególnymi klat-
kami zapewniamy przy użyciu funkcji
cvWait-
Rysunek 2.
Skutek działania algorytmu Canny dla progów 100 oraz 150
Listing 5.
Funkcje wykorzystywane przy zapisywaniu plików wideo
CvVideoWriter
*
cvCreateVideoWriter
(
const
char
*
filename
,
// nazwa pliku docelowego
int
fourcc
,
// kod kodeku
double
fps
,
// liczba klatek na sekundę
CvSize
frame_size
,
// rozmiar klatki
int
is_color
=
1
);
// czy kolorowy?
int
cvWriteFrame
(
CvVideoWriter
*
writer
,
// wskaźnik do
struktury CvVideoWriter
const
IplImage
*
image
);
// obraz, który chcemy zapisać
void
cvReleaseVideoWriter
(
CvVideoWriter
**
writer
);
// wskaźnik na
wskaźnik do struktury CvVideoWriter
Listing 6.
Funkcje służąca do wydobywania krawędzi z obrazu
IplImage
*
doCanny
(
IplImage
*
in
,
double
lThresh
,
double
hThresh
)
{
if
(
in
->
nChannels
!=
1
)
return
NULL
;
IplImage
*
out
=
cvCreateImage
(
cvSize
(
in
->
width
,
in
->
height
),
IPL_
DEPTH_8U
,
1
);
cvCanny
(
in
,
out
,
lThresh
,
hThresh
);
return
out
;
}
62
październik 2009
Programowanie
OpenCV – systemy wizyjne
63
www.lpmagazine.org
Programowanie
OpenCV – systemy wizyjne
Key()
, jako parametr podając liczbę milisekund.
Odtwarzanie pliku wideo zostaje przerwane w
momencie wyświetlenia ostatniej klatki pliku
lub po naciśnięciu klawisza [ESC].
Zwróć uwagę, że każda pobrana klatka jest
przechowywana w strukturze
IplImage
, dzięki
czemu możemy ją poddać dowolnym transfor-
macjom, np. przy użyciu funkcji
cvSmooth()
.
Możemy również zapisywać wybrane klatki do
osobnych plików.
Jak zaraz się przekonasz, w bardzo podob-
ny sposób odbywa się odbieranie danych pocho-
dzących z kamery internetowej.
Obsługa kamery
Zajmiemy się teraz obsługą obrazu pochodzą-
cego z kamery internetowej. Wykorzystamy w
tym celu funkcje udostępniane przez HighGUI.
Kod przykładowego programu pobierające-
go obraz z kamery internetowej znajduje się na
Listingu 3. Z pewnością zauważasz duże podo-
bieństwo do aplikacji wyświetlającej zawartość
pliku wideo. W celu przechowywania informa-
cji o źródle obrazu wykorzystywana jest ta sama
struktura –
CvCapture
. Jedyną różnicę stanowi
wykorzystanie funkcji
cvCreateCameraCaptu-
re()
, powodującej rozpoczęcie pobierania ob-
razu z kamery, zamiast z pliku wideo. Jeżeli w
systemie obecna jest jedna kamera, to w wywo-
łaniu przekazujemy wartość 0, powodującą au-
tomatyczne wykrycie odpowiedniego urządze-
nia wejściowego. Reszta kodu jest taka sama jak
w przypadku programu z Listingu 2.
Zapisywanie obrazów i wideo
Bardzo przydatną funkcją biblioteki OpenCV
jest zapisywanie obrazów oraz ich sekwencji
w plikach. Pokażemy teraz, jak zastosować te
funkcje w naszych programach.
Zapisywanie obrazów
Zapisywanie pojedynczych obrazów jest bardzo
proste – wykorzystujemy w tym celu funkcję
cvSaveImage()
, przyjmującą dwa parametry
– wskaźnik do struktury
IplImage
oraz wskaź-
nik do ciągu znaków, określającego nazwę pli-
ku, w którym chcesz zapisać obraz. Przykład
zastosowania funkcji
cvSaveImage()
został
przedstawiony na Listingu 4.
Zapisywanie plików wideo
Zapisywanie sekwencji obrazów do pliku jest
nieco bardziej skomplikowane. Wykorzystuje-
my w tym celu funkcje, których sposób wywo-
łania został przedstawiony na Listingu 5.
Strukturą, która służy jako kontekst za-
pisu wideo jest
CvVideoWriter
. Nowy kon-
tekst zapisu pliku wideo tworzymy przy uży-
ciu funkcji
cvCreateVideoWriter()
. Przy jej
wywołaniu podajemy nazwę pliku w którym
chcemy zapisywać kolejne klatki (
filename
),
kod kodeku (
fourcc
), liczbę klatek na sekundę
(
fps
), rozmiar pojedynczej klatki (
frame_si-
ze
) oraz określamy, czy nagrywana sekwen-
cja klatek jest kolorowa (
is_color
). Szczegól-
nie duże znaczenie ma argument
fourcc
, prze-
chowujący kod kodeku – uzyskujemy go przy
użyciu makra
CV_FOURCC
, o składni przedsta-
wionej na Listingu 5. Jeżeli chcemy zapisać
plik wideo przy użyciu kodeku MJPG (Motion
JPG), jako argument fourcc podajmy
CV_FO-
URCC('M','J','P','G')
.
Zapis kolejnych klatek do pliku odbywa się
przy pomocy funkcji
cvWriteFrame()
. Po za-
kończeniu zapisywania, należy zamknąć dostęp
do pliku przy pomocy funkcji
cvReleaseVide-
oWriter()
.
Przekształcenia obrazu
W naszym pierwszym programie, przedsta-
wionym na Listingu 1, wykorzystaliśmy pro-
ste przekształcenie obrazu – wygładzanie meto-
dą Gaussa. Jest to bardzo przydatna funkcja, po-
zwalająca na usunięciu szumów z obrazu, mo-
gących powodować błędne rozpoznanie cech.
Biblioteka OpenCV zawiera bardzo wiele
funkcji, pozwalających na modyfikację obrazu.
Nie będziemy tu ich opisywać, ponieważ są pro-
ste w wykorzystaniu – wszelkie niezbędne in-
formacje znajdziesz na stronach OpenCV Wiki.
Są tam również dostępne opisy podstawowych
struktur, takich jak
CvMat
,
CvPoint
itp.
Detekcja krawędzi
Wykrywanie krawędzi jest jednym z podstawo-
wych problemów, których rozwiązanie jest kry-
tyczne z punktu widzenia systemów wizyjnych.
Istnieje wiele algorytmów, pozwalających na re-
alizację tej funkcji – my omówimy jeden z naj-
popularniejszych, zwany Canny (od nazwiska
twórcy).
Listing 6 zawiera przykładową funkcję, ko-
rzystającą z algorytmu Canny w celu wydobycia
krawędzi z obrazu (Rysunek 2). W celu prawi-
dłowego działania, przekazany obraz musi być
w skali szarości – odpowiednią konwersję pale-
ty kolorów możesz wykonać przy pomocy funk-
cji
cvCvtColor()
, której sposób zastosowania
został opisany na OpenCV Wiki.
Co dalej?
Jeżeli po przeczytaniu tego artykułu zaintereso-
wała Cię tematyka przekształceń i analizy obra-
zów przy wykorzystaniu biblioteki OpenCV, to
bardzo wiele ciekawych informacji znajdziesz
na stronach wymienionych w ramce W Sieci.
Szczególnie bogate w informacje są strony Wiki
projektu OpenCV.
Świadome wykorzystanie systemów wizyj-
nych wymaga znajomości specyficznych roz-
wiązań, stosowanych w tej dziedzinie. Jeże-
li chciałbyś zapoznać się z przekształceniami
obrazu od strony teoretycznej, to gorąco pole-
cam Ci zapoznanie się z literaturą z tej dziedzi-
ny. Trudno tu wskazać najlepsze tytuły, bowiem
większość z nich nie została przetłumaczona na
język polski.
Podsumowanie
Tym sposobem dotarliśmy do końca artykułu.
Mam nadzieję, że przekonałem Cię iż syste-
my wizyjne oraz techniki przetwarzania i trans-
formacji obrazu mają bardzo duże znaczenie w
wielu dziedzinach. Własnoręcznie wykorzysta-
łeś bibliotekę OpenCV w celu realizacji czę-
ści z nich.
Nie traktuj tego artykułu jako pełnego
wprowadzenia do tematyki systemów wizyj-
nych – jest to bardzo szeroka dziedzina, w któ-
rej wiele trendów (szczególnie w zakresie wy-
korzystywanego sprzętu) ulega szybkim zmia-
nom. Dużą popularność zyskują obecnie sys-
temy wizyjne budowane w oparciu o układy
FPGA (ang. Field Programmable Gate Array)
– pozwalające na bardzo szybką realizację na-
wet bardzo złożonych algorytmów. Opis ich za-
stosowania znacznie wykracza jednak poza te-
matykę tego artykułu.
Autor interesuje się bezpieczeństwem sys-
temów informatycznych, programowaniem,
elektroniką, muzyką rockową, architekturą
mikroprocesorów oraz zastosowaniem Li-
nuksa w systemach wbudowanych.
Kontakt z autorem: rkulaga89@gmail.com
O autorze
• Strona projektu OpenCV – http://sourceforge.net/projects/opencvlibrary/
• Wiki OpenCV – http://opencv.willowgarage.com/wiki/
• Strona projektu video4linux – http://linux.bytesex.org/v4l2/
• Strona programu camorama – http://camorama.fixedgear.org/
• Prosty program do detekcji twarzy, korzystający z Haar – http://nashruddin.com/
OpenCV_Face_Detection
W Sieci