OpenCV

From ImageWiki

Revision as of 13:58, 8 August 2006 by Hauberg (Talk | contribs)
Jump to: navigation, search

Denne side giver en bl�d introduktion til OpenCV, som er et kraftigt bibliotek til billedbehandling og Computer Vision udviklet i C. OpenCV's hjemmeside kan ses her. Projektet har desuden en god wiki.

Generelt er OpenCV yderst veldokumenteret, s� denne side giver kun et par simple eksempler p� anvendelse. Et problem ved OpenCV's dokumentation er dog at der er s� meget af den, hvilket kan g�re det hele noget uoverskueligt. Man skal derfor vide hvad man leder efter -- men bare rolig, det l�rer man med tiden.

Contents

Strukturen af OpenCV

OpenCV best�r af tre dele

  • cxcore stiller diverse basale strukturer til r�dighed. Dette inkluderer strukturer til billeder, matricer, punkter, o.lign. Desuden indeholder cxcore basale grafiske funktioner, s� som tegning af linier, cirkler, firkanter, osv.
  • cv indeholder funktioner til billedbehandling, Computer Vision og m�nstergenkendelse. Det vil sige funktioner til kantdetektion, kamerakalibrering, beregning af motion flow, klyngeanalyse og s� videre.
  • highgui indeholder funktioner til opbygning af simple grafiske brugergr�nseflader og til indl�sning af billeder. Dvs. at highgui prim�rt bruges til at hente billeder (fra kamera og filer) og derefter vise dem.

Hvordan benyttes OpenCV p� Linux?

En af OpenCV's styrker er at det er let at benytte. Hver af de tre dele af OpenCV stiller en header-fil til r�dighed der blot skal inkluderes i dit C/C++ program. Dvs. f�lgende tre header-filer er interessante: "cxcore.h", "cv.h" og "highgui.h".

For at overs�tte programmer der benytter OpenCV, benyttes programmet pkg-config. Dette program fort�ller blot hvilke argumenter der skal gives til overs�tteren for at OpenCV kan benyttes. Kommandoen

pkg-config --cflags opencv

udskriver de argumenter der skal gives til overs�tteren for at den kan finde OpenCV, mens kommandoen

pkg-config --libs opencv

udskriver de argumenter der skal gives til overs�tteren for at den kan linke til OpenCV. Dette g�r det yderst nemt at skrive en passende Makefile. Her gives et mindre eksempel, som du selv m� tilpasse til dit eget projekt.

# Compile and link flags
CXX      =  g++
CXXFLAGS = `pkg-config opencv --cflags` -Wall
LIBS     = `pkg-config opencv --libs`

# Name of executable
EXECUTABLE = myprogram

# Files
SOURCES = myprogram.cc myauxilaryfunction.cc
OBJECTS = $(patsubst %.cc, %.o, $(SOURCES))

# Linking
all: $(OBJECTS)
	$(CXX) $(LIBS) $(OBJECTS) -o $(EXECUTABLE)

# Compilation
%.o : %.cc
	$(CXX) $(CXXFLAGS) -c $^

Eksempel 1

Det f�rste eksempel vi ser p� tager billeder fra et kamera og viser dem i et vindue. Det er formentlig det mest simple og alligevel nyttige program der kan skrives i OpenCV. Programmet kan findes i Robot Eksperimentariums SVN under Examples/opencv/Eksempel1 og best�r af filen eksempel1.cc og en tilh�rende Makefile.

#include "highgui.h"

int main() 
{
    // Get an OpenCV camera handle
    CvCapture *cam = cvCaptureFromCAM(-1);

    // Initialise the GUI
    const char *window = "Eksempel 1";
    cvNamedWindow(window, CV_WINDOW_AUTOSIZE);

    // The main loop
    while (cvWaitKey(4) == -1) {
        IplImage *im = cvQueryFrame(cam);
        cvShowImage(window, im);
    }

    // Clean up
    cvDestroyAllWindows();
    cvReleaseCapture(&cam);

    return 0;
}

Den tilh�rende Makefile ser s�ledes ud

# Compile and link flags
CXX      =  g++
CXXFLAGS = `pkg-config opencv --cflags` -Wall
LIBS     = `pkg-config opencv --libs`

# Name of executable
EXECUTABLE = eksempel1

# Files
SOURCES = eksempel1.cc
OBJECTS = $(patsubst %.cc, %.o, $(SOURCES))

# Linking
all: $(OBJECTS)
	$(CXX) $(LIBS) $(OBJECTS) -o $(EXECUTABLE)

# Compilation
%.o : %.cc
	$(CXX) $(CXXFLAGS) -c $^

Som det ses er programmet ganske simpelt. Pr�v at overs�tte og k�re programmet. Husk at forbinde et kamera til maskinen f�r programmet k�res, ellers virker det ikke. N�r programmet k�res afsluttes det ved at trykke p� en vilk�rlig tast -- i denne situation returnerer cvWaitKey ASCII koden for den trykkede tast, hvilket er forskellig fra -1.

Eksempel 2

Det n�ste eksempel er en simpel udvidelse af Eksempel 1. Her konverteres det farvebillede kameraet returnerer til et gr�tone billede, hvor der findes kanter som vises. Dette forts�tter indtil brugeren trykker p� en vilk�rlig tast, hvorefter det sidst fundne kantbillede gemmes p� disken i png format. Udover de ekstra funktionskald viser eksemplet ogs� hvorledes nye billeder allokeres og deallokeres. Som tidligere kan koden findes i Robot Eksperimentariums SVN under Examples/opencv/Eksempel2.

#include "cxcore.h"
#include "cv.h"
#include "highgui.h"

int main() 
{
    // Get an OpenCV camera handle
    CvCapture *cam = cvCaptureFromCAM(-1);

    // Initialise the GUI
    const char *window = "Eksempel 2";
    cvNamedWindow(window, CV_WINDOW_AUTOSIZE);

    // Allocate an 640x480 gray scale image for the gray scale image and 
    // the edge image.
    // This assumes that the camera returns 640x480 images.
    const CvSize size = cvSize(640, 480);
    IplImage *gray  = cvCreateImage(size, IPL_DEPTH_8U, 1);
    IplImage *edges = cvCreateImage(size, IPL_DEPTH_8U, 1);

    // The main loop
    while (cvWaitKey(4) == -1) {
        IplImage *im = cvQueryFrame(cam);
        cvCvtColor(im, gray, CV_BGR2GRAY); // Convert color image to gray scale
        cvCanny(gray, edges, 1000, 750, 5); // Find edges
        cvShowImage(window, edges);
    }
    cvSaveImage("edges.png", edges); // Save the last edge image

    // Clean up
    cvDestroyAllWindows();
    cvReleaseCapture(&cam);
    cvReleaseImage(&gray);
    cvReleaseImage(&edges);

    return 0;
}

Den tilh�rende Makefile er en triviel �ndring af den fra Eksempel 1, hvorfor den ikke vises her.

Tips og tricks

Her er en samling af diverse r�d, der kan v�re relevante under udvikling af programmer i OpenCV.

BGR?

Der er v�rd at bem�rke at OpenCV benytter BGR fremfor RGB. Dvs. at en pixels farve opbevares i r�kkef�lgen Bl�, Gr�n, R�d, i mods�tning til traditionelt hvor R�d, Gr�n, Bl� r�kkef�lgen benyttes. Dette har kun sj�ldent betydning, men n�r der arbejdes med farvetransformationer o.lign. b�r dette holdes in mente.

Tilgang til pixels

En af de ting der efter min mening kan v�re lidt besv�rligt er at l�se og skrive enkelte pixels i billeder. Denne generelle teknik for billeder af forskellig type beskrives ganske godt i OpenCV's FAQ (XXX: link til denne). Typisk arbejdes dog med enten gr�tone eller RGB billeder hvor hver pixel repr�senteres med 8 bit. Her benytter jeg ofte f�lgende simple makroer:

#define GRAY(IMAGE, X, Y) \
   ((uchar*)((IMAGE)->imageData  + (IMAGE)->widthStep*(Y)))[X]
#define RED(IMAGE, X, Y) \
   ((uchar*)((IMAGE)->imageData + (IMAGE)->widthStep*(Y)))[(X)*3+2]
#define GREEN(IMAGE, X, Y) \
   ((uchar*)((IMAGE)->imageData + (IMAGE)->widthStep*(Y)))[(X)*3+1]
#define BLUE(IMAGE, X, Y) \
   ((uchar*)((IMAGE)->imageData + (IMAGE)->widthStep*(Y)))[(X)*3]

Herefter er det muligt at tilg� pixel (x, y) i gr�tone billedet I p� f�lgende m�de:

// S�tter I(x,y) = I(x,y) + 1
int tmp = GRAY(I, x, y);
GRAY(I, x, y) = tmp + 1;

Tilsvarende kan de enkelte elementer af pixels i RGB billedet RGB tilg�s:

// Overskriver den bl� v�rdi af RGB(x,y) med den tilsvarende r�de v�rdi
int red = RED(RGB, x, y);
BLUE(RGB, x, y) = red;

Det er dog meget en smagssag om disse makroer g�r koden k�nnere.

Propaganda

En af �rsagerne til at OpenCV benyttes er at det er frit programmel. Det betyder at vi har adgang til alle dele af kildekoden og vi har ret til �ndre i denne hvis vi har behov for dette. Dette betyder ogs� at det uden problemer er muligt at hente OpenCV p� nettet og installere det p� egen maskine.

Personal tools