CUDABOF unter Ubuntu 10.04 32 bit

There was a time, when I shared a blog. This post was written by Stephan. See all blogpost from him or stalk him on github.


Das Open Source Projekt OpenVIDIA : Parallel GPU Computer Vision beschäftigt sich mit Nvidias CUDA-Technology und Computer Vision. U.a gibt es die Beispielanwendung “CUDABOF” (CUDA Bayesian Real-time Optical Flow), in der es um Bewegungserkennung geht (mehr über die Theorie könnt ihr hier erfahren). Die CUDA-GPU soll dabei die Bewegungsberechnungen unterstützen.

Das Programm konnte mit der gegebenen Makefile aber nicht erfolgreich kompiliert werden. Darum gibt es hier eine angepasste Makefile für ein 32Bit System:

``` ###

Configuration

###

NVIDIA_INSTAL_DIR=$(HOME)/NVIDIA_GPU_Computing_SDK/C CUDA_BASE=/usr/local/cuda

###

You shouldn’t have to change down from here

###

INCLUDE:= -I.
-I/usr/local/cuda/include
-I$(NVIDIA_INSTAL_DIR)/common/inc/
-I$(CUDA_BASE)/include

CXXFLAGS= -fno-strict-aliasing -DUNIX -O0 -ggdb $(shell pkg-config –cflags opencv)

LDFLAGS= -L$(NVIDIA_INSTAL_DIR)/lib
-L$(NVIDIA_INSTAL_DIR)/common/lib
-L$(NVIDIA_INSTAL_DIR)
-L$(CUDA_BASE)/lib
-lcutil_i386 -lcudart -lGL -lGLU -lglut -lGLEW
$(shell pkg-config –libs opencv) \

NVCCFLAGS = –compile –host-compilation ‘C++’
–compiler-options -fno-strict-aliasing
–compiler-options -ggdb $(INCLUDE)
–compiler-bindir=/usr/bin/gcc-4.3

EXEC = test01
test02_spatialDerivs
test03_gaussianPyramid
test04_opticalFlow

all: $(EXEC)

VERBOSITY:=@ ECHO_COMPILING=@echo “compiling $@”

###### #

COMPILATION OF OBJECT FILES

# ######

%.o: %.cu %.hpp CUDABOF.hpp $(ECHO_COMPILING) $(VERBOSITY)nvcc $(NVCCFLAGS) $<

%.o: %.cpp *.hpp $(ECHO_COMPILING) $(VERBOSITY)g++ -c $< $(INCLUDE) $(CXXFLAGS)

###### #

TESTS

# ######

TEST_BUILD_RULE= $(VERBOSITY)g++ -fPIC -o $@ $^ $(LDFLAGS)

test01: test01_kernel.o test01.o Utils.o MathUtils.o $(ECHO_COMPILING) $(TEST_BUILD_RULE)

test02_spatialDerivs: test02_spatialDerivs.o Utils.o MathUtils.o BayesianOpticalFlowKernels.o $(ECHO_COMPILING) $(TEST_BUILD_RULE)

test03_gaussianPyramid: test03_gaussianPyramid.o Utils.o MathUtils.o GaussianPyramidKernel.o $(ECHO_COMPILING) $(TEST_BUILD_RULE)

test04_opticalFlow: test04_opticalFlow.o Utils.o MathUtils.o OpticalFlow.o BayesianOpticalFlowKernels.o GaussianPyramidKernel.o $(ECHO_COMPILING) $(TEST_BUILD_RULE)

###### #

TESTS

# ###### clean: rm -f *.o $(EXEC) ``

Anmerkung: Falls ihr bei der CUDA-Installation abweichende Pfade genommen habt (vor allem beim CUDA-SDK, das standardmäßig im Home-Ordner des Nutzers installiert wird), müsst ihr die Pfade natürlich anpassen (über die Variablen NVIDIA_INSTAL_DIR und CUDA_BASE am Anfang der Datei).

Folgende Bibliotheken/Pakete sind zudem nötig:

  1. OpenCV: libcv-dev
  2. libhighgui-dev
  3. Compiler g++ und gcc in Version 4.3 (mit Version 4.4 lässt sich dieses Programm und die Nvidia-Bespiele zu Cuda nicht kompilieren)

Nach dem ihr “make” erfolgreich ausgeführt habt, könnt ihr folgende Programme in der Konsole ausführen:

“test04_opticalFlow” verwendet bei der Bewegungsvorhersage die GPU und erzeugt auf meinem Laptop so nur 80 Prozent CPU-Auslastung (zum Start des Programms muss eine Webcam/Videokamera angeschlossen sein, die von OpenCV erkannt wird).

Bei Problemen mit der neuen Datei hilft es vielleicht, die originale Makefile mit der angepassten zu vergleichen.

Viele Grüße

Stephan

Cuda SDK Code-Beispiele unter Ubuntu 10.04 32bit kompilieren

There was a time, when I shared a blog. This post was written by Stephan. See all blogpost from him or stalk him on github.


Heute möchte ich zeigen, wie man die Cuda-Code Examples unter Ubuntu 10.04 erfolgreich kompilieren kann. CUDA funtkioniert nur mit unterstützten Grafikkarten ab Geforce 8. Zuerst ladet ihr euch die benötigten Dateien von der Nvidia Homepage herunter:

  1. CUDA Toolkit for Ubuntu Linux 9.04 32bit
  2. Grafiktreiber: Developer Drivers for Linux (195.36.15) 32bit (falls nicht bereits vorhanden)
  3. GPU Computing SDK code samples and more

Die heruntergeladenen .run-Dateien anschließend in der Konsole mit dem altbekannten sh-Befehl installieren. Bei der Installation werdet ihr nach einigen Installationspfaden gefragt. Bitte belasst es hier bei den vorgegebenen Standardwerten, wenn ihr nicht genau wisst, was ihr tut.

sudo sh devdriver_3.0_linux_32_195.36.15.run
sudo sh cudatoolkit_3.0_linux_32_ubuntu9.04.run
sh gpucomputingsdk_3.0_linux.run # nicht mit Root-Rechten ausführen

Dann öffnet ihr die Konsole und bearbeitet die Bashkonfigurationsdatei

sudo nano $HOME/.bashrc

Folgende Codezeilen müsst ihr an das Ende der Datei einfügen:

export CUDA_BIN="/usr/local/cuda/bin"
export PATH=$PATH:$CUDA_BIN
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib

Anschließend die Bash neuladen:

source $HOME/.bashrc

Und testen ob alles geklappt hat:

nvcc -V

Die Ausgabe in der Konsole sollte etwas so aussehen:

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2009 NVIDIA Corporation
Built on Fri_Feb_19_18:18:31_PST_2010
Cuda compilation tools, release 3.0, V0.2.1221

Nun müssen wir einen Symlink zur Cuda-Bibliothek setzen:

sudo ln -s /usr/lib/nvidia-current/libcuda.so /usr/lib/libcuda.so

Damit verhindern wir, das beim Kompilieren “libcuda” nicht gefunden wird.

Nun müssen wir noch gcc und g++ in der Version 4.3 installieren:

sudo aptitude install g++-4.3 gcc-4.3

und in der Datei “common.mk”, die ihr unter

cd $HOME/NVIDIA_GPU_Computing_SDK/C/common

findet, sucht ihr folgende Zeilen:

# architecture flag for nvcc and gcc compilers build
CUBIN_ARCH_FLAG :=
CXX_ARCH_FLAGS  :=
NVCCFLAGS       := --compiler-bindir=/usr/bin/gcc-4.4.3
LIB_ARCH        := $(OSARCH)

Nach eurer Bearbeitung müsste es dann so aussehen:

# architecture flag for nvcc and gcc compilers build
CUBIN_ARCH_FLAG :=
CXX_ARCH_FLAGS  :=
NVCCFLAGS       := --compiler-bindir=/usr/bin/gcc-4.3
LIB_ARCH        := $(OSARCH)

Ist alles erledigt, wechselt ihr in den Ordner der Cuda-Beispiele und startet die Kompilierung

cd $HOME/NVIDIA_GPU_Computing_SDK/C/
make

Die fertigen Programme findet ihr unter :

cd $HOME/NVIDIA_GPU_Computing_SDK/C/bin/linux/release

Viel Spaß dabei und ich hoffe, einigen etwas Arbeit erspart zu haben.

Gruß Stephan

Nutzung von cvCanny in OpenCV

There was a time, when I shared a blog. This post was written by Stephan. See all blogpost from him or stalk him on github.


Mit der Funktion cvCanny von OpenCV lassen sich Kanten in einem Bild erfassen. Hier ein Beispiel, wie man ein Bild auf der Festplatte erfolgreich mit cvCanny erfasst. Wichtig ist, dass das geladene Bild in einem Kanal vorliegt, also “grayscaled” ist. Dies erreicht man durch folgenden Aufruf, bei dem der zweite Parameter der Funktion cvLoadImage auf 0 gesetzt wird (weitere Infos hier).

 IplImage* in = cvLoadImage(argv[1],0);

Dann erzeugt man ein neues Bild (Variable out), das die gleiche Dimensionen wie das Eingangsbild (Variable in) besitzt (und natürlich auch nur einen Kanal). Mehr zur Funktion cvCreateImage gibt es hier.

IplImage* out = cvCreateImage(
            cvGetSize(in),
            IPL_DEPTH_8U,
            1
            );

Anschließend muss nur noch die cvCanny-Funktion aufgerufen werden, mit den Parametern kann man anschließend etwas “herumspielen”:

cvCanny(in, out, 0.3, 0.8);

//Bild darstellen
cvNamedWindow("Canny", CV_WINDOW_AUTOSIZE);
cvShowImage("Canny", out);

//ermöglicht, dass das Bild angezeigt wird, bis Taste gedrückt wird, da keine Schleife
cvWaitKey(0);

Enthält dein Eingangsbild mehrere Kanäle, wirst du beim Aufruf deines Programms folgende Fehlermeldung erhalten (kompilieren lässt es sich):

OpenCV ERROR: Unsupported format or combination of formats () in function cvCanny

Nachtrag:

Liest man Livebilder aus einer Kamera aus , benötigt man die Hilfe von cvCvtColor

//Kamera auslesen
CvCapture* capture;
capture = cvCreateCameraCapture(0); // 0 muss gegebenenfalls angepasst werden

//aktuelles Bild der Videokamera erhalten
IplImage* in = cvQueryFrame(capture);

//Graubild erzeugen
IplImage* out = cvCreateImage(
            cvGetSize(in),
            IPL_DEPTH_8U,
            1
            );

cvCvtColor(in, out, CV_BGR2GRAY);

//Graubild anzeigen
cvNamedWindow("Gray Image", CV_WINDOW_AUTOSIZE);
cvShowImage("Gray Image", out);

//ermöglicht, dass das Bild angezeigt wird, bis Taste gedrückt wird, da keine Schleife
cvWaitKey(0);

cvGetCaptureProperty von OpenCV unter Ubuntu nutzen

There was a time, when I shared a blog. This post was written by Stephan. See all blogpost from him or stalk him on github.


Nachdem ich bei der Einarbeitung in OpenCV einige Probleme hatte, mit Hilfe der Funktion cvGetCaptureProperty() die Eigenschaften des geöffneten Videos korrekt auszulesen, bin ich bei der Forensuche auf eine Lösung gekommen, die es zumindest ermöglicht, die Anzahl der Bilder des Videos korrekt auszulesen. Dazu müsst ihr in eurem Quellcode folgende Funktion hinzufügen:

#include "iostream";
#include "fstream";
#include "highgui.h"
#include "cv.h"

using namespace std;

int getAVIFrames(char * fname) {
char tempSize[4];
// Trying to open the video file
ifstream videoFile(fname, ios::in | ios::binary);
// Checking the availablity of the file
if (!videoFile) {
cout << "Couldn't open the input file " << fname << endl;
exit(1);
};
// get the number of frames
videoFile.seekg(0x30, ios::beg);
videoFile.read(tempSize, 4);
int frames = (unsigned char) tempSize[0] + 0x100 * (unsigned char) tempSize[1] + 0x10000 * (unsigned char) tempSize[2] + 0x1000000 * (unsigned char) tempSize[3];
videoFile.close();
return frames;
}

Nun könnt ihr durch Aufruf dieser Funtkion zumindest die Anzahl der Frames erhalten. Ein Aufruf in eurem Programmcode könnte zum Beispiel so aussehen:

int video_frames = getAVIFrames(argv[1]);

Beim Start des Programmes müsst ihr natürlich den Namen des Videos mit übergeben.

Alle anderen Ausleseversuche der folgenden Eigenschaften lieferten bei mir immer wieder nur 0:

printf("CV_CAP_PROP_POS_MSEC: %f\n",
cvGetCaptureProperty(capture, CV_CAP_PROP_POS_MSEC));
printf("CV_CAP_PROP_POS_FRAMES: % f\n",
cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES));
printf("CV_CAP_PROP_FRAME_WIDTH: %f\n",
cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH));
printf("CV_CAP_PROP_FRAME_HEIGHT: %f\n",
cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT));
printf("CV_CAP_PROP_FPS: %f\n",
cvGetCaptureProperty(capture, CV_CAP_PROP_FPS));
printf("CV_CAP_PROP_POS_AVI_RATIO: %f\n",
cvGetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO));
printf("CV_CAP_PROP_FRAME_COUNT: %f\n",
cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT));

Das als mögliche Fehlerquelle der verwendete Codec in Frage kommen könnte, kann ich nicht bestätigen. Ich habe mittels ffmpeg verschiedene Varianten des selben Videos angefertigt, jedoch ergab sich keine Besserung.

Das muss wohl ein Linuxproblem der neueren Versionen von OpenCV sein (und laut den Forenbeiträgen besteht es auch schon länger, weiteres hier, inklusive der hier geposteten Lösung aus dem O’Reilly Buch Learning OpenCV).

OpenCV in Netbeans und Ubuntu

There was a time, when I shared a blog. This post was written by Stephan. See all blogpost from him or stalk him on github.


Um die Open Source Computer Vision Library unter Netbeans 6.8 zu nutzen musst du folgendes einstellen:

Führst du nun folgenden Code aus und kompilierst ihn, sollte dein erstes OpenCV-Programm erfolgreich gestartet werden:

/*
* File:   main.cpp
* Author: stephan
*
* Created on 11. Mai 2010, 22:33
*/

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

int main(int argc, char** argv) {
IplImage* img = cvLoadImage("image.jpg"); // oder als Argument cvLoadImage(argv[1]);
cvNamedWindow("Example1", CV_WINDOW_AUTOSIZE);
cvShowImage("Example1", img);
cvWaitKey(0);
cvReleaseImage(&amp;img);
cvDestroyWindow("Example1");
};

In diesem Beispiel wird das Bild image.jpg in fest in den Quellcode eingebunden. Möchtest du Argumente bei Programmstart übergeben und per argv[] der Main-methode darauf zugreifen, kannst du dies über den Eigenschaftsdialog des Projektes in der Kategorie Run tun. Der Parameter dafür heißt Arguments. Im Quellcode enthält dann argv[1] den Wert image.jpg (siehe Bild 4)