Playing with Qt and OpenCv

In this project I’m going to capture the image from a USB camera, using openCV, and showing all in a QT window.

Let’s started:

The first thing that we have to do, once we have created the project, is to edit the *.pro file, and add our OpenCv paths.

QT       += core gui
 TARGET = untitled
 TEMPLATE = app
 INCLUDEPATH += /home/opencv_source/trunk/opencv/include/opencv
 LIBS += -L/home/opencv_source/trunk/opencv/release/lib -lml -lcvaux -lhighgui -lcv -lcxcore
 SOURCES += capture.cpp\
 main.cpp\
 mainwindow.cpp

HEADERS  +=  capture.h\
 mainwindow.h

FORMS    += mainwindow.ui

I had a problem,  “undefined recerence to vtable” ,that I could fix placing on top capture.h and capture.cpp files.

Once we have ready our environment I’ll explain the content of the files:

– capture: Is the most important file, this class runs in other thread that the GUI, and all that it does is emitting a signal when has a new IplImage from the cam.

Create a new Thread in QT is so easy, all that we have to do is derivate from QThread and implement the virtual method void run()

class Captura : public QThread
 {
 Q_OBJECT              //We need this macro for use Signals mechanism
 public:
 void run();
 signals:
 void newImgAvailable(QImage*);
 };

void Capture::run()

{
 CvCapture * cap = cvCaptureFromCAM(0);
 if(cap == NULL)
 {
 cout << "There were troubles .. " << endl;
 }
 else
 {
 cout << "Ok" << endl;
 IplImage* imgDisplay;
 while(1){
 imgDisplay = cvQueryFrame(cap);
 QImage* image = IplImage2QImage(imgDisplay);
 emit newImgAvailable(image);
 QThread::msleep(10);
 }
 }
 }
<pre>

– In mainwindow we are going to create the instance of capture, start it, and connect with our own slots wich will set the image in a QLabel using setPixMap property.

The header:

class MainWindow : public QMainWindow
 {
 Q_OBJECT

public:
 explicit MainWindow(QWidget *parent = 0);
 ~MainWindow();

public slots:
 void getImg(QImage*);
 private:
 Ui::MainWindow *ui;
 };

and the cpp:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),  ui(new Ui::MainWindow)
 {
 ui->setupUi(this);
 Capture* cap = new Capture();               //Create the Thread wich deals with opencv
 connect(cap, SIGNAL(newImgAvailable(QImage*)),this, SLOT(getImg(QImage*)));
 cap->start();  //starting the thread...
 }

void MainWindow::getImg(QImage* img)   //This code will update the image
 {
 ui->label->setPixmap(QPixmap::fromImage(*img));
 delete img;
 }

To avoid memory leaks we have to bear in mind that getImg has to delete the QImage.

Important: We mustn’t release the IplImage* in the loop, because this  is made internally and it would be a mistake

Anuncios

1 comentario

Working with Emdebian

Installing EmDebian on a USB drive:

  1. The first thing that we should do is formating the USB drive (ext2 in my case)
  2. now we are going to mount the USB in /media/grip folder.
  3. Obtaining lenny from the repositories..
  4. We are going to make a chroot
  5. Before installing a new kernel, I had to create a new file /etc/kernel-img.conf and pasting this text (In the guide this step wasn’t mandatory, but it was for me)
  6. Installing grub.
  7. Beware We must install grub on /dev/sdb not in /dev/sdbX
  8. Exiting from chroot
  9. In my case, I had to fix grub: I edited menu.lst file, and I change the script to start in hd0,0 insted hd1,0
  10. Change password for root user with passwd, and then add a user with adduser command.

mkdir /media/grip/
mount /dev/sdb1 /media/grip/
sudo debootstrap lenny /media/grip/ http://www.emdebian.org/grip/
cd /media/grip/
mount -o bind /dev/ dev/
mount -o bind /proc proc/
chroot . /bin/bash
aptitude update
nano /etc/kernel-img.conf
do_symlinks = yes
relative_links = yes
do_bootloader = no
do_bootfloppy = no
do_initrd = yes
link_in_boot = no
postinst_hook = update-grub
postrm_hook = update-grub

aptitude install linux-image-2.6.28-1-686 initramfs-tools
aptitude install what-you-want
aptitude install grub
grub-install /dev/sdb
update-grub
exit
umount dev/
umount proc/
cd ../
umount grip/

This information is based on  http://gionn.net/howto-install-emdebian-grip-deboostrap

Deja un comentario

Porque no emplear cvSet2D. Why we shouldn’t use cvSet2D

Trás implementar la clase para el cambio de espacio de color he querido comprobar cuanta diferencia había entre los distintos métodos:

JETMAP: ha tardado: 9.7 milisegundos
JETMAPFAST: ha tardado: 1.555 milisegundos
HsvMap: ha tardado: 9.702 milisegundos
HsvMapFast: ha tardado: 1.556 milisegundos
HotMap: ha tardado: 9.735 milisegundos
HotMapFast: ha tardado: 1.555 milisegundos
CoolMap: ha tardado: 9.727 milisegundos
CoolMapFast: ha tardado: 1.556 milisegundos
SpringMap: ha tardado: 9.726 milisegundos
SpringMapFast: ha tardado: 1.569 milisegundos
SummerMap: ha tardado: 9.672 milisegundos
SummerMapFast: ha tardado: 1.568 milisegundos
AutumnMap: ha tardado: 9.789 milisegundos
AutumnMapFast: ha tardado: 1.554 milisegundos
WinterMap: ha tardado: 10.007 milisegundos
WinterMapFast: ha tardado: 1.555 milisegundos
GrayMap: ha tardado: 9.924 milisegundos
GrayMapFast: ha tardado: 1.554 milisegundos
BoneMap: ha tardado: 9.714 milisegundos
BoneMapFast: ha tardado: 1.555 milisegundos
CopperMap: ha tardado: 9.961 milisegundos
CopperMapFast: ha tardado: 1.564 milisegundos
PinkMap: ha tardado: 9.681 milisegundos
PinkMapFast: ha tardado: 1.556 milisegundos
LinesMap: ha tardado: 9.96 milisegundos
LinesMapFast: ha tardado: 1.568 milisegundos

Trás ver la evidente ventaja, a continuación expongo como sería el método rápido:

int alto    = entrada->height;
int ancho   = entrada->width;
int step    = entrada->widthStep;
int canales = entrada->nChannels;
uchar* data      = (uchar *)entrada->imageData;

for(int i=0; i < alto;i++)
for(int j=0; j <ancho;j++)
for(int k=0; k < canales;k++)
data[i*step+j*canales+k]= pink[data[i*step+j*canales+k]*3 +2-k];

After develop the class for space color changes, I wanted check the differences between both methods:

JETMAP: takes: 9.7 miliseconds
JETMAPFAST: takes: 1.555 miliseconds
HsvMap: takes: 9.702 miliseconds
HsvMapFast: takes: 1.556 miliseconds
HotMap: takes: 9.735 miliseconds
HotMapFast: takes: 1.555 miliseconds
CoolMap: takes: 9.727 miliseconds
CoolMapFast: takes: 1.556 miliseconds
SpringMap: takes: 9.726 miliseconds
SpringMapFast: takes: 1.569 miliseconds
SummerMap: takes: 9.672 miliseconds
SummerMapFast: takes: 1.568 miliseconds
AutumnMap: takes: 9.789 miliseconds
AutumnMapFast: takes: 1.554 miliseconds
WinterMap: takes: 10.007 miliseconds
WinterMapFast: takes: 1.555 miliseconds
GrayMap: takes: 9.924 miliseconds
GrayMapFast: takes: 1.554 miliseconds
BoneMap: takes: 9.714 miliseconds
BoneMapFast: takes: 1.555 miliseconds
CopperMap: takes: 9.961 miliseconds
CopperMapFast: takes: 1.564 miliseconds
PinkMap: takes: 9.681 miliseconds
PinkMapFast: takes: 1.556 miliseconds
LinesMap: takes: 9.96 miliseconds
LinesMapFast: takes: 1.568 miliseconds

Once we see the advantages of using pointers, I write the code for the fastest way:

int alto    = entrada->height;
int ancho   = entrada->width;
int step    = entrada->widthStep;
int canales = entrada->nChannels;
uchar* data      = (uchar *)entrada->imageData;

for(int i=0; i < alto;i++)
for(int j=0; j <ancho;j++)
for(int k=0; k < canales;k++)
data[i*step+j*canales+k]= pink[data[i*step+j*canales+k]*3 +2-k];

1 comentario

Mapas de Color en OpenCv

Recientemente he necesitado la obtención de imágenes en mapas de color distintos al RGB, como no he encontrado dentro de la librería OpenCv funciones para ello he decidido construirlas.

A continuación una imágen en las que se ve la imagen original y algunos de los mapas de color aplicados:

ColorMaps

Proveo dos funciones distintas para cada mapa, en la primera empleo la función cvSet2D para realizar el cambio, mientras que en las que denomino Fast empleo punteros. El rendimiento de las funciones Fast es aproximadamente 6 veces más rápido que las otras.

Se trata de funciones estáticas que están definidias en tres archivos:

  1. colormaps.h:  Contiene los arrays con los factores de conversión
  2. colorspace.h: Definición de las funciones.
  3. colorspace.cpp: Implementación de las mismas.

Deja un comentario

Reparar Kernel dañados o borrados

Por accidente he borrado el kernel que tenia instalado.  A continuación detallo la solución para agregar un kernel desde un Live CD , se basa en acceder directamente a nuestra instalación:

 

Lo primero de todo, es montar la particiónen la que tenemos el Sistema Operativo, en micaso el primer disco duro:

$ sudo mount /dev/sda1 /mnt

A continuación se montan los siguientes dispositivos:
$ sudo mount --bind /dev /mnt/dev
$ sudo mount --bind /proc /mnt/proc

Ahora para acceder a nuestro sistema de fichero lo hacemos mediante chroot:

$ sudo chroot /mnt

y finalmente restauramos el GRUB

# grub-install --recheck /dev/sda

Uno de los problemas que he tenido es que lo intente desde un CD con la versión 8.10 que usa Grub, mientras en mi partición tengo GRUB2, tener esto en cuenta.

, ,

Deja un comentario

Protegido: Supresión de fondos

Este contenido está protegido por contraseña. Para verlo introduce tu contraseña a continuación:

1 comentario

Sistema de detección de clases de objetos utilizando modelos de partes deformables

En este proyecto se ha implementado un detector de clases genéricas de objetos utilizando una aproximación piramidal

y detectores de gradientes orientados (HOG).

Está desarrollado en C++ y hace uso de modelos ya entrenados existentes en workspaces de MATLAB.

A continuación unas imágenes del detector funcionando y un video.

Deja un comentario