[Jde-dev] Ticket 167
JoseMaria
jmplaza en gsyc.es
Sab Ene 31 18:07:45 CET 2009
Hola mozos,
> Por cierto, toda la doc que comentas en tú correo estaría genial si la
> subimos a alguna sección del wiki, para que quede bien reflejado los
> cambios y el uso actual del api.
Sip, el sitio natural es la sección del manual de Jde que explica la
biblioteca progeo. Imagino que Sara está en ello...
Sobre las mejoras que describe Sara en progeo, os cuento un poco más la
intención, el contexto y la historia del asunto. Progeo es la biblioteca
que relaciona las imágenes con el espacio tridimensional que observa la
cámara. Gracias a ella hemo hecho aplicaciones como ElderCare [1] o
Attention [2], que estiman la posición 3D de una persona o reconstruyen
en 3D la escena que rodea un par de cámaras.
Hasta ahora usabamos un modelo pinhole [3] para modelar las cámaras.
Este modelo es relativamente simple y responde a cámaras ideales. Por
ejemplo es el que siguen las cámaras de OpenGL. Con el calibrador que
hizo Redo enriquecimos el modelo de cámara: le añadimos el parámetro
skew, y que las focales en horizontal y en vertical pudieran ser
diferentes. Con ellos el modelo representa más fielmente a cámaras
reales, que no encajan en el idílico modelo pinhole.
Hasta ahora el esquema calibrador era el único en usar ese modelo, de
hecho calculaba los valores de esos parámetros skew, fdistx y fdisty. La
biblioteca progeo aún no había incorporado ese modelo más rico en sus
cálculos. Con el parche que ha enviado Sara ya sí lo utiliza y ahora
todas las aplicaciones que usan progeo pueden beneficiarse de sus
cálculos más exactos.
Puestos a cambiar el API hemos incluido también varios parámetros de
distorsión radial para modelar correctamente aún a más cámaras reales.
De hecho aquellas que presentan ciertos defectos típicos como la
distorsión tipo barrilete. Esto de momento no lo vamos a implementar en
el código de la biblioteca, pero hemos dejado abierta la puerta para
hacerlo en un futuro no muy lejano, sin tener que cambiar el API de
progeo.
La incorporación de 'rows' y 'columns' obedece a una mala elección en el
API antiguo. Después de usarlo con cámaras virtuales de distintos
tamaños, enseguida nos dimos cuenta de que lo natural era incorporar el
tamaño del fotograma en el modelo de la cámara.
Ánimo,
JoseMaria
[1] http://jde.gsyc.es/index.php/ElderCare
[2] http://jde.gsyc.es/index.php/Rocapal_visual_attention_3D
[3] http://en.wikipedia.org/wiki/Pinhole_camera
> > Debido a que el modelo de cámara que teníamos hasta ahora era muy
> > simplificado, se ha decidido introducir algunos parámetros más en la
> > estructura que representa una cámara en progeo:
> >
> > * rows: número de filas que tiene la imagen de la cámara
> >
> > * columns: número de columnas que tiene la imagen de la cámara
> >
> > * fdistx: distancia focal x en milímetros
> >
> > * fdisty: distancia focal y en milímetros (por defecto la distancia focal
> > y hará el papel de distancia focal 'a secas' del modelo simplificado
> > anterior.
> >
> > * skew: ángulo entre los ejes x e y de un píxel en radianes. El parámetro
> > 's' de la matriz 'K' toma valor de la siguiente manera s=skew*fdisty.
> >
> > * d1,d2,d3,d4,d5,d6,dx,dy: parámetros que modelan la distorsión radial (de
> > momento no se van a utilizar).
> >
> >
> > Considerar que el parámetro 's' puede tomar valores distintos de 0 ha
> > supuesto modificar las fórmulas para hallar la matriz inversa de 'K'
> > necesaria para backproject, obteniendo las siguientes nuevas relaciones en
> > la inversa de 'K':
> >
> > 1/k11 -k12/(k11·k22) (k12·k23 - k13·k22) / (k22·k11)
> >
> > 0 1/k22 -k23/k22
> >
> > 0 0 1
> >
> > También se ha cambiado el API de la función displayline(), a la que ahora
> > se le pasa todo la estructura de una cámara.
> >
> > documento de texto sencillo adjunto (parche)
> > Index: schemas/extrinsics/extrinsics.c
> > ===================================================================
> > --- schemas/extrinsics/extrinsics.c (revisión: 275)
> > +++ schemas/extrinsics/extrinsics.c (copia de trabajo)
> > @@ -366,7 +366,7 @@
> > fprintf(salida,"FOApositionH %f\n",mycameras[mycam].foa.H);
> > fprintf(salida,"roll %f\n",mycameras[mycam].roll);
> > fprintf(salida,"\n #intrinsics\n");
> > - fprintf(salida,"f %f\n",mycameras[mycam].fdist);
> > + fprintf(salida,"f %f\n",mycameras[mycam].fdisty);
> > fprintf(salida,"u0 %f\n",mycameras[mycam].u0);
> > fprintf(salida,"v0 %f\n",mycameras[mycam].v0);
> > fclose(salida);
> > @@ -444,7 +444,7 @@
> > }
> > else if (strcmp(word1,"f")==0){
> > sscanf(buffer_file,"%s %s",word1,word2);
> > - mycameras[mycam].fdist=(float)atof(word2);
> > + mycameras[mycam].fdisty=(float)atof(word2);
> > }
> > else if (strcmp(word1,"u0")==0){
> > sscanf(buffer_file,"%s %s",word1,word2);
> > @@ -453,7 +453,7 @@
> > else if (strcmp(word1,"v0")==0){
> > sscanf(buffer_file,"%s %s",word1,word2);
> > mycameras[mycam].v0=(float)atof(word2);
> > - }
> > + }
> > }
> > return 1;
> > }
> > @@ -726,11 +726,14 @@
> > mycameras[vcam].foa.Y = 1975.0;
> > mycameras[vcam].foa.Z = -225.0;
> > mycameras[vcam].foa.H = 1.;
> > - mycameras[vcam].fdist = (float)ISIGHT_PINHOLE_FDIST;
> > + mycameras[vcam].fdisty = (float)ISIGHT_PINHOLE_FDIST;
> > mycameras[vcam].u0 = (float)ISIGHT_PINHOLE_U0;
> > mycameras[vcam].v0 = (float)ISIGHT_PINHOLE_V0;
> > mycameras[vcam].roll = 0.0;
> > - update_camera_matrix(&mycameras[vcam]);
> > + mycameras[vcam].skew = 0.0;
> > + mycameras[vcam].columns = SIFNTSC_COLUMNS;
> > + mycameras[vcam].rows = SIFNTSC_ROWS;
> > + update_camera_matrix(&mycameras[vcam]);
> > }
> >
> >
> > @@ -749,7 +752,7 @@
> > fl_set_slider_value(fd_extrinsicsgui->roll_slider,(double)((mycameras[mycam].roll*360)/(2*PI)));
> >
> > /* intrinsics */
> > - fl_set_slider_value(fd_extrinsicsgui->focus_slider,(double)mycameras[mycam].fdist);
> > + fl_set_slider_value(fd_extrinsicsgui->focus_slider,(double)mycameras[mycam].fdisty);
> > fl_set_slider_value(fd_extrinsicsgui->u0,(double)mycameras[mycam].u0);
> > fl_set_slider_value(fd_extrinsicsgui->v0,(double)mycameras[mycam].v0);
> > }
> > @@ -862,7 +865,7 @@
> >
> > }else if(obj == fd_extrinsicsgui->focus_slider){ /* FOCUS DISTANCE SLIDER */
> >
> > - mycameras[mycam].fdist=(float) fl_get_slider_value(fd_extrinsicsgui->focus_slider);
> > + mycameras[mycam].fdisty=(float) fl_get_slider_value(fd_extrinsicsgui->focus_slider);
> > update_camera_matrix(&mycameras[mycam]);
> > /*mydebug();*/
> >
> > @@ -940,7 +943,7 @@
> > else return -1;
> > }
> >
> > -int virtual_drawline(HPoint2D p1, HPoint2D p2, FL_COLOR colour)
> > +int virtual_drawline(HPoint2D p1, HPoint2D p2, FL_COLOR colour, TPinHoleCamera camera)
> > /* it takes care of important features */
> > /* before/behind the focal plane, inside/outside the image frame */
> > {
> > @@ -953,7 +956,7 @@
> > return 0;
> > }
> >
> > -int drawline(HPoint2D p1, HPoint2D p2, FL_COLOR colour)
> > +int drawline(HPoint2D p1, HPoint2D p2, FL_COLOR colour, TPinHoleCamera camera)
> > /* it takes care of important features */
> > /* before/behind the focal plane, inside/outside the image frame */
> > {
> > @@ -1005,7 +1008,7 @@
> > for(i=0;i<room_lines;i++){
> > project(room[i*2+0],&a,mycameras[mycam]);
> > project(room[i*2+1],&b,mycameras[mycam]);
> > - drawline(a,b,FL_RED);
> > + drawline(a,b,FL_RED,mycameras[mycam]);
> > }
> > /* cross at the optical center */
> > fila=SIFNTSC_ROWS-1-(int)mycameras[mycam].u0;
> > @@ -1091,7 +1094,7 @@
> > H2.Z=0;
> > project(H1,&a,mycameras[mycam]);
> > project(H2,&b,mycameras[mycam]);
> > - drawline(a,b,FL_GREEN);
> > + drawline(a,b,FL_GREEN,mycameras[mycam]);
> >
> > /* rendering of virtual image */
> > /* reset_virtual_buffer */
> > @@ -1107,47 +1110,47 @@
> > backproject(&a3A,a,mycameras[mycam]);
> > project(a3A,&a,mycameras[vcam]);
> > project(mycameras[mycam].position,&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_DEEPPINK);
> > + virtual_drawline(a,b,FL_DEEPPINK,mycameras[mycam]);
> > a.x=0.;
> > a.y=SIFNTSC_COLUMNS-1.;
> > a.h=1.;
> > backproject(&a3B,a,mycameras[mycam]);
> > project(a3B,&a,mycameras[vcam]);
> > project(mycameras[mycam].position,&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_DEEPPINK);
> > + virtual_drawline(a,b,FL_DEEPPINK,mycameras[mycam]);
> > a.x=0.;
> > a.y=0.;
> > a.h=1.;
> > backproject(&a3C,a,mycameras[mycam]);
> > project(a3C,&a,mycameras[vcam]);
> > project(mycameras[mycam].position,&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_DEEPPINK);
> > + virtual_drawline(a,b,FL_DEEPPINK,mycameras[mycam]);
> > a.x=SIFNTSC_ROWS-1.;
> > a.y=0.;
> > a.h=1.;
> > backproject(&a3D,a,mycameras[mycam]);
> > project(a3D,&a,mycameras[vcam]);
> > project(mycameras[mycam].position,&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_DEEPPINK);
> > + virtual_drawline(a,b,FL_DEEPPINK,mycameras[mycam]);
> >
> > project(a3A,&a,mycameras[vcam]);
> > project(a3B,&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_DEEPPINK);
> > + virtual_drawline(a,b,FL_DEEPPINK,mycameras[mycam]);
> > project(a3B,&a,mycameras[vcam]);
> > project(a3C,&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_DEEPPINK);
> > + virtual_drawline(a,b,FL_DEEPPINK,mycameras[mycam]);
> > project(a3C,&a,mycameras[vcam]);
> > project(a3D,&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_DEEPPINK);
> > + virtual_drawline(a,b,FL_DEEPPINK,mycameras[mycam]);
> > project(a3D,&a,mycameras[vcam]);
> > project(a3A,&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_DEEPPINK);
> > + virtual_drawline(a,b,FL_DEEPPINK,mycameras[mycam]);
> >
> > /* room in virtual camera */
> > for(i=0;i<room_lines;i++){
> > project(room[i*2+0],&a,mycameras[vcam]);
> > project(room[i*2+1],&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_BLACK);
> > + virtual_drawline(a,b,FL_BLACK,mycameras[mycam]);
> > }
> >
> > /* Draw XY, XZ, YZ grids */
> > @@ -1155,28 +1158,28 @@
> > {
> > project(gridXY[2*i],&a,mycameras[vcam]);
> > project(gridXY[2*i+1],&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_RED);
> > + virtual_drawline(a,b,FL_RED,mycameras[mycam]);
> > project(gridXY[2*SLOTS+2*i],&a,mycameras[vcam]);
> > project(gridXY[2*SLOTS+2*i+1],&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_RED);
> > + virtual_drawline(a,b,FL_RED,mycameras[mycam]);
> > }
> > for(i=0;i<SLOTS;i++)
> > {
> > project(gridYZ[2*i],&a,mycameras[vcam]);
> > project(gridYZ[2*i+1],&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_PALEGREEN);
> > + virtual_drawline(a,b,FL_PALEGREEN,mycameras[mycam]);
> > project(gridYZ[2*SLOTS+2*i],&a,mycameras[vcam]);
> > project(gridYZ[2*SLOTS+2*i+1],&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_PALEGREEN);
> > + virtual_drawline(a,b,FL_PALEGREEN,mycameras[mycam]);
> > }
> > for(i=0;i<SLOTS;i++)
> > {
> > project(gridXZ[2*i],&a,mycameras[vcam]);
> > project(gridXZ[2*i+1],&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_BLUE);
> > + virtual_drawline(a,b,FL_BLUE,mycameras[mycam]);
> > project(gridXZ[2*SLOTS+2*i],&a,mycameras[vcam]);
> > project(gridXZ[2*SLOTS+2*i+1],&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_BLUE);
> > + virtual_drawline(a,b,FL_BLUE,mycameras[mycam]);
> > }
> >
> > /* camera axis in virtual camera */
> > @@ -1186,21 +1189,21 @@
> > relativas2absolutas(XaxisRel,&Xaxis);
> > project(mycameras[mycam].position,&a,mycameras[vcam]);
> > project(Xaxis,&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_PALEGREEN);
> > + virtual_drawline(a,b,FL_PALEGREEN,mycameras[mycam]);
> > relativas2absolutas(YaxisRel,&Yaxis);
> > project(mycameras[mycam].position,&a,mycameras[vcam]);
> > project(Yaxis,&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_BLUE);
> > + virtual_drawline(a,b,FL_BLUE,mycameras[mycam]);
> > relativas2absolutas(ZaxisRel,&Zaxis);
> > project(mycameras[mycam].position,&a,mycameras[vcam]);
> > project(Zaxis,&b,mycameras[vcam]);
> > - virtual_drawline(a,b,FL_RED);
> > + virtual_drawline(a,b,FL_RED,mycameras[mycam]);
> >
> > /*cameras axis*/
> > project(mycameras[mycam].position,&a,mycameras[vcam]);
> > project(mycameras[mycam].foa,&b,mycameras[vcam]);
> > /*FL_WHEAT,FL_PALEGREEN*/
> > - virtual_drawline(a,b,FL_RED);
> > + virtual_drawline(a,b,FL_RED,mycameras[mycam]);
> >
> >
> >
> > Index: libs/progeo/progeo.h
> > ===================================================================
> > --- libs/progeo/progeo.h (revisión: 275)
> > +++ libs/progeo/progeo.h (copia de trabajo)
> > @@ -47,12 +47,18 @@
> > HPoint3D position; /* camera 3d position in mm */
> > HPoint3D foa; /* camera 3d focus of attention in mm */
> > float roll; /* camera roll position angle in rads */
> > - float fdist; /* focus distance in mm*/
> > + float fdistx; /* focus x distance in mm*/
> > + float fdisty; /* focus y distance in mm*/
> > float u0,v0; /* pixels */
> > + float skew; /*angle between the x and y pixel axes in rads*/
> > + int rows; /* image height in pixels */
> > + int columns; /* image width in pixels */
> > /* camera K matrix */
> > float k11,k12,k13,k14,k21,k22,k23,k24,k31,k32,k33,k34;
> > /* camera rotation + translation matrix */
> > float rt11,rt12,rt13,rt14,rt21,rt22,rt23,rt24,rt31,rt32,rt33,rt34,rt41,rt42,rt43,rt44;
> > + /* distorsion parameters */
> > + float d1,d2,d3,d4,d5,d6,dx,dy;
> > /* top right and bottom left points */
> > HPoint3D tr, bl;
> > /* name */
> > @@ -77,5 +83,5 @@
> > extern void update_stereocamera_matrix(TPinHoleStereocamera *stereo);
> > extern int project(HPoint3D in, HPoint2D *out, TPinHoleCamera camera);
> > extern int backproject(HPoint3D *out, HPoint2D in, TPinHoleCamera camera);
> > -extern int displayline(HPoint2D p1, HPoint2D p2, HPoint2D *a, HPoint2D *b);
> > +extern int displayline(HPoint2D p1, HPoint2D p2, HPoint2D *a, HPoint2D *b, TPinHoleCamera camera);
> > extern void display_camerainfo(TPinHoleCamera camera);
> > Index: libs/progeo/progeo.c
> > ===================================================================
> > --- libs/progeo/progeo.c (revisión: 275)
> > +++ libs/progeo/progeo.c (copia de trabajo)
> > @@ -23,10 +23,6 @@
> > #include <math.h>
> > #include <stdio.h>
> >
> > -/* SIF image size */
> > -#define SIFNTSC_ROWS 240
> > -#define SIFNTSC_COLUMNS 320
> > -
> > #define PI 3.141592654
> >
> > int debug=0;
> > @@ -116,13 +112,13 @@
> > camera->rt44=1.;
> >
> > /* intrinsics parameters */
> > - camera->k11=camera->fdist; camera->k12=0.; camera->k13=camera->u0; camera->k14=0.;
> > - camera->k21=0.; camera->k22=camera->fdist; camera->k23=camera->v0; camera->k24=0.;
> > + camera->k11=camera->fdisty; camera->k12=camera->skew*camera->fdisty; camera->k13=camera->u0; camera->k14=0.;
> > + camera->k21=0.; camera->k22=camera->fdisty; camera->k23=camera->v0; camera->k24=0.;
> > camera->k31=0.; camera->k32=0.; camera->k33=1.; camera->k34=0.;
> >
> > if (debug==1) printf("Camera %s Located at (%.f,%.f,%.f)\n",camera->name,camera->position.X,camera->position.Y,camera->position.Z);
> > if (debug==1) printf("Camera %s Orientation: pointing towards FocusOfAtention (%.f,%.f,%.f), roll (%.f)\n",camera->name,camera->foa.X,camera->foa.Y,camera->foa.Z,camera->roll*360./(2*PI));
> > - if (debug==1) printf("Camera %s f= %.5f y0=%d x0=%d\n",camera->name,camera->fdist,(int)camera->v0,(int)camera->u0);
> > + if (debug==1) printf("Camera %s f= %.5f y0=%d x0=%d\n",camera->name,camera->fdisty,(int)camera->v0,(int)camera->u0);
> > if (debug==1) printf("Camera %s K matrix\n %.3f %.1f %.1f %.1f\n %.1f %.3f %.1f %.1f\n %.1f %.1f %.1f %.1f\n",camera->name,camera->k11,camera->k12,camera->k13,camera->k14,camera->k21,camera->k22,camera->k23,camera->k24,camera->k31,camera->k32,camera->k33,camera->k34);
> > if (debug==1) printf("Camera %s RT matrix\n %.1f %.1f %.1f %.1f\n %.1f %.1f %.1f %.1f\n %.1f %.1f %.1f %.1f\n %.1f %.1f %.1f %.1f\n",camera->name,camera->rt11,camera->rt12,camera->rt13,camera->rt14,camera->rt21,camera->rt22,camera->rt23,camera->rt24,camera->rt31,camera->rt32,camera->rt33,camera->rt34,camera->rt41,camera->rt42,camera->rt43,camera->rt44);
> > }
> > @@ -243,7 +239,9 @@
> > myin.x=in.x*camera.k11/in.h;
> > myin.y=in.y*camera.k11/in.h;
> >
> > - ik11=(1./camera.k11); ik12=0.; ik13=-(camera.k13/camera.k11);
> > + ik11=(1./camera.k11);
> > + ik12=-camera.k12/(camera.k11*camera.k22);
> > + ik13=(camera.k12*camera.k23-camera.k13*camera.k22)/(camera.k22*camera.k11);
> > ik21=0.; ik22=(1./camera.k22); ik23=-(camera.k23/camera.k22);
> > ik31=0.; ik32=0.; ik33=1.;
> >
> > @@ -286,7 +284,7 @@
> >
> > /* if p1 and p2 can't be drawed in a 320x240 image, then it will return 0.
> > otherwise it will return 1 and gooda & goodb will be the correct points in the image to be drawn */
> > -int displayline(HPoint2D p1, HPoint2D p2, HPoint2D *a, HPoint2D *b)
> > +int displayline(HPoint2D p1, HPoint2D p2, HPoint2D *a, HPoint2D *b, TPinHoleCamera camera)
> > /* it takes care of important features: before/behind the focal plane, inside/outside the image frame */
> > {
> >
> > @@ -296,7 +294,7 @@
> > float Xmax,Xmin,Ymax,Ymin;
> > float papb=0.;
> >
> > - Xmin=0.; Xmax=SIFNTSC_ROWS-1.; Ymin=0.; Ymax=SIFNTSC_COLUMNS-1.;
> > + Xmin=0.; Xmax=camera.rows-1.; Ymin=0.; Ymax=camera.columns-1.;
> > /* Watchout!: they can't reach 240 or 320, their are not valid values for the pixels */
> >
> > l0.x=0.; l0.y=1.; l0.h=-Ymin;
> > @@ -547,7 +545,7 @@
> > printf("Camera %s\n\n",camera.name);
> > printf(" Position: (X,Y,Z,H)=(%.1f,%.1f,%.1f,%.1f)\n",camera.position.X,camera.position.Y,camera.position.Z,camera.position.H);
> > printf(" Focus of Attention: (x,y,z,h)=(%.1f,%.1f,%.1f,%.1f)\n\n",camera.foa.X,camera.foa.Y,camera.foa.Z,camera.foa.H);
> > - printf(" Focus Distance: %.1f mm\n",camera.fdist);
> > + printf(" Focus Distance: %.1f mm\n",camera.fdisty);
> > printf(" Optical Center: (x,y)=(%.1f,%.1f)\n\n",camera.u0,camera.v0);
> > printf(" K Matrix: | %.1f %.1f %.1f %.1f |\n",camera.k11,camera.k12,camera.k13,camera.k14);
> > printf(" | %.1f %.1f %.1f %.1f |\n",camera.k21,camera.k22,camera.k23,camera.k24);
> > _______________________________________________
> > Jde-developers mailing list
> > Jde-developers en gsyc.es
> > http://gsyc.escet.urjc.es/cgi-bin/mailman/listinfo/jde-developers
> --
> Roberto Calvo Palomino | Libre Software Engineering Lab (GSyC)
> Tel: (+34) 91 488 85 23 | Universidad Rey Juan Carlos
> Tel: (+34) 91 488 81 05 | Edif. Departamental II - Despacho 116
> rocapal en gsyc.es | c/Tulipán s/n 28933 Móstoles (Madrid)
> http://libresoft.es/
>
> GPG-KEY: http://gsyc.es/~rocapal/rocapal.gpg
> _______________________________________________
> Jde-developers mailing list
> Jde-developers en gsyc.es
> http://gsyc.escet.urjc.es/cgi-bin/mailman/listinfo/jde-developers
--
http://gsyc.es/jmplaza
Universidad Rey Juan Carlos
More information about the Jde-developers
mailing list