PROGRAMACIO DE FUNCIONS VILI EN C. 1. Nivells de programació en ViLi 2. Funcions C de processament d’imatges tipus d’imatge atributs i funcions d’acces operacions de creació i eliminació d’imatges apuntadors, funcions pel recorregut, “ switch(ImType(ima)) ” - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
PROGRAMACIO DE FUNCIONS VILI EN C
1. Nivells de programació en ViLi
2. Funcions C de processament d’imatges• tipus d’imatge• atributs i funcions d’acces• operacions de creació i eliminació d’imatges• apuntadors, funcions pel recorregut, “switch(ImType(ima))”• excepcions : Raise(<missatge error>)
6. Integració de la nova funció • fitxers d’include usrfdef.h, usrflib.h, usrftab.h• makefile
1. Nivells de programació en ViLi
Nivell imatge
Interficie Lisp C
Nivell pixel
Interpret de Lisp
simbols Lisp
taula de funcionsde l’interpretfunció en C
d’interficie
funcions C :• imlib.dll• (loadlibrary “... .dll”)
nodes Lisp
arguments C
2. Funcions C de processament d’imatges
2.1 Tipus d’imatges : include\image.h
typedef struct Image { char *Ident; /* image identifier */ int Type; /* image type IMA_BYTE IMA_SHORT IMA_LONG IMA_FLOAT IMA_COMPLEX */ int NCol; /* number of columns */ int NLin; /* number of lines */ int NPlanes; /* number of planes 1=2d image, >1 3d image */ int NChannels; /* number of channels ex: colour image (RGB) = 3 */ int GridType; /* GRID_RECT, GRID_HEX */ void *Data; /* image data */} *Image;
• les funcions ImageB, ImageS, ImageL, ImageF, ImageC retornen respectivament l’adreça del primer pixel d’una imatge d’un byte, short, long, float, complex per pixel.
• els apuntadors de recorregut es declaran register per intentar que el compilador es assigni als registres de la CPU
• depenent del tipus d’imatge a generar/recorrer, el proces es el mateix pero el tipus dels apuntadors no. Ho distingim fer un “switch(ImType(ima))” (veure exemples).
2. Funcions C de processament d’imatges
Quan es detecta un error per qualsevol causa, voldrem imprimir un missatge d’explicaciói retornar a l’interpret Lisp, no pas sortir del ViLi.
Ho fem cridant la funció de gestió d’exceptions ViLi, Raise(“Missatge d’error\n”);
/* Funcio que mostreja una imatge seleccionant punts cada un cert pas. Parametres : - Imatge d'entrada - pas per columna, fila, pla i canal Retorna una imatge del mateix tipus que la d'entrada, mostrejada. Errors : algun dels passos es menor que 1 */
register short fil, col, pla, cha ; /* per recorrer la imatge In */
/* controls sobre els parametres */
if ((steprow < 1) || (stepcol < 1) || (steppla < 1) || (stepcha < 1)) Raise(”Sample2 : step less than 1\n") ;
3. Exemples : sample2( )
/* nombre de files, columnes, plans i canals de la imatge d'entrada */ filinp = ImNLin(In); colinp = ImNCol(In); plainp = ImNPlanes(In); chainp = ImNChannels(In);
/* nombre de files, columnes, plans i canals de la imatge de sortida */ filout = ceil( (float) filinp / steprow ) ; colout = ceil( (float) colinp / stepcol ) ; plaout = ceil( (float) plainp / steppla ) ; chaout = ceil( (float) chainp / stepcha ) ;
/* creem la imatge de sortida */ Out = NewImage("Sample",ImType(In), colout, filout, plaout, chaout, GRID_RECT);
switch (ImType(In)) { case IM_BYTE: { register Byte *pin, *pout; pin = ImageB(In) ; pout = ImageB(Out) ; for (cha = 0 ; cha < chainp ; cha += stepcha) for (pla = 0 ; pla < plainp ; pla += steppla) for (fil = 0 ; fil < filinp ; fil += steprow) { pin = LineB(In, fil, pla, cha) ; for (col = 0 ; col < colinp ; col += stepcol, pin += stepcol, pout++) *pout = *pin ; } break; }
3. Exemples : sample2( )
case IM_SHORT: { register short *pin, *pout; pin = ImageS(In); pout = ImageS(Out); for (cha = 0 ; cha < chainp ; cha += stepcha) for (pla = 0 ; pla < plainp ; pla += steppla) for (fil = 0 ; fil < filinp ; fil += steprow) { pin = LineS(In, fil, pla, cha) ; for (col = 0 ; col < colinp ; col += stepcol, pin += stepcol, pout++) *pout = *pin ; } break; } case IM_LONG: { register long *pin, *pout; pin = ImageL(In); pout = ImageL(Out); for (cha = 0 ; cha < chainp ; cha += stepcha) for (pla = 0 ; pla < plainp ; pla += steppla) for (fil = 0 ; fil < filinp ; fil += steprow) { pin = LineL(In, fil, pla, cha) ; for (col = 0 ; col < colinp ; col += stepcol, pin += stepcol, pout++) *pout = *pin ; } break; }
3. Exemples : sample2( )
case IM_FLOAT: { register float *pin, *pout ; pin = ImageF(In); pout = ImageF(Out); for (cha = 0 ; cha < chainp ; cha += stepcha) for (pla = 0 ; pla < plainp ; pla += steppla) for (fil = 0 ; fil < filinp ; fil += steprow) { pin = LineF(In, fil, pla, cha) ; for (col = 0 ; col < colinp ; col += stepcol, pin += stepcol, pout++) *pout = *pin ; } break; } default: DelImage(Out); Raise(ErrTypeIm); } /* switch */ return Out;} /* sample2 */
3. Exemples : sample2( )
4. Funció C d’interficie
Què fa la funció d’interficie ?
1. Protegeix els arguments en front al mecanisme d’alliberament de memoria del Lisp
2. Obté i verifica el tipus dels arguments passats a la funció de l’interpret
3. Verificar el número de argumentos
4. Desencapsula els arguments (transforma de Lisp a C)
5. Crida la funció de processament en C
6. Encapsula el resultat (en fa un node Lisp)
7. Desprotegeix els arguments protegits abans
8. Retorna el resultat
xlsave1(LVAL)
xlga<tipus>()getArgument()
xllastarg() : si n’hi ha més, errormoreargs() : n’hi ha més encara ?
get<tipus>(LVAL)
<variable C> = sample2(...)
cv<tipus>(<variable C>)
xlpop(), xlpopn(m)m nombre d’arguments protegits
return LVAL
4. Funció C d’interficie
Funcions per obtenir i verificar arguments Lisp de diferents tipus :
/* Interficie de sample2 Format : ( sample2 <Image> [<int> [<int> [<int> [<int>] ] ] ] ) Parametres : imatge a mostrejar i pas per columna, fila, pla i canal en aquest ordre. Per defecte el pas es 1 */
LVAL xsample2 (){ LVAL Arg, Out; int ArgNum[4]; /* maxim 4 arguments de pas */ int i ;
xlsave1(Arg); Arg=xlgaimage();
/* llegim els passos i posem valors per defecte */
for (i=0; i<4; ++i) ArgNum[i] = 1;
for (i=0; i<4; ++i) { if (!moreargs()) break; ArgNum[i]=getfixnum(xlgafixnum()); } xllastarg();
Out = cvImageNode ( sample2 (getImage(Arg), ArgNum[0], ArgNum[1], ArgNum[2], ArgNum[3]) ) ; xlpop(); return Out ;}
5. Exemples : xsample2( )
6. Integració d’una nova funció (Visual C++)
Cal crear una DLL amb Visual C++ que contingui la nova funció a afegir al ViLi.
1. Crear un arxiu <funcio>.cpp que contingui :
a) includes ViLi : f) funció (fixe) DllMain( ) com#include <xlisp.h> als exemples Sample2
i#include <image.h> diamferet de
\CrossVisions\Examples\ViLi\
b) altres includes necessaris, com ara :#include <math.h>
c) codi funció, <funcio>(), per exemple sample2()d) codi interficie de la funció x<funcio>(), per exemple xsample2()
e) #define S SUBR #define F FSUBR FUNDEF localFunTab[]={ { "SAMPLE2", S, xsample2 }, { 0, 0, 0} };
6. Integració d’una nova funció (Visual C++)
2. Entrar en Visual C++ i crear un projecte nou de DLL, seguint al peu de la lletra les instruccions de l’arxiu
CrossVisions\Doc\Readme.txt
a l’apartat “DLL ViLi o VisionOk”
3. Copiar la DLL creada a \Debug al directori de ViLi
CrossVisions\lib\
4. Executar entrant en ViLi i fent
ViLi> (loadlibrary “… .dll”)
Consells : • editar l’arxiu d’exemple Sample2.cpp per fer el vostre.• provar en ViLi la funció polar amb testpol.lsp