PROGRAMACIO DE FUNCIONS VILI EN C
description
Transcript of PROGRAMACIO DE FUNCIONS VILI EN C
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>)
3. Exemples : thr.c , sample2.c
4. Funció C d’interficie• obtenció d’arguments Lisp : xlga<type>() , xllastarg() , moreargs()• desencapsulament : get<type>()• encapsulament : cv<type conversion>()
5. Exemples : xthr.c , xsample2.c
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;
/* image types */#define IM_BYTE 1#define IM_SHORT 2#define IM_LONG 3#define IM_FLOAT 4#define IM_COMPLEX 5
/* grid types */#define GRID_RECT 1#define GRID_HEX 2
/* Tipo byte */typedef unsigned char Byte;
/* Tipo complejo */typedef struct Complex { float Re,Im; /* parte real y parte imaginaria */} Complex;
2.2 Atributs i funcions d’acces : include\image.h
#define ImIdent(Im) ((Im)->Ident)#define ImType(Im) ((Im)->Type)#define ImNLin(Im) ((Im)->NLin)#define ImNCol(Im) ((Im)->NCol)#define ImNPlanes(Im) ((Im)->NPlanes)#define ImNChannels(Im) ((Im)->NChannels)#define ImGridType(Im) ((Im)->GridType)
/* Dimensiones en Pixels de la imagen */
#define DimImage(Im) ((Im)->NChannels*(Im)->NPlanes*(Im)->NLin*(Im)->NCol)#define DimChannel(Im) ((Im)->NPlanes*(Im)->NLin*(Im)->NCol)#define DimPlane(Im) ((Im)->NLin*(Im)->NCol)#define DimLine(Im) ((Im)->NCol)
2. Funcions C de processament d’imatges
2.3 Operacions de creació i eliminació d’imatges
extern Image NewImage ARGS((char *Ident,int Type,int NCol, int NLin, int NPlanes,int NChannels,int GridType));extern void DelImage ARGS((Image));#define NewTypeIm(IM,Ident) NewImage((Ident), \ (IM)->Type, \ (int) (IM)->NCol,(int) (IM)->NLin,(int) (IM)->NPlanes, \ (int) (IM)->NChannels,(IM)->GridType)
extern void ImRename ARGS((Image,char *));extern void SetImToVal ARGS((Image,double));extern Image ImCpy ARGS((Image));
2. Funcions C de processament d’imatges
2.4 Apuntadors, funcions pel recorregut , “switch(ImType(ima))”
Image Out;register Byte *pOut;::Out = NewImage(”Resultat",IM_BYTE, ncol, nlin, npla, ncha, GRID_RECT); pout = ImageB(Out);for (y=0 ; y<nlin ; y++) { for (x=0 ; x<ncol ; x++) { *pout = .... pout ++; }}
• 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”);
3. Exemples : thr( )
Image thr(In, Umbral, Dentro, Fuera)Image In;double Umbral, Dentro, Fuera;{ Image Out; register int NPix;
NPix=DimImage(In); Out=NewTypeIm(In,"Thr"); switch (ImType(In)) { case IM_BYTE: { register Byte *PIn, *POut; register Byte u,d,f;
u=Umbral; d= Dentro; f= Fuera; for (PIn=ImageB(In), POut=ImageB(Out); NPix>0; --NPix) if (*PIn++ >= u) *POut++ = d; else *POut++ = f; break; } case IM_SHORT: { register short *PIn, *POut; register short u,d,f;
u=Umbral; d= Dentro; f= Fuera;
for (PIn=ImageS(In), POut=ImageS(Out); NPix>0; --NPix) if (*PIn++ >= u) *POut++ = d; else *POut++ = f; break; }
case IM_LONG: { register long *PIn, *POut; register long u,d,f;
u=Umbral; d= Dentro; f= Fuera; for (PIn=ImageL(In), POut=ImageL(Out); NPix>0; --NPix) if (*PIn++ >= u) *POut++ = d; else *POut++ = f; break; } case IM_FLOAT: { register float *PIn, *POut; register float u,d,f;
u=Umbral; d= Dentro; f= Fuera; for (PIn=ImageF(In), POut=ImageF(Out); NPix>0; --NPix) if (*PIn++ >= u) *POut++ = d; else *POut++ = f; break; } default: DelImage(Out); Raise(ErrTypeIm); } /* switch */ return Out;} /* thr */
/* 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 */
Image sample2(In, stepcol, steprow, steppla, stepcha)Image In;int stepcol, steprow, steppla, stepcha ;{ Image Out; int filinp, colinp, plainp, chainp ; int filout, colout, plaout, chaout ;
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 :
xlgacons()xlgalist()xlgasymbol()xlgastring()xlgaobject()xlgafixnum()xlgaflonum()xlganum()xlgachar()xlgavector()xlgastream()xlgaustream()xlgastruct()xlgaclosure()xlgaimage()
Funcions de desencapsulament
getfixnum(x)getflonum(x)getchcode(x)getnum()getstring(x)getfile(x)getImage(x)
Funcions d’encapsulament
LVAL cvsymbol(char*);LVAL cvstring(char*);LVAL cvfile(FILE*);LVAL cvfixnum(int);LVAL cvflonum(double);LVAL cvchar(char);LVAL cvImageNode(Image);
sencersflotantssencers o flotants
5. Exemples : xthr( )
/* Interficie de xthr. Format: (thr <Image> <umbral> [<Dentro> <Fuera>])*/
LVAL xthr(){ LVAL Out,Arg; double Umbral, Dentro, Fuera;
xlsave1(Arg); Arg=xlgaimage(); Umbral=getnum(xlganum()); Dentro=255.0; Fuera=0.0; if (moreargs()) { Dentro=getnum(xlganum()); Fuera=getnum(xlganum()); } xllastarg(); Out=cvImageNode(Thr(getImage(Arg), Umbral, Dentro, Fuera)); xlpop(); return Out;}
/* 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