background image

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?

background image

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

background image

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

;

 

}

background image

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

);

background 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

;

 

}

background image

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