Le module Image, votre nouvel ami

frogsspiffyΤεχνίτη Νοημοσύνη και Ρομποτική

18 Ιουλ 2012 (πριν από 4 χρόνια και 11 μήνες)

345 εμφανίσεις


Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
J a f a r  :  I n t r o d u c t i o n   a u   m o d u l e   I m a g e
Le module Image,
votre nouvel ami...

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
T h èm e s   a b o r d és

Problématique

La structure
IplImage

La classe
JfrImage

Le lien avec OpenCV

Petits exemples ...

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
P r o b l ém a t i q u e

Motivations :

Unification des structures images

Structure de donnée moderne/puissante

Fonctions d'accès et de traitements d'image bas
niveau déjà disponibles

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
P r o b l ém a t i q u e

L'existant :

Calife !

Structures de données obsolètes

Fonctions utilitaires disponibles

Fonctions de traitement d'image orientée vision
disponibles

Fonctions orientée robotiques disponibles

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
P r o b l ém a t i q u e

Le challenger :

OpenCV

Structure de données plus complète (en C)

Fonctions utilitaires disponibles

Fonctions de traitement d'image orientée vision
disponibles

Fonctions orientée robotique pratiquement
inexistantes

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
P r o b l ém a t i q u e

« Un gros schéma ...
JfrImage
IplImage
I/O Functions
Calife Functions
Image Processing
Basic image properties : 
 
­ Pixels data
 
­ Width/heigth infos
 
­ ...
Higher Level Properties :
 
­ ROI 
 
­ Ops
 
­ indice/sequenceInfo
 
­ pose
 
­ time
wrap
wrap
code 
changes
Reading/ Writing for files
Gradients / Filters / Morpho
Transforms / Contours
Histograms ...
Stereo / IPM 
Segs2D / Contours

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
P r o b l ém a t i q u e

... vaut mieux qu'un petit discours »

Création d'une classe
JfrImage
(C++)

Encapsulation de la structure
IplImage
utilisée
par OpenCV (C)

Réemploi au plus simple des fonctions OpenCV
« bas-niveau »

Réinjection du code Calife « haut-niveau » en le
modifiant

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
O p e n C V   e t   l a   s t r u c t u r e   I p l I m a g e

OpenCV

Librairie de fonctions relatives a la vision
développée initialement chez Intel

OpenSource

Très grande communauté (active)

Codes optimisés

Ne fonctionnent que sur des machines x86
(Windows/Linux) et PowerPC (MacOS X)

ou que sur lin et osx ????

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
O p e n C V   e t   l a   s t r u c t u r e   I p l I m a g e

IplImage


Structure employée par toutes les fonctions de
traitement d'image d'OpenCV

Paramètres importants :

Taille de l'image :
width
,
height

Nombre de plans chromatiques (
nChannels
)

Profondeur des pixels (
depth
) :

Le tableau de pixels :
imageData


Rembourrage sur la largeur :
widthStep

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
O p e n C V   e t   l a   s t r u c t u r e   I p l I m a g e

Précisions sur les paramètres

nChannels
: 1,2,3 ou 4. Mais les fonctions d'OpenCV ne
travaillent en général qu'avec 1 ou 3 plans.

Profondeur possibles :

unsigned 1-bits/8-bits/16-bits

signed 8-bits/16-bits/32bits

floating point 32-bits/64-bits

widthStep
:
width
widthStep

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Les paramètres de
JfrImage
:

opencvImage
, pointeur vers une
IplImage (IplImage*)

listROI
, liste de régions d'intérêts (
list<IplROI*>
)

listOperations
, liste d'opérations (
list<string>
)

sequenceInfo
, des infos sur la séquence (
string
)

indice
, un indice (
int
)

colorSpace
, type d'espace de couleur (
TypeColorSpace
)

pose
, informations de position (
t3d*
)

timeStamp
, un temps (
timespec
)

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Un inventaire à la Prévert ...

opencvImage
, pointeur vers une
IplImage (I)

Accesseur :

IplImage* getIplImage()

void setIplImage (IplImage *opencvImage_)

Aucun accès ne devrait être fait mise à part dans une
fonction wrappant une fonction d'OpenCV

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Un inventaire à la Prévert ...

listROI
, liste de régions d'intérêts (
list<IplROI*>
)

Accesseurs :

std::list<IplROI*>& getListROI()

std::size_t getListROISize () const

void addROI (IplROI * iplROI_)

void addROI (int coi_, int xOffset_, int yOffset_, int width_, int
height_)


Les fonctions OpenCV utilisant les régions d'intérêts
utilisent celle, unique, définie dans
IplImage.

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Un inventaire à la Prévert ...

listOperations
, liste d'opérations (
list<string>
)

Accesseurs :

std::list<std::string>& getListOperation()

std::size_t getListOperationSize() const

void addOperation (const std::string & operation_)

Pas de fonction de suppression

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Un inventaire à la Prévert ...

sequenceInfo
, des infos sur la séquence (
string
)

Accesseurs :

std::string getSequenceInfo () const

void setSequenceInfo (const std::string & sequenceInfo_)

Champ destine a recevoir par exemple le path d'une
séquence d'image

indice
, un indice (
int
)

Accesseur get/set standards

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Un inventaire à la Prévert ...

colorSpace
, type d'espace de couleur (
TypeColorSpace
)

Accesseurs :

JfrImage::TypeColorSpace getColorSpace () const

void setColorSpace (JfrImage::TypeColorSpace colorSpace_)

Espaces chromatiques possibles :

enum TypeColorSpace {GREY, BGR, RGB, HSV, HSL, CMY,
CMYK, LUV, LAB, XYZ, YXY, UNKNOWN }

Ce champ n'est qu'informatif vis a vis d'OpenCV qui
ne reconnaît que le Greyscale et le BGR

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Un inventaire à la Prévert ...

pose
, informations de position (
t3d*
)

Pas encore implemente.

timeStamp
, un temps (
timespecs
)

Pas encore finalise.

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Les paramètres d'
IplImage
:

width, height, depth, nChannels, widthStep
:

Accesseurs :

int getWidth () const

int getHeight () const

int getDepth () const

int getnChannels () const

int getWidthStep() const

Pas de fonctions
set()

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Les paramètres d'
IplImage
:

Le type TypeIplDepth :

enum TypeIplDepth {u1 = IPL_DEPTH_1U, u8 =
IPL_DEPTH_8U, s8 = IPL_DEPTH_8S, u16 =
IPL_DEPTH_16U, s16 = IPL_DEPTH_16S, s32 =
IPL_DEPTH_32S, f32 = IPL_DEPTH_32F, f64 =
IPL_DEPTH_64F}

Chaque fonction de la classe
JfrImage
qui utilise le
paramètre
depth
utilise ce type pour la définir

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Constructeurs :

Pas de constructeur par défaut

Deux constructeurs 'de base' :

JfrImage (int width_, int height_,
JfrImage::TypeIplDepth depth_, int channels_)

JfrImage (int width_, int height_,
JfrImage::TypeIplDepth depth_, int channels_, int
indice_, const std::string &sequenceInfo_)

Un constructeur de recopie :

JfrImage (const jafar::image::JfrImage &jfrImage_)

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

I/O functions :

Lecture de fichier image :

staticJfrImage* loadImage (const char* filename, int iscolor =
-1)


Le
depth
de la
JfrImage
retournee est toujours u8

Il ne peut y avoir que 1 ou 3 plans chromatiques

Cette fonction supporte les formats de fichiers :

Windows bitmaps : BMP, DIB

JPEG files : JPEG, JPG, JPE

Portable Network Graphics : PNG

Portable image format : PBM, PGM, PPM

Sun rasters : SR, RAS

TIFF files - TIFF, TIF

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

I/O functions :

Ecriture de fichier image :

int saveImage (const char * filename)

myJfrImage.getnChannels()
doit être égal a 1 ou 3

Si
depth

u8
, les pixels sont convertis en
u8

Cette fonction supporte les formats de fichiers :

Windows bitmaps : BMP, DIB

JPEG files : JPEG, JPG, JPE

Portable Network Graphics : PNG

Portable image format : PBM, PGM, PPM

Sun rasters : SR, RAS

TIFF files - TIFF, TIF

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Fonctions utilitaires :

Cloner une image sans recopie :

JfrImage* cloneEmpty(JfrImage::TypeIplDepth depth_ =
(jafar::image::JfrImage::TypeIplDepth) -1, int channels_ = -1)

Possibilité de conserver
depth
et
nChannels

ou de les modifier

Le passage de paramètres par défaut (=-1)
conserve
depth
et
nChannels

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Fonctions utilitaires :

Copier les paramètres spécifiques
à

JfrImage
:

void copyJfrHeader(JfrImage& dst_)

Copie les attributs :

listROI

listOperations

sequenceInfo

indice

colorSpace

pose

timeStamp

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Fonctions utilitaires :

Changement d'espace de couleur ?

void convertColorMode(JfrImage& dst_, TypeColorConvMode
colorCode_);

Une petite explication max?

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Fonctions utilitaires :

Conversion de
depth
:

void convertScale(JfrImage& dst_, double scale_=1, double
shift_=0)

Conversion de toutes
depth
(sauf
u1
) vers celle de
dst

Peut appliquer une transformation affine sur les
valeurs du pixels du type :

I(dst) = I(this)*scale_ + shift_

ps faut changer le nom en convertDepth. je viens
encore de me faire avoir..

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Fonctions utilitaires :

Changement d'échelle :

void resize(JfrImage& dst_, TypeInterpolationMethod
interpolation_=inter_linear);

encore un petit coup max. c'est ton bebe celle la ;)


Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

Accéder aux pixels :

Les pixels sont stockés dans le
char* imageData
.

C'est donc toujours un
char*
quelque soit le
depth

choisi :
u8
(unsigned 8-bits) ou
f32
(floating-point 32-
bits)

Lors d'un accès aux pixels un
cast
de
imageData
est
donc nécessaire.

Deux méthodes sont possibles ...

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

La mauvaise :
#include "image/JfrImage.hpp"
using namespace jafar::image;
JfrImage img(800, 600, s16, 1);
int* pxPtr;
pxPtr = static_cast<int*>(img.getImageData());

Sur des machines
x86
sous
Linux
le type
int
est
associé
à

signed 16-bits
=>
ç
a marche

Mais quand est-il sur MacOS X ou de futurs
plateformes ?

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
L a   c l a s s e   J f r I m a g e

La bonne :
#include "image/JfrImage.hpp"
using namespace jafar::image;
JfrImage img(800, 600, s16, 1);
s16_cell::cell_type *pxPtr;
pxPtr = static_cast<s16_cell::cell_type*>(img.getImageData());

Cette méthode garantit l'utilisation du bon type pour
parcourir les tableaux de pixels et fonctionne sur tout
types de plateformes

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
U t i l i s a t i o n   d e s   f o n c t i o n s   d'O p e n C V

Principe :

Encapsulation d'une
IplImage
dans la classe
JfrImage
=> permet l'utilisation des fonctions
d'
OpenCV

Comment appeler les fonctions ?

Directement :
cvLaplace(const IplImage* source, IplImage* dst);
cvLaplace(source.getIplImage(),dst.getIplImage());

A travers un
wrap
de la fonction
OpenCV
:
laplace(const JfrImage& source, JfrImage& dst);
laplace(source,dst);

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
U t i l i s a t i o n   d e s   f o n c t i o n s   d'O p e n C V

Pourquoi wrapper ?

Pour être indépendant d'
OpenCV
. Un changement de
librairie n'occasionne que des changements dans les
fonctions de
wrap

Parce qu'
OpenCV
n'a pas de gestion d'erreur mais
qu'on peut en mettre une dans le
wrap

Est-ce que toutes les fonctions sont déjà
wrappées ?

NON ! On compte sur vous !

Jafar : Introduction au module Image
   
Robotic and Artificial Intelligence Research Group ­ LAAS/CNRS
U t i l i s a t i o n   d e s   f o n c t i o n s   d'O p e n C V

Un exemple, la function
Gradient::canny()
class Gradient {
private :
public :

static inline void canny(const JfrImage& src_, JfrImage&
dst_, double th1_, double th2_, int aperture_size_=3) {

cvCanny(src_.getIplImage(), dst_.getIplImage(), th1_,
th2_, aperture_size_);

std::ostringstream stream;

stream << "canny : th1=" << th1_ << " th2=" << th2_ << "
aperture_size=" << aperture_size_ ;

dst_.addOperation(stream.str());

}
}; // class Gradient