Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

average_Filter.cpp

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission :
00003         Realtime Vision Processing System
00004 
00005     Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008 
00009     This file is part of Phission.
00010 
00011     Phission is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU Lesser General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     Phission is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU Lesser General Public License for more details.
00020 
00021     You should have received a copy of the GNU Lesser General Public License
00022     along with Phission; if not, write to the Free Software
00023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025  ---------------------------------------------------------------------------*/
00026 #ifdef HAVE_CONFIG_H
00027     #include <phissionconfig.h>
00028 #endif
00029 
00030 #include <phStandard.h>
00031 
00032 #include <average_Filter.h>
00033 
00034 #include <phError.h>
00035 #include <phMemory.h>
00036 #include <phPrint.h>
00037 
00038 /* ---------------------------------------------------------------------- */
00039 /* ---------------------------------------------------------------------- */
00040 average_Filter::average_Filter( uint32_t nFrames ) :
00041     phFilter("average_Filter")
00042 
00043 {
00044     this->m_nFrames             = 2;
00045     this->m_total_stored        = 0;
00046     this->m_first_frame_index   = 0;
00047     this->m_current_frame_index = 0;
00048     
00049     this->m_frame_elems         = 0;
00050     this->m_frame_size          = 0;
00051     
00052     this->m_imgptrs             = NULL;
00053     this->m_imgptrs_size        = 0;
00054     this->m_buffer              = NULL;
00055     this->m_buffer_size         = 0;
00056     this->m_outputBuffer        = NULL;
00057     this->m_outputBuffer_size   = 0;
00058 
00059     this->m_last_result             = NULL;
00060     this->m_last_result_size        = 0;
00061     this->m_last_result_weight      = NULL;
00062     this->m_last_result_weight_size = 0;
00063 
00064     this->m_temp                = NULL;
00065     this->m_temp_size           = 0;
00066 
00067     this->m_buf_height          = 0;
00068     this->m_buf_width           = 0;
00069     this->m_buf_depth           = 0;
00070     this->m_buf_format          = phImageNOFORMAT;
00071     this->m_buf_nframes         = 2;
00072 
00073     
00074     this->m_format =  phImagePackedFormatMask;
00075 
00076     this->set(nFrames);
00077 }
00078 
00079 /* ---------------------------------------------------------------------- */
00080 average_Filter::~average_Filter()
00081 {
00082     phFree(this->m_temp);
00083     phFree(this->m_last_result);
00084     phFree(this->m_last_result_weight);
00085     phFree(this->m_buffer);
00086     phFree(this->m_imgptrs);
00087 }
00088 
00089 /* ------------------------------------------------------------------------ */
00090 phFilter *average_Filter::cloneFilter()
00091 {
00092     phFUNCTION("average_Filter::cloneFilter")
00093     int locked = 0;
00094     average_Filter *ave = new average_Filter();
00095 
00096     phTHIS_LOOSE_LOCK(locked);
00097     
00098     ave->set(this->m_nFrames);
00099 
00100     phTHIS_LOOSE_UNLOCK(locked);
00101 
00102     return (phFilter *)ave;
00103 }
00104 
00105 /* ---------------------------------------------------------------------- */
00106 int average_Filter::set( uint32_t nFrames )
00107 {
00108     phFUNCTION("average_Filter::set")
00109     int locked = 0;
00110 
00111     phTHIS_LOOSE_LOCK(locked);
00112 
00113     this->m_nFrames = nFrames;
00114     
00115     phTHIS_LOOSE_UNLOCK(locked);
00116     
00117     return phSUCCESS;
00118 }
00119 /* ---------------------------------------------------------------------- */
00120 /* this method resets all the variables required to start the filter anew */
00121 /* ---------------------------------------------------------------------- */
00122 int average_Filter::flush()
00123 {
00124     phFUNCTION("average_Filter::flush")
00125     int locked = 0;
00126 
00127     phTHIS_LOOSE_LOCK(locked);
00128 
00129     /* erased the buffers and reset all the vars */
00130     this->check_buffers(1);
00131     
00132     phTHIS_LOOSE_UNLOCK(locked);
00133 
00134     return phSUCCESS;
00135 }
00136 
00137 /* ---------------------------------------------------------------------- */
00138 /* This function checks to make sure the buffers have been initialized
00139  * and allocates memory if they haven't. This also checks to see if the
00140  * size of the image has changed: if it has, then it has to flush the 
00141  * buffers. */
00142 /* ---------------------------------------------------------------------- */
00143 int average_Filter::check_buffers(uint32_t alloc)
00144 {
00145     phFUNCTION("average_Filter::check_buffers")
00146     uint32_t i = 0;
00147 
00148     /* check to see if the buffer needs to be allocated */
00149     if (this->m_buffer == NULL)
00150     {
00151         alloc = 1;
00152     }
00153     /* Check to see if one of the parameters has changed */
00154     else if ((this->m_buf_height    != height)  ||
00155              (this->m_buf_width     != width)   ||
00156              (this->m_buf_depth     != depth)   || 
00157              (this->m_buf_format    != format)  ||
00158              (this->m_buf_nframes   != this->m_nFrames))
00159     {
00160         alloc = 1;
00161     }
00162     
00163     /* height, width and depth are set by 'process' */
00164     if (((height > 0) && (width > 0) && (depth > 0)) && (alloc))
00165     {
00166         this->m_frame_elems = height * width * depth;
00167         
00168         this->m_buf_height  = height;
00169         this->m_buf_width   = width;
00170         this->m_buf_depth   = depth;
00171         this->m_buf_format  = format;
00172         this->m_buf_nframes = this->m_nFrames;
00173         
00174         phDALLOC_RESIZE( this->m_last_result,
00175                          this->m_last_result_size,
00176                          this->m_frame_elems,
00177                          double);
00178         
00179         phDALLOC_RESIZE( this->m_last_result_weight,
00180                          this->m_last_result_size,
00181                          this->m_buf_nframes,
00182                          double);
00183         
00184         phDALLOC_RESIZE( this->m_temp,
00185                          this->m_temp_size,
00186                          this->m_frame_elems,
00187                          uint8_t);
00188         
00189         /* allocate one chunk of memory for all the stored frame buffers
00190          * being differenced */
00191         phDALLOC( this->m_buffer,
00192                   this->m_buffer_size,
00193                   (this->m_frame_elems * this->m_buf_nframes),
00194                   uint8_t );
00195         phDALLOC_RESIZE(  this->m_imgptrs,
00196                           this->m_imgptrs_size,
00197                           this->m_buf_nframes,
00198                           uint8_t * );
00199         
00200         this->m_frame_size = this->m_frame_elems * sizeof(uint8_t);
00201         
00202         for (i = 0; i < this->m_nFrames; i++)
00203         {
00204             this->m_imgptrs[i] = this->m_buffer + 
00205                                  (this->m_frame_size * i);
00206         }
00207 
00208 /* Not being used; If one decides they want to use this, instead of writing
00209  * to Image below (in the 'filter') function, write to this buffer and then
00210  * maybe phMemcpy to Image */
00211 /*
00212         phDALLOC( this->m_outputBuffer,
00213                   this->m_outputBuffer_size,
00214                   this->m_frame_elems,
00215                   uint8_t );
00216 */        
00217         /* preping the filter to wait for nFrames again before differencing 
00218          * those frames.
00219          * Need to reset this if we've reallocated buffers. Something TODO
00220          * might be to find out if this is really necessary or a 
00221          * way to allow reallocation without complete reset. Currently,
00222          * this is just being super-extra-doubly sure things work right
00223          * by limiting the filter with such an action. */
00224         this->m_total_stored = 0;
00225         this->m_first_frame_index = 0;
00226         this->m_current_frame_index = 0;
00227     }
00228     
00229     return phSUCCESS;
00230 error:
00231     return phFAIL;
00232 }
00233 
00234 /* ---------------------------------------------------------------------- */
00235 /* 'process' locks the object before calling 'filter' */
00236 /* ---------------------------------------------------------------------- */
00237 int average_Filter::filter()
00238 {
00239     phFUNCTION("average_Filter::filter")
00240     uint32_t j = 0;
00241     double X = 0;
00242     
00243     double  weight = 0.0;
00244     int32_t oldest_index    = 0;
00245     uint8_t *oldest_frame = NULL;
00246     double  oldest_weight   = 0.0;
00247 
00248     /* defined before being called:
00249      *  width
00250      *  height
00251      *  depth
00252      *  Image
00253      */
00254 
00255     /* 0.) Allocate the required space to store up nFrames before 
00256      * differencing them */
00257     this->check_buffers();
00258     
00259     /* Begin Filter */
00260     
00261     /* copy the current frame into the buffer and adjust the 
00262      * index pointers to the first and last frames */
00263     phMemcpy(this->m_temp,
00264              Image,
00265              this->m_frame_size);
00266     
00267     weight = (1.0 / ((double)this->m_buf_nframes));   
00268     oldest_index = ((int32_t)this->m_current_frame_index + 1) % this->m_buf_nframes;
00269     oldest_weight = this->m_last_result_weight[oldest_index];
00270     oldest_frame = this->m_imgptrs[oldest_index];
00271 
00272     for (j = 0; j < this->m_frame_elems; j++)
00273     {
00274         X = this->m_last_result[j];
00275         X -= (((double)oldest_frame[j]) * oldest_weight);
00276         X += (((double)Image[j])) * weight;
00277         
00278         this->m_last_result[j] = X;
00279         
00280         X = (X > 255) ? 255 : X;
00281         Image[j] = (uint8_t)X;
00282     }    
00283 
00284     this->m_last_result_weight[this->m_current_frame_index] = weight;
00285         
00286     /* copy the current frame into the buffer and adjust the 
00287      * index pointers to the first and last frames */
00288     phMemcpy(this->m_imgptrs[this->m_current_frame_index],
00289              this->m_temp,
00290              this->m_frame_size);
00291     
00292     this->m_current_frame_index = (this->m_current_frame_index+1) %
00293                                    this->m_buf_nframes;
00294     
00295     /* End Filter */
00296     
00297     /* make sure to free up any space here, not including Image */
00298     
00299     return phSUCCESS;
00300 #if 0
00301 error:
00302     /* make sure to free up any space here, not including Image */
00303     
00304     return phFAIL;
00305 #endif
00306 }
00307 
00308 




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:08 2007 for phission by  doxygen 1.4.4