[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

BOUNCE rtl@rtlinux.org: Approval required: Admin request: /^subject:\s*help\b/i Non-member submission from [oscar <domingue@l (fwd)



>From owner-rtl Mon May 21 03:55:38 2001
Received: from lasmea.univ-bpclermont.fr (root@lasmea.univ-bpclermont.fr [193.54.50.15])
	by hq.fsmlabs.com (8.11.2/8.11.2) with ESMTP id f4L9tbr18500
	for <rtl@rtlinux.org>; Mon, 21 May 2001 03:55:37 -0600
Received: from lasmea.univ-bpclermont.fr ([193.54.50.225])
	by lasmea.univ-bpclermont.fr (8.9.3 (PHNE_18979)/8.9.3) with ESMTP id LAA25677
	for <rtl@rtlinux.org>; Mon, 21 May 2001 11:50:53 +0200 (METDST)
Sender: oscar@lasmea.univ-bpclermont.fr
Message-ID: <3B08E4DE.EDBA07F6@lasmea.univ-bpclermont.fr>
Date: Mon, 21 May 2001 11:50:22 +0200
From: oscar <domingue@lasmea.univ-bpclermont.fr>
X-Mailer: Mozilla 4.75 [es] (X11; U; Linux 2.2.14-rtl2.3 i686)
X-Accept-Language: en,x-ns1xvubdMeeNh5,x-ns2U0e0btwUq5f
MIME-Version: 1.0
To: rtlinux mai list <rtl@rtlinux.org>
Subject: help to adapt a program
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit

I think i haven't been so explicit before and it's for that because
anybody could help me . Here is the program.
In fact, the only important part to see is the following. In the
LancementAcquisition() function there is a while using the
AcquerirImageGdk(...) function to take images in a continue mode. What i
think is to change this part by a periodic rttask (by this way i could
control the frequency of image capture , images/seg) using the body of
AcquerirImageGdk() in this rttask. 
I want to know if it is possible and some idea of the troubles i will
find (commuications between this tasks, access to resources in rttask,
etc...). I think on e time i know how to start i will be able to
continue...
If anybody could tell me i would be very agreed with him/her. Thank you.

Here is...


/*----------------------------------------------------------------------------------*/
/*  Programme permettant la validation du suivi de route marques, dans
des zones    */
/*        de focalisation guidees par la mise a jour des
parametres                 */
/*              en utilisant des droites comme
detections.                          */
/*----------------------------------------------------------------------------------*/

#include <gtkLib.h>
#include <gdk.h>
#include <gdkprivate.h>
#include <gdkx.h>

#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/videodev.h>
#include <meteorLib.h>  
//#include "evicam.h"
#include <sys/time.h>
#include <unistd.h> 

extern "C" {
#include "ellipse.h"
#include "ellipse_lum.h"
#include "matrix.h"
#include "matrice_inter.h"
#include "Global_Data.h"
}

#include "commandePTZ.h"
#include "main.h"



Fenetre          *ptFen, *ptMessage, *ptParametres;
AireDessin       *AireImage; 
Label            *LeMessage;
Image             image;    //-- image 

// fichier image (en char) FORMAT_Xx(FORMAT_Y/2) car une trame sur 2
!!!!
unsigned char *ptImage = NULL;

// variables pour les boucles Acqui et Lecture Sequence
int              finLectureSequence=1;
int              incrementSequence=1;
int              finAcquisitionSequence=1; 

// variables pour le tracking
int             nb_pt_selec=0; // nombre de points selectionnes dans
l'image pour designer le motif a suivre
int             nb_pt_selec_max = 3; // nombre de points a selectionner
pour designer le motif (=3 pour l'ellipse,
=4 pour le quadrilatere)

// variables pour le suivi de quadrilatere (position du quadrilatere et
de la grille)
Global_Data  gd; 
Grille       gr; 


// variable pour le suivi d'ellipses
Ellipse el;
Parametres_Suivi parametres_suivi;
#ifdef ELLIPSE_LUM
Ellipse_lum el_lum;
Parametres_Suivi_lum parametres_suivi_lum;
#endif
double **mat_inter;

double vref[2043];
double vec[2043];

/* variables pour lacquisition des coord de l'ellipse ou du
qudrilatere*/
int xp[5];
int yp[5];
int incr=0;

/* variables pour le suivi  */

camera evi;// variable de la camera
Parametres_Commande parametres_commande;



int enable_track=0; // variable test pour boucle acquisition/tracking
int alterne_Zoom_PanTilt = 1;
int trace = 0; // variable trace
int first_time = 0; //variable test pour savoir s'il faut desallooc
mat_inter ou non ?
int nbTot;



int  TAILLE_IMAGE_X,TAILLE_IMAGE_Y;   // taille de l'image suivant X et
Y 





//---------------------------------------------------------
// Setting de la carte Meteor Matrox (vctrl)
//---------------------------------------------------------

//---------------------------------------------------------
void print_settings(int fd) {
//---------------------------------------------------------
  struct v4l2_format fmt;
  int input = -1;
  struct v4l2_input inp;
  struct v4l2_standard std;

  fmt.type = V4L2_BUF_TYPE_CAPTURE;
  if (ioctl(fd,VIDIOC_G_FMT,&fmt) < 0)
    perror("getting video format"),exit(1);
  if (ioctl(fd,VIDIOC_G_INPUT,&input) < 0)
    perror("getting video input"),exit(1);
  inp.index = input;
  if (ioctl(fd,VIDIOC_ENUMINPUT,&inp) < 0)
    perror("getting video input"),exit(1);
  printf("%d x %d @ %d bpp from input %d (%s)\n",
        
fmt.fmt.pix.width,fmt.fmt.pix.height,fmt.fmt.pix.depth,input,inp.name);
  printf("The inputs are:  ");
  for (input=0; ;++input)
  {
        inp.index = input;
        if (ioctl(fd,VIDIOC_ENUMINPUT,&inp) < 0)
                break;
        printf("%d = %s;  ",input,inp.name);
  }
  if (ioctl(fd, VIDIOC_G_STD, &std) == 0)
    printf("\nThe video standard is %s\n",std.name);

  printf("\n");
  close(fd);
  exit(0);
}

//---------------------------------------------------------
// Gestion des messages
//---------------------------------------------------------

//---------------------------------------------------------
void Click_messageOK()
//---------------------------------------------------------
{
  ptMessage->Cache();
}

//---------------------------------------------------------
void AfficheMessage(char *message)
//---------------------------------------------------------
{
      LeMessage->Texte(message);
      ptMessage->Montre();      
}

//---------------------------------------------------------
// Gestion des parametres
//---------------------------------------------------------

//---------------------------------------------------------
void Click_parametresOK()
//---------------------------------------------------------
{
  ptParametres->Cache();
}

//---------------------------------------------------------
void AfficheParametres()
//---------------------------------------------------------
{
      //LeMessage->Texte(message);
      ptParametres->Montre();      
}

//---------------------------------------------------------
// Gestion des images
//---------------------------------------------------------

//----------------------------------------------------- 
void ecriture_image(int *im, int tx, int ty, char *nom)
//----------------------------------------------------- 
{
  Image image;
  unsigned char *tabchar = new unsigned char[tx*ty];

  for (int i=0;i<tx*ty;i++) {
    tabchar[i] = im[i];
  }
  image.LireTabUchar(tabchar, tx, ty);
  image.Enregistrer(nom);
  delete [] tabchar;
}


//---------------------------------------------------------
// Affichage des objects suivis....
//---------------------------------------------------------

//----------------------------------------------------- 
void  trace_ellipse(Ellipse e,int col) 
//----------------------------------------------------- 
{
  int      i, nbpt=1000;
  float   xi,yi,xf,yf,phi=0,pas;
  float   ct, st;  
  int test_sortie = 0;

  ct = cos(e.theta);
  st = sin(e.theta);
  pas = 2.0*M_PI/(float)nbpt;
  for (i=0;i<nbpt;i++){
    xi = e.r1*cos(phi);
    yi = e.r2*sin(phi);
    xf = e.xc + xi*ct - yi*st;
    yf = e.yc + xi*st + yi*ct; 
    xi=xf;
    yi=yf*2;
    if ((xi >= 0)&&(xi <FORMAT_X-1)&&(yi >= 0)&&(yi < FORMAT_Y-1))
      {
        AireImage->Point((int)xi,(int)yi,ROUGE);
      }
    else 
      { //* deuxieme critere d'arret = ellipsee sortie de l'image
        test_sortie = 1;
      }
    phi+=pas;
  }
  if (test_sortie)
    {
        fprintf(stderr,"**** Enable_Tracking Error : Ellipse out of
image ****\n\a\a\a");
        enable_track = 0;
    }
}
#ifdef ELLIPSE_LUM

//----------------------------------------------------- 
void  trace_ellipse_lum(Ellipse_lum e,int col) 
//----------------------------------------------------- 
{
  int      i, nbpt=1000;
  float   xi,yi,xf,yf,phi=0,pas;
  float   ct, st;  
  int test_sortie = 0;

  ct = cos(e.theta);
  st = sin(e.theta);
  pas = 2.0*M_PI/(float)nbpt;
  for (i=0;i<nbpt;i++){
    xi = e.r1*cos(phi);
    yi = e.r2*sin(phi);
    xf = e.xc + xi*ct - yi*st;
    yf = e.yc + xi*st + yi*ct; 
    xi=xf;
    yi=yf*2;
    if ((xi >= 0)&&(xi <FORMAT_X-1)&&(yi >= 0)&&(yi < FORMAT_Y-1))
      {
        AireImage->Point((int)xi,(int)yi,ROUGE);
      }
    else 
      { //* deuxieme critere d'arret = ellipsee sortie de l'image
        test_sortie = 1;
      }
    phi+=pas;
  }
  if (test_sortie)
    {
        fprintf(stderr,"**** Enable_Tracking Error : Ellipse out of
image ****\n\a\a\a");
        enable_track = 0;
    }
}

#endif

//----------------------------------------------------- 
void  trace_quadrilatere() 
//----------------------------------------------------- 
{
  AireImage->TypeTrait(4);
  // quadrilatere
 
AireImage->Segment((int)gr.uf[1],2*(int)gr.vf[1],(int)gr.uf[2],2*(int)gr.vf[2],ROUGE);
 
AireImage->Segment((int)gr.uf[2],2*(int)gr.vf[2],(int)gr.uf[3],2*(int)gr.vf[3],ROUGE);
 
AireImage->Segment((int)gr.uf[3],2*(int)gr.vf[3],(int)gr.uf[4],2*(int)gr.vf[4],ROUGE);
 
AireImage->Segment((int)gr.uf[4],2*(int)gr.vf[4],(int)gr.uf[1],2*(int)gr.vf[1],ROUGE);
  // diagonales
 
AireImage->Segment((int)gr.uf[1],2*(int)gr.vf[1],(int)gr.uf[3],2*(int)gr.vf[3],ROUGE);
 
AireImage->Segment((int)gr.uf[4],2*(int)gr.vf[4],(int)gr.uf[2],2*(int)gr.vf[2],ROUGE);
}



//----------------------------------------------------- 
void Attend() 
//-----------------------------------------------------
{ 
  GdkEvent *event; 
  char fin = 0; 

  do { 
     while (!(event = gdk_event_get())); 
     if (event->type ==   GDK_BUTTON_PRESS) fin = 1; 
  } while (!fin); 
} 

/*--------------------------------------------------------------*/
void TrackQuadrilatere(){
/*--------------------------------------------------------------*/

 if(((int)gr.uf[1]>0)&&((int)gr.uf[1]<gd.im.col)&&
        ((int)gr.uf[1]>0)&&((int)gr.vf[1]<gd.im.lig)&&
        ((int)gr.uf[2]>0)&&((int)gr.uf[2]<gd.im.col)&&
        ((int)gr.uf[2]>0)&&((int)gr.vf[2]<gd.im.lig)&&
        ((int)gr.uf[3]>0)&&((int)gr.uf[3]<gd.im.col)&&
        ((int)gr.uf[3]>0)&&((int)gr.vf[3]<gd.im.lig)&&
        ((int)gr.uf[4]>0)&&((int)gr.uf[4]<gd.im.col)&&
        ((int)gr.uf[4]>0)&&((int)gr.vf[4]<gd.im.lig)
   ){


 /*  fprintf(stderr,"   -> position (%f,%f)(%f,%f)(%f,%f)(%f,%f)\n",
           gr.uf[1],gr.vf[1],
           gr.uf[2],gr.vf[2],
           gr.uf[3],gr.vf[3],
           gr.uf[4],gr.vf[4]
           );*/

   gd.im.data = ptImage;

   Validation_mat(&gr,&gd,mat_inter);
 }
else 
  {
    trace = 0;
    enable_track=0;
    fprintf(stderr,"\nprobl. \n\a");
  }
}


//----------------------------------------------------- 
void TrackEllipse()
//----------------------------------------------------- 
{
  int i,j,k;
  double p[5],er;
  double diff[2048];

  //* PATTERN VECTOR
  echantillonne_ellipse(el,vec,
                        FORMAT_X,240,ptImage,
                        &parametres_suivi);
          
  //* Diff(PATTERN VECTOR)
  for(k=0;k<parametres_suivi.nbTot;k++)
    if((vec[k])!=-1) 
      {
        diff[k]=vref[k]-vec[k]; 
        // fprintf(stderr," %f  ",diff[k]);
      }
    else 
      {diff[k]=0.;}
          
          
  //* Estimation du PARAMETERS VECTOR avec la INTERACTION MATRIX
  for(i=0;i<parametres_suivi.nbp;i++)
    {
      for(j=0,er=0;j<parametres_suivi.nbTot;j++) er+=
mat_inter[i][j]*diff[j];
      p[i]=er;
    }

  //* Coordonnees de l'ellipse "corrigee" a partir du PARAMETERS VECTOR
  el.r1 = el.r1*(-p[2]+1.);
  el.r2 = el.r2*(-p[3]+1.);
  el.theta -= p[4];
  el.xc -= el.r1*p[0]*cos(el.theta)-el.r2*p[1]*sin(el.theta);
  el.yc -= el.r1*p[0]*sin(el.theta)+el.r2*p[1]*cos(el.theta);
          
  //fprintf(stderr,"Je te suis
(%f,%f,%f,%f,%f)\n",el.r1,el.r2,el.theta,el.xc,el.yc);
}

#ifdef ELLIPSE_LUM

//----------------------------------------------------- 
void TrackEllipse_lum()
//----------------------------------------------------- 
{
  int i,j,k;
  double p[6],er;
  double diff[2048];

  //* PATTERN VECTOR
  echantillonne_ellipse_lum(el_lum,vec,
                        FORMAT_X,(int)(FORMAT_Y/2.),ptImage,
                        &parametres_suivi_lum);
          
  //* Diff(PATTERN VECTOR)
  for(k=0;k<parametres_suivi_lum.nbTot;k++)
    if((vec[k])!=-1) 
      {
        diff[k]=vref[k]-vec[k]; 
        // fprintf(stderr," %f  ",diff[k]);
      }
    else 
      {diff[k]=0.;}
          
          
  //* Estimation du PARAMETERS VECTOR avec la INTERACTION MATRIX
  for(i=0;i<parametres_suivi_lum.nbp;i++)
    {
      for(j=0,er=0;j<parametres_suivi_lum.nbTot;j++) er+=
mat_inter[i][j]*diff[j];
      p[i]=er;
    }

  //* Coordonnees de l'ellipse "corrigee" a partir du PARAMETERS VECTOR
  el_lum.r1 = el_lum.r1*(-p[2]+1.);
  el_lum.r2 = el_lum.r2*(-p[3]+1.);
  el_lum.theta -= p[4];
  el_lum.xc -=
el_lum.r1*p[0]*cos(el_lum.theta)-el_lum.r2*p[1]*sin(el_lum.theta);
  el_lum.yc -=
el_lum.r1*p[0]*sin(el_lum.theta)+el_lum.r2*p[1]*cos(el_lum.theta);
  el_lum.luminance -=  p[5];
  fprintf(stderr,"luminance =  %f \n",el_lum.luminance  );
          
  //fprintf(stderr,"Je te suis
(%f,%f,%f,%f,%f)\n",el.r1,el.r2,el.theta,el.xc,el.yc);
}

#endif

//---------------------------------------------------------
int AcquerirImageGdk(capture_device * pcapt_d,struct v4l2_buffer
*pbuf,int streaming)
//---------------------------------------------------------
{
  int l,nbPlanes;
  static char init=1;
  static clock_t tempsFin=0;
  int tempsAttente;
  static Display *display;
  static XImage *ximg[STREAMBUFS];
  char  *ptrChar;
  int  *ptrInt;
  static char tabChar[FORMAT_X*FORMAT_Y*2];
  static unsigned char tabunsignedChar[FORMAT_X*FORMAT_Y/2];
  int ELL_QUADR;
  //int bidule;

  struct timeval time_out1,time_out0;
  struct timeval time_track1,time_track0;
  struct timeval time_controlPTZ1,time_controlPTZ0;
  struct timeval time_getPTZ1,time_getPTZ0;
  struct timezone tz;

 
  gettimeofday(&time_out0,&tz);


  if (init) {
    init_eviG21(&evi,&parametres_commande);
    fprintf(stderr,"taille_axe = %d \n",parametres_commande.taille_axe);

    display = GDK_GC_XDISPLAY(AireImage->Gc());
    nbPlanes = DisplayPlanes(display,0);
    printf("nb plans : %d\n",nbPlanes);

    //    tabChar = (char*) calloc(pcapt_d->width * pcapt_d->height,1);
    init=false;
  }


  int tx =  pcapt_d->width;
  int ty =  pcapt_d->height;


  if (capture_dq (pcapt_d, pbuf, streaming))
    {
      fprintf(stderr,"numero buffer %d \n",pbuf->index);
      // modif pour lire le dernier buffer remplit !!!!
    /*    if (pbuf->index==0)
          {
          bidule = 3;
          }
          else if (pbuf->index==1)
          {
          bidule = 0;
          }
          else if (pbuf->index==2)
          {
          bidule = 1;
          }
          else if (pbuf->index==3)
          {
          bidule = 2;
          }
          
          ptrInt = (int*)pcapt_d->vimage[bidule].data;*/
      ptrInt = (int*)pcapt_d->vimage[pbuf->index].data;
      //free(ptImage);
      ptImage = tabunsignedChar;//(unsigned char
*)malloc(FORMAT_X*240*sizeof(char));
      ptrChar = tabChar; 
      for (l=0;l<ty;l+=2) {
        for (int c=0;c<tx;c++) {
          *(ptrChar++) = *(ptrInt++) ;// il lit une trame sur l'image
precedente
          *(ptrChar+tx) = *(ptrInt) ;
          *(ptImage++) = *(ptrInt) ;
        }
        ptrChar += tx;
      }

      ptImage = tabunsignedChar;  // on met le pointeur au debut !!!
        //ptrInt = (int*)pcapt_d->vimage[pbuf->index].data;
    if (enable_track)
        {
          gettimeofday(&time_getPTZ0,&tz);
          evi.zoom = DonnePositionZoom();
          evi.focus = DonnePositionFocus();
          gettimeofday(&time_getPTZ1,&tz);
        }
     

      // On va te enable_tracker putain d'ellipse ou de quadrilatere...
      gettimeofday(&time_track0,&tz);
      if (nb_pt_selec_max ==3)
        {
          ELL_QUADR =0;
#ifdef ELLIPSE_LUM
          if(enable_track != 0) TrackEllipse_lum();
          
          if (trace) trace_ellipse_lum(el_lum,0);
#else
          if(enable_track != 0) TrackEllipse();
          if (trace) trace_ellipse(el,0);
         // parametres_commande.taille_axe = 2. * el.r1;
#endif

        }
      else 
        {
          ELL_QUADR =1;
          if(enable_track != 0)  TrackQuadrilatere();
          if (trace) trace_quadrilatere();
        //  parametres_commande.taille_axe = sqrt(
(gr.uf[1]-gr.uf[3])*(gr.uf[1]-gr.uf[3])+
        //                                         
(2.*gr.vf[1]-2.*gr.vf[3])*(2.*gr.vf[1]-2.*gr.vf[3]) );
        }
      gettimeofday(&time_track1,&tz);
 

      // Et maintenant on va faire bouger la camera tout seule...c'est
pas magique, c'est scientifique...
      gettimeofday(&time_controlPTZ0,&tz);
      if (enable_track) enable_track = 2;
      if (alterne_Zoom_PanTilt)
        {
          if (enable_track == 1)
            {
              CommandePositionPanTilt(&el,
                                     
&gr.uf[1],&gr.uf[2],&gr.uf[3],&gr.uf[4],
                                     
&gr.vf[1],&gr.vf[2],&gr.vf[3],&gr.vf[4],
                                     
ELL_QUADR,evi,parametres_commande);
              enable_track = 2;
            }
          else  if (enable_track == 2)
            {
              // bientot sur vos ecrans le Pan-Tilt
              PanTiltTracking(el,
                              gr.uf[1],gr.uf[2],gr.uf[3],gr.uf[4],
                             
2*gr.vf[1],2*gr.vf[2],2*gr.vf[3],2*gr.vf[4],
                              ELL_QUADR,evi,parametres_commande);
              //          fprintf(stderr,"zoom = %d \n",evi.zoom);
          
            }
          alterne_Zoom_PanTilt = 0;
        }
      else 
        {
          if (enable_track)
            {
              ZoomTracking(el,
                           gr.uf[1],gr.uf[2],gr.uf[3],gr.uf[4],
                           2*gr.vf[1],2*gr.vf[2],2*gr.vf[3],2*gr.vf[4],
                           ELL_QUADR,evi,parametres_commande);
            }
          alterne_Zoom_PanTilt = 1;
        }
      gettimeofday(&time_controlPTZ1,&tz);
 
      capture_q (pcapt_d, pbuf, streaming);
  
    }

  AireImage->AfficheImage((unsigned char*)tabChar, 0,0,tx,ty);

         

 
//gdk_draw_gray_image(AireImage->w()->window,AireImage->Gc(),0,0,tx,ty,GDK_RGB_DITHER_NORMAL,(unsigned
char*)ptrInt,tx);

  gettimeofday(&time_out1,&tz);
  fprintf(stderr,"Temps boucle = %.1f ms. (tracking = %.2f ms.
PTZcontrol = %.2f ms. PTZget = %.2f ms.)\n",
         
(1000000*(time_out1.tv_sec-time_out0.tv_sec)+time_out1.tv_usec-time_out0.tv_usec)/1000.,
         
(1000000*(time_track1.tv_sec-time_track0.tv_sec)+time_track1.tv_usec-time_track0.tv_usec)/1000.,
         
(1000000*(time_controlPTZ1.tv_sec-time_controlPTZ0.tv_sec)+time_controlPTZ1.tv_usec-time_controlPTZ0.tv_usec)/1000.,
         
(1000000*(time_getPTZ1.tv_sec-time_getPTZ0.tv_sec)+time_getPTZ1.tv_usec-time_getPTZ0.tv_usec)/1000.
          );
  parametres_commande.temps_boucle =
(1000000*(time_out1.tv_sec-time_out0.tv_sec)+time_out1.tv_usec-time_out0.tv_usec)/1000.;
 

  return 0;
}

//---------------------------------------------------------
void LancementAcquisition()
//---------------------------------------------------------
{
  finAcquisitionSequence=0;

  static char init=true;
  static capture_device capt_d;
  struct v4l2_buffer tempbuf;

  if (init) {
    // Parametres video.
    unsigned int format;
    int input;
    char my_device[64];

    // Initialisation du port video.
    strcpy (my_device, VID_DEVICE);
    input=VID_PORT;
    format=capture_fmt(FORMAT_BIT);
  //  format=capture_fmt(8);
  //  printf("format %d\n", format);

    capture_init (&capt_d, my_device, input, format, FORMAT_X, FORMAT_Y,
8);
    grabSetFps(capt_d.fd_video, 30);  // X images par seconde.
    capture_start (&capt_d, VID_STREAMING);
   
    printf ("Capturing %dx%dx%d \"%4.4s\" images\n",
    capt_d.width, capt_d.height, capt_d.depth,
    (char *) &(capt_d.pixelformat));
    printf ("Images are %d bytes each\n", 
    capt_d.width * capt_d.height * capt_d.depth / 8);

    init = 0;
  }

  /*ptIm=(unsigned char *)malloc(capt_d.width*capt_d.height 
   *capt_d.depth/8*sizeof(unsigned char));*/

  do {
    AcquerirImageGdk(&capt_d,&tempbuf, VID_STREAMING);
    //    AfficherImageX(AireImage, capt_d.width, capt_d.height ,ptIm);
    /*       image.LireTabUchar(ptIm, capt_d.width, capt_d.height);
             AireImage->AfficheImage(image);*/ 

   // AfficherImageX(AireImage, capt_d.width, capt_d.height ,ptIm1);
      while (gdk_events_pending()) gtk_main_iteration_do(1); 
  } while (!finAcquisitionSequence && finLectureSequence);

  capture_perf(&capt_d);
  //  ecriture_image(ptIm,capt_d.width, capt_d.height,"image0.tif");
  // ecriture_image(ptIm1,capt_d.width, capt_d.height,"image1.tif");

}

//---------------------------------------------------------
void ArretAcquisition()
//---------------------------------------------------------
{
  finAcquisitionSequence=1;
  enable_track = 0;
}

//-----------------------------------------
gboolean ClickAireImage (GtkWidget       *widget,
                         GdkEventButton  *event,
                         gpointer         user_data)
//-----------------------------------------
{
  //Parametres_Apprentissage parametres_appr;
  double **X = NULL;
  double **Yref = NULL;
  double *err = NULL;
  int u = int(event->x);
  int v = int(event->y);
  int i;
  clock_t t0, t1;
 
  if (!finAcquisitionSequence && finLectureSequence)
    {
      finLectureSequence=1;
      finAcquisitionSequence=1;
    }

  xp[nb_pt_selec] = u;
  yp[nb_pt_selec] = (int)((double)v/2.); // une trame sur 2
  nb_pt_selec++;
  fprintf(stderr," * Init Point %d : (%d,%d)\n",
          nb_pt_selec,xp[nb_pt_selec-1],yp[nb_pt_selec-1]*2);
  if (nb_pt_selec==nb_pt_selec_max)
    {
      t0 = clock();
      if (nb_pt_selec_max==3)
      {
        fprintf(stderr," * Liberation de la
memoire\n",parametres_suivi.nbTot);
        if (first_time)
          {
            //init_luminance = 0;
            freeMd(mat_inter);
            first_time = 1;
          }
/*
        fprintf(stderr," * Initialisation des param de suivi\n");
        Init_Param_Suivi(&parametres_suivi);
        CalcParam(&el,xp,yp);
        fprintf(stderr," * Parametre de l'ellipse :
                 \n\txc = %f\n\tyc = %f\n\ttheta = %f\n\tr1 = %f\n\tr2 =
%f \n",
                el.xc, el.yc, el.theta,el.r1,el.r2);      
        trace_ellipse(el,0);
       
echantillonne_ellipse(el,vref,FORMAT_X,(int)(FORMAT_Y/2.),ptImage,&parametres_suivi);
        fprintf(stderr," * Allocation de la matrice d'inter\n");
        mat_inter =
allocMd(parametres_suivi.nbp,parametres_suivi.nbTot);
        //parametres_appr.X =
allocMd(parametres_suivi.nbexp,parametres_suivi.nbTot);
        //parametres_appr.Yref =
allocMd(parametres_suivi.nbp,parametres_suivi.nbexp);
        //parametres_appr.err =
(double*)malloc(parametres_suivi.nbexp*sizeof(double));
        X = allocMd(parametres_suivi.nbexp,parametres_suivi.nbTot);
        Yref = allocMd(parametres_suivi.nbp,parametres_suivi.nbexp);
        err = (double*)malloc(parametres_suivi.nbexp*sizeof(double));
                fprintf(stderr," * Calcul de la matrice d'interaction
\n");

        //parametres_appr.nb_boucle_max = 5;
//      parametres_appr.nb_boucle = 0;
//      for
(parametres_appr.nb_boucle=0;parametres_appr.nb_boucle<parametres_appr.nb_boucle_max;parametres_appr.nb_boucle++)
//        {
             CalcA_and_Track2(mat_inter,X,Yref,err,el,vref,
                            FORMAT_X, 
                            (int)(FORMAT_Y/2.), // une seule trame sur 2 
                            ptImage,parametres_suivi,0);
        fprintf(stderr," * Parametre de l'ellipse :
                 \n\txc = %f\n\tyc = %f\n\ttheta = %f\n\tr1 = %f\n\tr2 =
%f \n",
                el.xc, el.yc, el.theta,el.r1,el.r2);      
                   
//        }
        freeMd(X);
        freeMd(Yref);
        free(err);
        
//      CalcA(mat_inter,el,vref, 
        //      FORMAT_X,  
        //      (int)(FORMAT_Y/2.), // une seule trame sur 2  
         //     ptImage,parametres_suivi); 

        nb_pt_selec = 0;
*/

#ifdef ELLIPSE_LUM
        // apprentissage de la matrice avec variation de la luminance
        fprintf(stderr," * Initialisation des param de suivi\n");
        Init_Param_Suivi_lum(&parametres_suivi_lum);
        CalcParam_lum(&el_lum,xp,yp);
        fprintf(stderr," * Parametre de l'ellipse :
                 \n\txc = %f\n\tyc = %f\n\ttheta = %f\n\tr1 = %f\n\tr2 =
%f\n\tluminance = %f \n",
                el_lum.xc, el_lum.yc,
el_lum.theta,el_lum.r1,el_lum.r2,el_lum.luminance);         
        trace_ellipse_lum(el_lum,0);
       
echantillonne_ellipse_lum(el_lum,vref,FORMAT_X,(int)(FORMAT_Y/2.),ptImage,&parametres_suivi_lum);
        fprintf(stderr," * Allocation de la matrice d'inter\n");
        mat_inter =
allocMd(parametres_suivi_lum.nbp,parametres_suivi_lum.nbTot);
                fprintf(stderr," * Calcul de la matrice d'interaction
\n");
        CalcA_lum(mat_inter,el_lum,vref, 
              FORMAT_X,  
              (int)(FORMAT_Y/2.), // une seule trame sur 2  
              ptImage,parametres_suivi_lum); 
        nb_pt_selec = 0;
#else
        fprintf(stderr," * Initialisation des param de suivi\n");
        Init_Param_Suivi(&parametres_suivi);
        CalcParam(&el,xp,yp);
        fprintf(stderr," * Parametre de l'ellipse :
                 \n\txc = %f\n\tyc = %f\n\ttheta = %f\n\tr1 = %f\n\tr2 =
%f\n\t\n",
                el.xc, el.yc, el.theta,el.r1,el.r2);      
        trace_ellipse(el,0);
       
echantillonne_ellipse(el,vref,FORMAT_X,(int)(FORMAT_Y/2.),ptImage,&parametres_suivi);
        fprintf(stderr," * Allocation de la matrice d'inter\n");
        mat_inter =
allocMd(parametres_suivi.nbp,parametres_suivi.nbTot);
                fprintf(stderr," * Calcul de la matrice d'interaction
\n");
        CalcA(mat_inter,el,vref, 
              FORMAT_X,  
              (int)(FORMAT_Y/2.), // une seule trame sur 2  
              ptImage,parametres_suivi); 
        nb_pt_selec = 0;
#endif
      }
      else 
        {
          fprintf(stderr," * Liberation de la memoire\n");
          if (first_time)
            {
              freeMd(mat_inter);
              first_time = 1;
            }
          fprintf(stderr," * Initialisation des param de suivi\n");
          gd.im.data = ptImage;  
          gd.im.lig = (int)(FORMAT_Y/2.);
          gd.im.col = FORMAT_X;
          fprintf(stderr," * Parametre du quadrilatere (%d)\n",NB_PTS);
          for (i=0;i<nb_pt_selec_max;i++)
            {
              gd.x[i+1]=xp[i];
              gd.y[i+1]=yp[i];
              fprintf(stderr,"   -> point
(%d,%d)\n",gd.x[i+1],gd.y[i+1]);
            }
          Init_grille(&gr,&gd);
          fprintf(stderr," * Allocation de la matrice d'inter\n");
          mat_inter = allocMd(8*4, NB_PTS);
          fprintf(stderr,"   -> matrice 1 \n");
          Apprentissage_mat(&gr,&gd,mat_inter,3,0.01); 
          fprintf(stderr,"   -> matrice 2\n");
          Apprentissage_mat(&gr,&gd,mat_inter,2,0.05); 
          fprintf(stderr,"   -> matrice 3\n");
          Apprentissage_mat(&gr,&gd,mat_inter,1,0.1); 
          fprintf(stderr,"   -> matrice 4\n");
          Apprentissage_mat(&gr,&gd,mat_inter,0,0.2); 
          nb_pt_selec = 0;
        }
      t1 = clock();
      enable_track =1;
      fprintf(stderr," * OK pour le tracking (temps app. = %f)\n",
(float)((t1-t0)/1000000.));
    if (nb_pt_selec_max ==3)
      {
#ifdef ELLIPSE_LUM
        parametres_commande.taille_axe = 2. * el_lum.r1;
#else
        parametres_commande.taille_axe = 2. * el.r1;
#endif
      }
    else 
      {
        parametres_commande.taille_axe = 1./2. * sqrt(
(gr.uf[1]-gr.uf[3])*(gr.uf[1]-gr.uf[3])+
                                              
(2.*gr.vf[1]-2.*gr.vf[3])*(2.*gr.vf[1]-2.*gr.vf[3]) );
      }
      trace = 1;
      fprintf(stderr," * OK pour l'affichage\n");
      
      fprintf(stderr," * Relance l'acquisition \n");
      LancementAcquisition();
    }

 
 
  return FALSE;
}


//---------------------------------------------------------
void NeRienFaire()
//---------------------------------------------------------
{
  AfficheMessage("Sorry : Cette fonction n'est pas encore implemente
!");
}
  //(*parametres_commande).gain_PanTilt_PanTilt = 75.;
  //(*parametres_commande).gain_PanTilt_Zoom = 50.;
  //(*parametres_commande).gain_Zoom = 0.1;
  //(*parametres_commande).taille_axe = TAILLE_AXE;
  //(*parametres_commande).tolerance = TOLERANCE;

//---------------------------------------------------------
void Init_gPP(float val)
//---------------------------------------------------------
{
  parametres_commande.gain_PanTilt_PanTilt = val;
}
//---------------------------------------------------------
void Init_gPZ(float val)
//---------------------------------------------------------
{
  parametres_commande.gain_PanTilt_Zoom = val;
}
//---------------------------------------------------------
void Init_gZ(float val)
//---------------------------------------------------------
{
  parametres_commande.gain_Zoom = val;
}
//---------------------------------------------------------
void Init_tai(float val)
//---------------------------------------------------------
{
  parametres_commande.taille_axe = val;
}
//---------------------------------------------------------
void Init_tol(float val)
//---------------------------------------------------------
{
  parametres_commande.tolerance = val;
}


//---------------------------------------------------------
void ChoixAlgoProjectif()
//---------------------------------------------------------
{
  if(!enable_track)
    nb_pt_selec_max = 4; // nombre de points selectionnes  
  else 
    {
      AfficheMessage("Erreur : vous ne pouvez pas changer de type
d'algorithme \ntant que la phase de suivi est
active");
    }
}

//---------------------------------------------------------
void ChoixAlgoAffine()
//---------------------------------------------------------
{
  if(!enable_track)
    nb_pt_selec_max = 3;
  else 
    {
      AfficheMessage("Erreur : vous ne pouvez pas changer de type
d'algorithme \ntant que la phase de suivi est
active");
    }
}

//-----------------------------------------
int main (int argc, char *argv[])
//-----------------------------------------
{
  // variables pour l'initialisation de la camera
  int vfd = 0;
  int arg;
  char curchar;
  int devicenext = 0;
  char *devname = "/dev/video";

  int width=0,height=0,bpp=0;
  int input=-1;
  char *std = NULL;
  struct v4l2_standard vstd;
  int query = 1;
  struct v4l2_format fmt;

  // taille de l'image
  width = FORMAT_X;
  height= FORMAT_Y;
  bpp= FORMAT_BIT;
  query = 0;

  // init meteor (vctrl + vcat)
  vfd = open(devname,O_RDWR);
  if ((vfd > 0) && query) print_settings(vfd);

  if (vfd <= 0) {
    fprintf(stderr,"sorry, no such device %s\n",devname);
    exit(1);
  }

  if (std)
  {
    int i,err;
    ioctl(vfd, VIDIOC_G_STD, &vstd);
    for (i = 0, err = 0; err == 0; ++i)
      {
        struct v4l2_enumstd     estd;
        estd.index = i;
        err = ioctl(vfd, VIDIOC_ENUMSTD, &estd);
        if (!err)
          {
            if (strcmp(std,(char *)(estd.std.name)) == 0)
              vstd = estd.std;
          }
      }
    err = ioctl(vfd, VIDIOC_S_STD, &vstd);
    if (err)
      printf("S_STD returned error %d\n",errno);
  }
  fmt.type = V4L2_BUF_TYPE_CAPTURE;
  if (ioctl(vfd,VIDIOC_G_FMT,&fmt) < 0)
    perror("getting video format"),exit(1);
  if (width) fmt.fmt.pix.width = width;
  if (height) fmt.fmt.pix.height = height;
  if (bpp) fmt.fmt.pix.depth = bpp;
  switch (bpp) {
    case 8: fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_GREY;break;
    case 15: fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB555;break;
    case 16: fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565;break;
    case 24: fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24;break;
    case 32: fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR32;break;
  }
  if (ioctl(vfd,VIDIOC_S_FMT,&fmt) < 0)
    perror("setting video format"),exit(1);
  if (input != -1 && ioctl(vfd,VIDIOC_S_INPUT,&input) < 0)
    perror("setting video input"),exit(1);

  close(vfd);


  // init  GtkLib pour l'environnement graphique
  GtkLibInit(&argc, &argv);

  // Definition de la fenetre principale
  Fenetre fen(argv[0]);
  Frame frameMain(fen,2,2); // main
  Frame frameImage(frameMain,1,1); 
  Frame framePaddle(frameMain,3,3); // image
  Frame frameZoom(frameMain,2,1); // paddla

  ptFen = &fen;

  AireDessin aireImage(frameImage,0,0,FORMAT_X,FORMAT_Y);
  aireImage.CBclickSouris(ClickAireImage);
  AireImage = &aireImage;
 
  Menu menu(fen, "Quitter","Acquisition","Algo Tracking","PTZ
Tracking","Camera");
  menu.Ajoute(0); // Separateur
  menu.Ajoute(0,"Quitter", GtkLibFin,'Q');

  menu.Ajoute(1); // Separateur
  menu.Ajoute(1,"Lancer acquisition",LancementAcquisition,'A');
  menu.Ajoute(1,"Arreter acquisition", ArretAcquisition,'D');
  
  menu.Ajoute(2); // Separateur
  menu.Ajoute(2,"Projectif (quad.)",ChoixAlgoProjectif,'P');
  menu.Ajoute(2,"affine (Ellipse)",ChoixAlgoAffine,'E');
  menu.Ajoute(2); // Separateur
  menu.Ajoute(2,"Proj. avec appr. rapide",NeRienFaire);
  menu.Ajoute(2,"affine avec appr. rapide",NeRienFaire);

  menu.Ajoute(3); // Separateur
  menu.Ajoute(3,"choix commande 1",NeRienFaire,'1');
  menu.Ajoute(3,"choix commande 2", NeRienFaire,'2');
  menu.Ajoute(3,"choix commande 3", NeRienFaire,'3');
  menu.Ajoute(3); // Separateur
  menu.Ajoute(3,"parametres Commande",AfficheParametres,'C');

  menu.Ajoute(4); // Separateur
  menu.Ajoute(4,"evi-g21 (Blanche)",NeRienFaire,'B');
  menu.Ajoute(4,"evi-d31 (Noire)",NeRienFaire,'N');
  menu.Ajoute(4); // Separateur
  menu.Ajoute(4,"Allumer Camera",CameraPowerOn);
  menu.Ajoute(4,"Eteindre Camera",CameraPowerOff);


  // Declaration du paddle 
  Bouton UpLeft (framePaddle,UpLeft,"UpLeft");
  Bouton Up (framePaddle,Up,"Up");           
  Bouton UpRight (framePaddle,UpRight,"UpRight");   
  Bouton Left (framePaddle,Left,"Left");
  Bouton Home (framePaddle,CameraHome,"Home");
  Bouton Right (framePaddle,Right,"Right");
  Bouton DownLeft (framePaddle,DownLeft,"DownLeft");
  Bouton Down (framePaddle,Down,"Down");
  Bouton DownRight (framePaddle,DownRight,"DownRight");   

  Bouton UnZoom (frameZoom,UnZoom,"     Zoom -   ");
  Bouton Zoom (frameZoom,Zoom,"     Zoom+    ");
 
 

  // Definition d'une fenetre "Message (d'erreur)"
  Fenetre fen_message("Message");
  Frame frameMessageLabel(fen_message,2,2);
  Frame frameMessageBoutonOK(fen_message,2,2);
  ptMessage = &fen_message;

  Label messageLabel(frameMessageLabel,"");
  LeMessage = &messageLabel;
  Bouton messageOK(frameMessageBoutonOK,Click_messageOK,"OK");

  // Definition d'une fenetre "parametre"
  Fenetre fen_parametres("Parametres");
  Frame frameParametresLabel(fen_parametres,2,50);
  Label messageLabel_gPP(frameParametresLabel,"gain PanTilt PanTilt
:",-1,-1,10);
  SpinBouton
spinbouton_gPP(frameParametresLabel,Init_gPP,50,100,75,-1,-1,10);
  Label messageLabel_gPZ(frameParametresLabel,"gain PanTilt Zoom
:",-1,-1,10);
  SpinBouton
spinbouton_gPZ(frameParametresLabel,Init_gPZ,0.,1.,0.1,0.1,-1,-1,10);
  Label messageLabel_gZ(frameParametresLabel,"gain Zoom :",-1,-1,10);
  SpinBouton
spinbouton_gZ(frameParametresLabel,Init_gZ,0,100,50,-1,-1,10);
  Label messageLabel_tai(frameParametresLabel,"taille_axe :",-1,-1,10);
  SpinBouton
spinbouton_tai(frameParametresLabel,Init_tai,0,100,50,-1,-1,10);
  Label messageLabel_tol(frameParametresLabel,"tolerance :",-1,-1,100);
  SpinBouton
spinbouton_tol(frameParametresLabel,Init_tol,0,10,5,-1,-1,10);
  ptParametres = &fen_parametres;
  Bouton parametresOK(frameParametresLabel,Click_parametresOK,"OK");

  // Affichage de la fenetre principale
  fen.Montre();
  CameraPowerOn();
  // lance l'environnment
  gtk_main ();
  return 0;                  
}