OpenCV

From ImageWiki

(Difference between revisions)
Jump to: navigation, search
Line 39: Line 39:
== Eksempel 1 ==
== Eksempel 1 ==
-
Det frste 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_Eksperimentarium_2006#The_SVN_Repository|kursets SVN]] under ''Examples/opencv/Eksempel1'' og bestr af filen ''eksempel1.cc'' og en tilhrende ''Makefile''.
+
Det frste 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 [[Robot_Eksperimentarium_2006#The_SVN_Repository|SVN]] under ''Examples/opencv/Eksempel1'' og bestr af filen ''eksempel1.cc'' og en tilhrende ''Makefile''.
  #include "highgui.h"
  #include "highgui.h"
Line 91: Line 91:
Det nste eksempel er en simpel udvidelse af Eksempel 1. Her konverteres det farvebillede kameraet returnerer til et grtone billede, hvor der findes kanter som vises. Dette fortstter indtil brugeren trykker p en vilkrlig tast, hvorefter det sidst fundne kantbillede gemmes p disken i png format.
Det nste eksempel er en simpel udvidelse af Eksempel 1. Her konverteres det farvebillede kameraet returnerer til et grtone billede, hvor der findes kanter som vises. Dette fortstter indtil brugeren trykker p en vilkrlig 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.
Udover de ekstra funktionskald viser eksemplet ogs hvorledes nye billeder allokeres og deallokeres.
-
Som tidligere kan koden findes i [[Robot_Eksperimentarium_2006#The_SVN_Repository|kursets SVN]] under ''Examples/opencv/Eksempel2''.
+
Som tidligere kan koden findes i Robot Eksperimentariums [[Robot_Eksperimentarium_2006#The_SVN_Repository|SVN]] under ''Examples/opencv/Eksempel2''.
  #include "cxcore.h"
  #include "cxcore.h"

Revision as of 13:58, 8 August 2006

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