OpenCV

From ImageWiki

(Difference between revisions)
Jump to: navigation, search
m
Line 1: Line 1:
-
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 [http://www.intel.com/technology/computing/opencv/index.htm her]. Projektet har desuden en god [http://opencvlibrary.sourceforge.net/ wiki].
+
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 [http://www.intel.com/technology/computing/opencv/index.htm her]. Projektet har desuden en god [http://opencvlibrary.sourceforge.net/ 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.
+
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.
== Strukturen af OpenCV ==
== Strukturen af OpenCV ==
-
OpenCV består af tre dele
+
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.
+
* '''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.
+
* '''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.
+
* '''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? ==
== 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".
+
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
+
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
  pkg-config --cflags opencv
-
udskriver de argumenter der skal gives til oversætteren for at den kan finde OpenCV, mens kommandoen
+
udskriver de argumenter der skal gives til overs?tteren for at den kan finde OpenCV, mens kommandoen
  pkg-config --libs opencv
  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.
+
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
  # Compile and link flags
-
  CXX      =  g++
+
  CXX      =  g
  CXXFLAGS = `pkg-config opencv --cflags` -Wall
  CXXFLAGS = `pkg-config opencv --cflags` -Wall
  LIBS    = `pkg-config opencv --libs`
  LIBS    = `pkg-config opencv --libs`
Line 39: Line 39:
== Eksempel 1 ==
== 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 [[Robot_Eksperimentarium_2006#The_SVN_Repository|SVN]] under ''Examples/opencv/Eksempel1'' og består af filen ''eksempel1.cc'' og en tilhørende ''Makefile''.
+
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 [[Robot_Eksperimentarium_2006#The_SVN_Repository|SVN]] under ''Examples/opencv/Eksempel1'' og best?r af filen ''eksempel1.cc'' og en tilh?rende ''Makefile''.
  #include "highgui.h"
  #include "highgui.h"
Line 60: Line 60:
     // Clean up
     // Clean up
     cvDestroyAllWindows();
     cvDestroyAllWindows();
-
     cvReleaseCapture(&cam);
+
     cvReleaseCapture(
-
+
-
    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 [[Robot_Eksperimentarium_2006#The_SVN_Repository|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 [[user:Hauberg|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 farvebilledet ''BGR'' tilgås:
+
-
// Overskriver den blå værdi af BGR(x,y) med den tilsvarende røde værdi
+
-
int red = RED(BGR, x, y);
+
-
BLUE(BGR, x, y) = red;
+
-
Det er dog meget en smagssag om disse makroer gør koden kønnere. Disse makroer findes i filen ''index.h'' i "Robot Eksperimentariums" [[Robot_Eksperimentarium_2006#The_SVN_Repository|SVN]] under ''src''.
+
-
 
+
-
== 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.
+
-
 
+
-
== Introduktion til OpenCV==
+
-
Her er en glimrende introduktion til den mest grundlæggende brug af opencv, med mange og gode eksempler:
+
-
http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.html
+

Revision as of 17:49, 17 April 2007

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.

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(
Personal tools