AccumulateStat.cpp

Go to the documentation of this file.
00001 /*
00002 This file is part of LIA_RAL which is a set of software based on ALIZE
00003 toolkit for speaker recognition. ALIZE toolkit is required to use LIA_RAL.
00004 
00005 LIA_RAL project is a development project was initiated by the computer
00006 science laboratory of Avignon / France (Laboratoire Informatique d'Avignon -
00007 LIA) [http://lia.univ-avignon.fr <http://lia.univ-avignon.fr/>]. Then it
00008 was supported by two national projects of the French Research Ministry:
00009         - TECHNOLANGUE program [http://www.technolangue.net]
00010         - MISTRAL program [http://mistral.univ-avignon.fr]
00011 
00012 LIA_RAL is free software: you can redistribute it and/or modify
00013 it under the terms of the GNU Lesser General Public License as
00014 published by the Free Software Foundation, either version 3 of
00015 the License, or any later version.
00016 
00017 LIA_RAL is distributed in the hope that it will be useful,
00018 but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00020 GNU Lesser General Public License for more details.
00021 
00022 You should have received a copy of the GNU Lesser General Public
00023 License along with LIA_RAL.
00024 If not, see [http://www.gnu.org/licenses/].
00025 
00026 The LIA team as well as the LIA_RAL project team wants to highlight the
00027 limits of voice authentication in a forensic context.
00028 The "Person Authentification by Voice: A Need of Caution" paper
00029 proposes a good overview of this point (cf. "Person
00030 Authentification by Voice: A Need of Caution", Bonastre J.F.,
00031 Bimbot F., Boe L.J., Campbell J.P., Douglas D.A., Magrin-
00032 chagnolleau I., Eurospeech 2003, Genova].
00033 The conclusion of the paper of the paper is proposed bellow:
00034 [Currently, it is not possible to completely determine whether the
00035 similarity between two recordings is due to the speaker or to other
00036 factors, especially when: (a) the speaker does not cooperate, (b) there
00037 is no control over recording equipment, (c) recording conditions are not
00038 known, (d) one does not know whether the voice was disguised and, to a
00039 lesser extent, (e) the linguistic content of the message is not
00040 controlled. Caution and judgment must be exercised when applying speaker
00041 recognition techniques, whether human or automatic, to account for these
00042 uncontrolled factors. Under more constrained or calibrated situations,
00043 or as an aid for investigative purposes, judicious application of these
00044 techniques may be suitable, provided they are not considered as infallible.
00045 At the present time, there is no scientific process that enables one to
00046 uniquely characterize a persones voice or to identify with absolute
00047 certainty an individual from his or her voice.]
00048 
00049 Copyright (C) 2004-2010
00050 Laboratoire d'informatique d'Avignon [http://lia.univ-avignon.fr]
00051 LIA_RAL admin [alize@univ-avignon.fr]
00052 Jean-Francois Bonastre [jean-francois.bonastre@univ-avignon.fr]
00053 */
00054 
00055 #if !defined(ALIZE_GeneralTools_cpp)
00056 #define ALIZE_GeneralTools_cpp
00057 
00058 #include <iostream>
00059 #include <fstream>  // pour outFile
00060 #include <cstdio>   // pour printf()
00061 #include <cassert> // pour le debug pratique
00062 #include <cmath>
00063 #include <liatools.h>
00064 #if defined(THREAD)
00065 #include <pthread.h>
00066 #endif
00067 
00068 //-------------------------------------------------------------------------
00069 //-- Accumulate the log likelihood for the selected frames and a given model
00070 void accumulateStatLLK(StatServer &ss,FeatureServer &fs,MixtureStat &llkAcc, unsigned long idxBeginFrame,unsigned long nbFrames,
00071                        Config &config)  
00072 {
00073   fs.seekFeature(idxBeginFrame);                                           // go to the frame in the buffer (and load it if needed)
00074   for (unsigned long n=0;n<nbFrames;n++){
00075     Feature f;
00076     if(fs.readFeature(f)==false) cout<<"No more features"<<endl;
00077     
00078     double toto=llkAcc.computeAndAccumulateLLK(f);
00079     if (debug) cout << "likelihood Frame["<<idxBeginFrame+n<<"]="<<toto<<endl;
00080   }
00081 }
00082 // one a Segment
00083 void accumulateStatLLK(StatServer &ss,FeatureServer &fs,MixtureStat &llkAcc,Seg* seg,Config &config)
00084 {
00085   unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName()); // Find the index of the first frame of the file in the buffer
00086   accumulateStatLLK(ss,fs,llkAcc,begin,seg->length(),config);
00087 }
00088 // One on Cluster
00089 void accumulateStatLLK(StatServer &ss,FeatureServer &fs,MixtureStat &llkAcc,SegCluster &selectedSegments,Config &config)
00090 {
00091   Seg* seg;                                                     // reset the reader at the begin of the input stream
00092   selectedSegments.rewind();      
00093   while((seg=selectedSegments.getSeg())!=NULL)                  // For each of the selected segments
00094     accumulateStatLLK(ss,fs,llkAcc,seg,config);
00095 }
00096  
00097  
00098 
00099 //-------------------------------------------------------------------------
00100 //-- accumulate the statistic for EM, using a current accumulator (wordl)
00101 //-- CAUTION: THE ACCUMULATOR SHOULD BE INITIALIZED (resetEM) BEFORE THE CALL
00102 //--          A GET CALL SHOULD BE DONE AFTER THE CALL  
00103 // One a part of the feature stream
00104 double accumulateStatEM(StatServer &ss,FeatureServer &fs,MixtureStat &emAcc,unsigned long idxBeginFrame,unsigned long nbFrames,Config &config){
00105   double llkAcc=0.0;
00106   fs.seekFeature(idxBeginFrame);                                           // go to the frame in the buffer (and load it if needed)
00107   for (unsigned long n=0;n<nbFrames;n++){
00108     Feature f;
00109     fs.readFeature(f);
00110     llkAcc+=log(emAcc.computeAndAccumulateEM(f));
00111     //for (unsigned long i=0;i<fs.getVectSize();i++)
00112     //  cout <<"f["<<i<<"]="<<f[i]<<endl;
00113   } 
00114   return llkAcc;
00115 }
00116 // one a Segment
00117 double accumulateStatEM(StatServer &ss,FeatureServer &fs,MixtureStat &emAcc,Seg* seg,Config &config){
00118   unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName());              // Find the index of the first frame of the file in the buffer
00119   return accumulateStatEM(ss,fs,emAcc,begin,seg->length(),config);
00120 }
00121 // One on Cluster
00122 double accumulateStatEMUnThreaded(StatServer &ss,FeatureServer &fs,MixtureStat &emAcc,SegCluster &selectedSegments,Config &config){
00123   double llkAcc=0.0;
00124   Seg* seg;                                                     // reset the reader at the begin of the input stream
00125   selectedSegments.rewind();      
00126   while((seg=selectedSegments.getSeg())!=NULL)                  // For each of the selected segments
00127     llkAcc+=accumulateStatEM(ss,fs,emAcc,seg,config);
00128   return llkAcc;
00129 }
00130 
00131 // Choose if its threaded or not here
00132 double accumulateStatEM(StatServer &ss,FeatureServer &fs,MixtureStat &emAcc,SegCluster &selectedSegments,Config &config){  
00133     double llkAcc=0.0;
00134     #if defined(THREAD)          
00135     if (config.existsParam("numThread") && config.getParam("numThread").toLong() >0) llkAcc=accumulateStatEMThreaded(ss,fs,emAcc,selectedSegments,config);                        // Compute EM statistics
00136     else llkAcc=accumulateStatEMUnThreaded(ss,fs,emAcc,selectedSegments,config);
00137     #else
00138    llkAcc= accumulateStatEMUnThreaded(ss,fs,emAcc,selectedSegments,config);            // Compute EM statistics
00139     #endif
00140   return llkAcc;
00141   }
00142 
00143   // With weight on a cluster
00144 double accumulateStatEM(StatServer &ss,FeatureServer &fs,MixtureStat &emAcc,SegCluster &selectedSegments,double & weight, Config &config){  
00145     double llkAcc=0.0;
00146     char cW[200];
00147     sprintf(cW,"%f",weight);
00148         String sW(cW);
00149     config.setParam("weightedEM","weight");
00150     if (verbose) cout << "Weighted EM with weight" << sW << endl;
00151     llkAcc= accumulateStatEM(ss,fs,emAcc,selectedSegments,config);
00152     return (weight*llkAcc);
00153   }
00154 // *****************************************************************************************************
00155 // ****************************** Threaded Version of Accumulate StatEM *********************************
00156 // **************************** Nicolas Scheffer, 16/02/2007 **********************************************
00157 #if defined(THREAD)
00158 pthread_mutex_t mutexsum; // lock variable
00159 bool stop=false; // flag variable once end of SegCluster is reached
00160 //******************** Data strucutre of thread **************************
00161 struct EMthread_data{
00162         SegCluster *selectedSegments;
00163         MixtureStat *emAcc;
00164          FeatureServer *fs;
00165         Config *config;
00166         double *llkAcc;
00167         RefVector <Feature> *featThreadBuff;
00168         unsigned long nThread;
00169 };
00170 // *********************** Routine **************************************
00171 static void *EMthread(void *threadarg) {
00172         struct EMthread_data *my_data;
00173         my_data = (struct EMthread_data *) threadarg;
00174         SegCluster &selectedSegments=*(my_data->selectedSegments);
00175         MixtureStat &emAcc=*(my_data->emAcc);
00176         FeatureServer &fs=*(my_data->fs);
00177         Config &config=*(my_data->config);
00178         unsigned long nT=my_data->nThread;
00179         double weight=1.0;
00180         if (config.existsParam("weightedEM")) weight=config.getParam("weightedEM").toDouble();
00181         // **************** Main loop
00182         Seg* seg;
00183         unsigned long  cnt=0;
00184         while(!stop)  {                // For each of the selected segments
00185              // ***************** Reading features is locked
00186             RefVector <Feature> featThreadBuff;          
00187             pthread_mutex_lock (&mutexsum);          
00188             if (stop) {pthread_mutex_unlock (&mutexsum);break;}                    
00189             cnt++;
00190             if ((seg=selectedSegments.getSeg())==NULL) {
00191               pthread_mutex_unlock (&mutexsum);
00192               if (verboseLevel >1) cout<<"Thread:"<<nT << " broke" << endl;
00193               stop=true;
00194               break;
00195             }
00196             unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName());
00197             fs.seekFeature(begin);             
00198             for (unsigned long j=0;j<seg->length();j++){            
00199               featThreadBuff.addObject(*(new Feature),j);
00200               fs.readFeature(featThreadBuff[j]);
00201             }
00202             pthread_mutex_unlock (&mutexsum);
00203              // ***************** End lock
00204             
00205             // ***************** Accumulate EM on the frameTab
00206             for (unsigned long j=0;j<seg->length();j++)
00207               (*(my_data->llkAcc))+=log(emAcc.computeAndAccumulateEM(featThreadBuff[j],weight));
00208             featThreadBuff.deleteAllObjects();                    
00209         }
00210         if (verboseLevel > 2) cout << "(AccumulateStatEM) Number of segments treated by thread ["<<nT<<"]="<<cnt<<endl;
00211         pthread_exit((void*) 0);
00212 }
00213 
00214 // Split selected cluster in nSplit clusters
00215 void splitSegCluster(SegCluster & selectedSegments,unsigned long nSplit,RefVector <SegCluster> &vSelected) {
00216   Seg* seg;
00217   unsigned long t=0;
00218   unsigned long offset=(totalFrame(selectedSegments))/nSplit;
00219   if (verbose) cout << "(AccumulateStatEM) Splitting cluster: Total["<<totalFrame(selectedSegments)<<"] "<<offset<<" frames/cluster"<<endl;
00220   unsigned long limit=offset-1;
00221   selectedSegments.rewind();   
00222   unsigned long cnt=0;
00223   while((seg=selectedSegments.getSeg())!=NULL) { 
00224     cnt+=seg->length();
00225     if (cnt>=limit) {
00226         if (verbose) cout<<"SegCluster["<<t<<"] full with "<<totalFrame(vSelected[t])<<" frames"<<endl;
00227         if (t!=nSplit-1) t++;cnt=0;
00228       }    
00229     vSelected[t].addCopy(*seg);
00230   }
00231 }
00232 
00233 //***************************Threaded version ***************************
00234 double accumulateStatEMThreaded(StatServer &ss,FeatureServer &fs,MixtureStat &emAcc,SegCluster &selectedSegments,Config &config){
00235   unsigned long NUM_THREADS=config.getParam("numThread").toLong();
00236   stop=false;
00237   if (verbose) cout << "(AccumulateStatEM) Threaded version of EM with "<<NUM_THREADS<<" threads"<<endl;
00238   double llkAcc=0.0;
00239   SegServer segServer;  
00240   //RefVector <SegCluster> vSelected;
00241   RefVector <MixtureStat> vEmAcc;    
00242   RealVector <double> vLlkAcc;  
00243   vLlkAcc.setSize(NUM_THREADS);
00244   vLlkAcc.setAllValues(0.0);
00245   selectedSegments.rewind();
00246   for(unsigned long t=0; t<NUM_THREADS; t++){
00247     /*vSelected.addObject(segServer.createCluster(selectedSegments.labelCode(),"",""),t);  
00248     vSelected[t].rewind();*/
00249     vEmAcc.addObject(ss.createAndStoreMixtureStat(emAcc.getMixture()),t);
00250     vEmAcc[t].resetEM();    
00251   }
00252   //splitSegCluster(selectedSegments,NUM_THREADS,vSelected);  
00253   struct EMthread_data thread_data_array[NUM_THREADS];
00254   pthread_t threads[NUM_THREADS];       
00255   pthread_attr_t attr;
00256   pthread_attr_init(&attr);
00257   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
00258   pthread_mutex_init(&mutexsum, NULL);
00259   int rc,status;
00260   for(unsigned long t=0; t<NUM_THREADS; t++){
00261     thread_data_array[t].selectedSegments=&selectedSegments;
00262     thread_data_array[t].emAcc=&vEmAcc[t];
00263     thread_data_array[t].fs=&fs;   
00264     thread_data_array[t].config=&config;
00265     thread_data_array[t].llkAcc=&vLlkAcc[t];
00266     thread_data_array[t].nThread=t;     
00267     if (verbose) cout<<"(AccumulateStatEM) Creating thread n["<< t<< "]"<<endl;    
00268     rc = pthread_create(&threads[t], &attr, EMthread, (void *)&thread_data_array[t]);           
00269     if (rc) throw Exception("ERROR; return code from pthread_create() is ",__FILE__,rc);
00270     }
00271     if (verbose) cout<<"(AccumulateStatEM) Computing on thread"<<endl;    
00272     pthread_attr_destroy(&attr);
00273     for(unsigned long t=0; t<NUM_THREADS; t++) {
00274       rc = pthread_join(threads[t], (void **)&status);
00275       if (rc)  throw Exception("ERROR; return code from pthread_join() is ",__FILE__,rc);
00276       if (verbose) cout <<"(AccumulateStatEM) Completed join with thread ["<<t<<"] status["<<status<<"]"<<endl;
00277     }
00278     if (verbose) cout <<"(AccumulateStatEM) Fuse EM Accs "<<endl;
00279       unsigned long total=0;
00280     for(unsigned long t=0; t<NUM_THREADS; t++) {
00281       if (verbose) cout << "Number of frames treated by thread ["<<t<<"]="<<vEmAcc[t].getEMFeatureCount()<<endl;
00282       total+=vEmAcc[t].getEMFeatureCount();
00283       emAcc.addAccEM(vEmAcc[t]);
00284       ss.deleteMixtureStat(vEmAcc[t]);
00285       llkAcc+=vLlkAcc[t];
00286     }
00287     cout << "Total Number of frames in threads: "<<total<<endl;
00288     pthread_mutex_destroy(&mutexsum);
00289 return llkAcc;
00290 }
00291 #endif
00292 // **************************** End ********************************
00293 
00294 /*Alex Preti things
00295 double accumulateStatEM(StatServer & ss, FeatureServer & fs,
00296   MixtureStat & emAcc, unsigned long idxBeginFrame, unsigned long nbFrames,
00297   double &weight, Config & config)
00298 {
00299   double llkAcc = 0.0;
00300   fs.seekFeature(idxBeginFrame);        // go to the frame in the buffer (and load it if needed)
00301   for (unsigned long n = 0; n < nbFrames; n++)
00302     {
00303       Feature f;
00304       fs.readFeature(f);
00305       llkAcc += log(emAcc.computeAndAccumulateEM(f, weight));
00306     }
00307   return (llkAcc * weight);
00308 }
00309 
00310 // one a Segment
00311 double accumulateStatEM(StatServer & ss, FeatureServer & fs,
00312   MixtureStat & emAcc, Seg * seg, double &weight, Config & config)
00313 {
00314   unsigned long begin = seg->begin() + fs.getFirstFeatureIndexOfASource(seg->sourceName());     // Find the index of the first frame of the file in the buffer
00315   return accumulateStatEM(ss, fs, emAcc, begin, seg->length(), weight,
00316     config);
00317 }
00318 
00319 // One on Cluster
00320 double accumulateStatEM(StatServer & ss, FeatureServer & fs,
00321   MixtureStat & emAcc, SegCluster & selectedSegments, double &weight,
00322   Config & config)
00323 {
00324   double llkAcc = 0.0;
00325   Seg *seg;                     // reset the reader at the begin of the input stream
00326   selectedSegments.rewind();
00327   while ((seg = selectedSegments.getSeg()) != NULL)     // For each of the selected segments
00328     llkAcc += accumulateStatEM(ss, fs, emAcc, seg, weight, config);
00329   return llkAcc;
00330 }*/
00331 
00332 
00333 //-------------------------------------------------------------------------
00334 //-- Accumulate the log likelihood for the selected frames and a given model, support weighted Feature Server (A.P)
00335 void accumulateStatLLK(StatServer & ss, FeatureServer & fs,
00336   MixtureStat & llkAcc, unsigned long idxBeginFrame, unsigned long nbFrames,
00337   double &weight, Config & config)
00338 {
00339   fs.seekFeature(idxBeginFrame);        // go to the frame in the buffer (and load it if needed)
00340   for (unsigned long n = 0; n < nbFrames; n++)
00341     {
00342       Feature f;
00343       if (fs.readFeature(f) == false)
00344         cout << "No more features" << endl;
00345 
00346       double toto = llkAcc.computeAndAccumulateLLK(f, weight);
00347       if (debug)
00348         cout << "likelihood Frame[" << idxBeginFrame +
00349           n << "]=" << toto << endl;
00350     }
00351 }
00352 
00353 // one a Segment, support weighted Feature Server (A.P)
00354 void accumulateStatLLK(StatServer & ss, FeatureServer & fs,
00355   MixtureStat & llkAcc, Seg * seg, double &weight, Config & config)
00356 {
00357   unsigned long begin = seg->begin() + fs.getFirstFeatureIndexOfASource(seg->sourceName());     // Find the index of the first frame of the file in the buffer
00358   accumulateStatLLK(ss, fs, llkAcc, begin, seg->length(), weight, config);
00359 }
00360 
00361 // One on Cluster, support weighted Feature Server (A.P)
00362 void accumulateStatLLK(StatServer & ss, FeatureServer & fs,
00363   MixtureStat & llkAcc, SegCluster & selectedSegments, double &weight,
00364   Config & config)
00365 {
00366   Seg *seg;                     // reset the reader at the begin of the input stream
00367   selectedSegments.rewind();
00368   while ((seg = selectedSegments.getSeg()) != NULL)     // For each of the selected segments
00369     accumulateStatLLK(ss, fs, llkAcc, seg, weight, config);
00370 }
00371 
00372 
00373 //-------------------------------------------------------------------------
00374 //-- accumulate the statistic on the frames (mean and cov), using a current 
00375 //-- FrameAcc
00376 //--
00377 //-- CAUTION: A COMPUTE_ALL AND A GET CALL SHOULD BE DONE AFTER THE CALLS  
00378 void accumulateStatFrame(FrameAcc & frameAcc,FeatureServer &fs,
00379                     unsigned long idxBeginFrame,unsigned long nbFrames,Config &config)
00380 {       
00381   fs.seekFeature(idxBeginFrame);                                           // go to the frame in the buffer (and load it if needed)
00382   Feature f;
00383   for (unsigned long n=0;n<nbFrames;n++){
00384     fs.readFeature(f);
00385     frameAcc.accumulate(f);
00386   }
00387 }
00388 // one a Segment
00389 void accumulateStatFrame(FrameAcc & frameAcc,FeatureServer &fs,Seg* seg,Config &config)
00390 {
00391   unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName());              // Find the index of the first frame of the file in the buffer
00392   accumulateStatFrame(frameAcc,fs,begin,seg->length(),config);
00393 }
00394 // One on Cluster
00395 void accumulateStatFrame(FrameAcc &frameAcc,FeatureServer &fs,SegCluster &selectedSegments,Config &config)
00396 {
00397   Seg* seg;                                                     // reset the reader at the begin of the input stream
00398   selectedSegments.rewind();      
00399   while((seg=selectedSegments.getSeg())!=NULL)                  // For each of the selected segments
00400     accumulateStatFrame(frameAcc,fs,seg,config);
00401 }
00402 
00403 
00404 //-------------------------------------------------------------------------
00405 //-- accumulate the statistic on the frames raw distribution of each coefficient
00406 //-- CAUTION: 
00407 //         *THE ACCUMULATOR SHOULD BE INITIALIZED BEFORE THE FIRST CALL
00408 //          initHistoTab()
00409 //         *THE HISTO SHOULD BE COMPUTED BEFORE TO USE THE STAT
00410 //          computeHistoTab()
00411 //         *The histoTab should be freezen after use
00412 //          freezeHistoTab();
00413 //      
00414 // Init the Histo array (one by coeff)
00415 double areaHisto(const Histo & histo,unsigned long bin)
00416 {
00417   return  histo.count(bin)*(histo.higherBound(bin)-histo.lowerBound(bin));
00418 }
00419 double areaHisto(const Histo & histo,unsigned long bin, double nonObserved)
00420 {
00421   return areaHisto(histo,bin)*(1-nonObserved) ;
00422 }
00423 double linearInterpolation(double val,double lower,double higher){
00424   const double EPS=0.000000000000000000001;
00425   double interval=higher-lower;
00426   if (interval<EPS) return 1;
00427   return (val-lower)/interval;
00428 } 
00429 void freezeHistoTab(Histo* &histoT)
00430 {
00431   delete []histoT;
00432 }
00433 void initHistoTab(Histo* &histoT,unsigned long size, unsigned long nbBins)
00434 {
00435   Histo tmp(nbBins);
00436   histoT=new Histo[size];
00437   for (unsigned long i=0;i<size;i++) histoT[i]=tmp;
00438 }
00439 void computeHistoTab(Histo* histoT,unsigned long size)
00440 {
00441   for (unsigned long i=0;i<size;i++) histoT[i].computeHisto();
00442 }
00443 
00444 void accumulateHistoFrame(Histo  *histoT,FeatureServer &fs,
00445                     unsigned long idxBeginFrame,unsigned long nbFrames,Config &config)
00446 {       
00447   fs.seekFeature(idxBeginFrame);                                           // go to the frame in the buffer (and load it if needed)
00448   Feature f;
00449   for (unsigned long n=0;n<nbFrames;n++){
00450     fs.readFeature(f);
00451     for (unsigned long c=0;c<fs.getVectSize();c++)
00452       histoT[c].accumulateValue(f[c]);
00453   }
00454 }
00455 // one a Segment
00456 void accumulateHistoFrame(Histo *histoT,FeatureServer &fs,Seg* seg,Config &config)
00457 {
00458   unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName());// Find the index of the first frame of the file in the buffer
00459   accumulateHistoFrame(histoT,fs,begin,seg->length(),config);
00460 }
00461 // One on Cluster
00462 void accumulateHistoFrame(Histo *histoT,FeatureServer &fs,SegCluster &selectedSegments,Config &config)
00463 {
00464   Seg* seg;                                                     // reset the reader at the begin of the input stream
00465   selectedSegments.rewind();      
00466   while((seg=selectedSegments.getSeg())!=NULL)                  // For each of the selected segments
00467     accumulateHistoFrame(histoT,fs,seg,config);
00468 }
00469 
00470 
00471 #endif //!defined(ALIZE_AccumulateStat_cpp)
00472 
00473