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

add_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 <add_Filter.h>
00033 
00034 #include <phError.h>
00035 #include <phMemory.h>
00036 #include <phPrint.h>
00037 
00038 /* ------------------------------------------------------------------------ */
00039 add_Filter::add_Filter( uint32_t nFrames,
00040                         uint32_t frame_step ) :
00041     phFilter("add_Filter")
00042 
00043 {
00044     if (nFrames < 2)    nFrames     = 2;
00045     if (frame_step < 1) frame_step  = 1;
00046 
00047     this->m_nFrames             = nFrames;
00048     this->m_frame_step          = frame_step;
00049     this->m_total_stored        = 0;
00050     this->m_first_frame_index   = 0;
00051     this->m_current_frame_index = 0;
00052     
00053     this->m_frame_elems         = 0;
00054     this->m_frame_size          = 0;
00055     
00056     this->m_imgptrs             = NULL;
00057     this->m_imgptrs_size        = 0;
00058     this->m_buffer              = NULL;
00059     this->m_buffer_size         = 0;
00060     this->m_outputBuffer        = NULL;
00061     this->m_outputBuffer_size   = 0;
00062 
00063     /* These are initialized to 0 because they will be set in check_buffers */
00064     this->m_buf_height          = 0;
00065     this->m_buf_width           = 0;
00066     this->m_buf_depth           = 0;
00067     this->m_buf_format          = phImageNOFORMAT;
00068     this->m_buf_nframes         = 0;
00069     this->m_buf_step            = 0;
00070     
00071 
00072     this->m_format =  phImagePackedFormatMask;
00073     
00074     this->set(nFrames,frame_step);
00075 }
00076 
00077 /* ------------------------------------------------------------------------ */
00078 add_Filter::~add_Filter()
00079 {
00080     phFree(this->m_buffer);
00081     phFree(this->m_imgptrs);
00082 }
00083 
00084 /* ------------------------------------------------------------------------ */
00085 phFilter *add_Filter::cloneFilter()
00086 {
00087     phFUNCTION("add_Filter::cloneFilter")
00088     int locked = 0;
00089     add_Filter *add = new add_Filter();
00090     
00091     phTHIS_LOOSE_LOCK(locked);
00092     
00093     add->set(this->m_nFrames,this->m_frame_step);
00094     
00095     phTHIS_LOOSE_UNLOCK(locked);
00096     
00097     return (phFilter *)add;
00098 }
00099 
00100 /* ------------------------------------------------------------------------ */
00101 int add_Filter::set( uint32_t nFrames,
00102                      uint32_t frame_step )
00103 {
00104     phFUNCTION("add_Filter::set")
00105     int locked = 0;
00106 
00107     phTHIS_LOOSE_LOCK(locked);
00108 
00109     if (nFrames < 2)    nFrames     = 2;
00110     if (frame_step < 1) frame_step  = 1;
00111 
00112     this->m_nFrames     = nFrames;
00113     this->m_frame_step  = frame_step;
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 add_Filter::flush()
00123 {
00124     phFUNCTION("add_Filter::flush")
00125 
00126     rc = this->lock();
00127     phPRINT_RC(rc,NULL,"this->lock()");
00128 
00129     /* erased the buffers and reset all the vars */
00130     this->check_buffers(1);
00131     
00132     rc = this->unlock();
00133     phPRINT_RC(rc,NULL,"this->unlock()");
00134 
00135     return phSUCCESS;
00136 }
00137 
00138 /* ---------------------------------------------------------------------- */
00139 /* This function checks to make sure the buffers have been initialized
00140  * and allocates memory if they haven't. This also checks to see if the
00141  * size of the image has changed: if it has, then it has to flush the 
00142  * buffers. */
00143 /* ---------------------------------------------------------------------- */
00144 int add_Filter::check_buffers(uint32_t alloc)
00145 {
00146     phFUNCTION("add_Filter::check_buffers")
00147     uint32_t i = 0;
00148 
00149     /* check to see if the buffer needs to be allocated */
00150     if (this->m_buffer == NULL)
00151     {
00152         alloc = 1;
00153     }
00154     /* Check to see if the image dimensions have changed */
00155     else if ((this->m_buf_height    != height)              ||
00156              (this->m_buf_width     != width)               ||
00157              (this->m_buf_depth     != depth)               || 
00158              (this->m_buf_format    != format))
00159     {
00160         alloc = 1;
00161     }
00162     /* Check to see if one of the parameters has changed */
00163     else if ((this->m_buf_nframes   != this->m_nFrames)     || 
00164              (this->m_buf_step      != this->m_frame_step))
00165     {
00166         alloc = 2;
00167     }
00168     
00169     /* height, width and depth are set by 'process' */
00170     if (((height > 0U) && (width > 0U) && (depth > 0U)) && (alloc))
00171     {
00176         /* The number of stored frames depends on how many frames we're
00177          * adding and the frame step used */
00178         this->m_buf_nframes = (((this->m_nFrames-1) * this->m_frame_step))+1;
00179 
00184         this->m_add_nframes     = this->m_nFrames;
00188         this->m_buf_step        = this->m_frame_step;
00189 
00190         /* The number of elements/pixels for each frame */
00191         this->m_frame_elems = height * width * depth;
00192         
00199         /* allocate one chunk of memory for all the stored frame buffers
00200          * being differenced */
00201         phDALLOC( this->m_buffer,
00202                   this->m_buffer_size,
00203                   (this->m_frame_elems * this->m_buf_nframes),
00204                   uint8_t);
00205         /* m_imgptrs is an array of pointers into m_buffer */
00206         phDALLOC_RESIZE( this->m_imgptrs,
00207                          this->m_imgptrs_size,
00208                          this->m_buf_nframes,
00209                          uint8_t * );
00210         
00211         /* This is the size in bytes of one frame */
00212         this->m_frame_size = this->m_frame_elems * sizeof(uint8_t);
00213         
00214         /* Set the pointers to individual buffers into the imgptrs 
00215          * array */
00216         for (i = 0; i < this->m_buf_nframes; i++)
00217         {
00218             this->m_imgptrs[i] = this->m_buffer + 
00219                                  (this->m_frame_size * i);
00220         }
00221 
00222         /* Not being used; If one decides they want to use this, instead of writing
00223          * to Image below (in the 'filter') function, write to this buffer and then
00224          * maybe phMemcpy to Image */
00225         /*
00226         phDALLOC( this->m_outputBuffer,
00227                   this->m_outputBuffer_size,
00228                   this->m_frame_elems,
00229                   uint8_t );
00230          */        
00231         /* preping the filter to wait for nFrames again before differencing 
00232          * those frames.
00233          * Need to reset this if we've reallocated buffers. 
00234          *
00235          * Something TODO might be to find out if this is really 
00236          * necessary or a  way to allow reallocation without complete 
00237          * reset. Currently, this is just being super-extra-doubly sure 
00238          * things work right by limiting the filter with such an action. */
00239         this->m_total_stored        = 0;
00240         this->m_first_frame_index   = 0;
00241         this->m_current_frame_index = 0;
00242 
00243         /* \var m_buf_height
00244          * This stores the height of the frames which comes from the
00245          * phFilter parent class member variable 'height' */
00246         this->m_buf_height      = height;
00247         /* \var m_buf_width
00248          * This stores the height of the frames which comes from the
00249          * phFilter parent class member variable 'width' */
00250         this->m_buf_width       = width;
00251         /* \var m_buf_depth
00252          * This stores the height of the frames which comes from the
00253          * phFilter parent class member variable 'depth' */
00254         this->m_buf_depth       = depth;
00255         /* \var m_buf_format
00256          * This stores the height of the frames which comes from the
00257          * phFilter parent class member variable 'format' */
00258         this->m_buf_format      = format;
00259                                           /*...and all are set by phPipline */
00260     }
00261     
00262     return phSUCCESS;
00263 error:
00264     return phFAIL;
00265 }
00266 
00267 /* ---------------------------------------------------------------------- */
00268 /* 'process' locks the object before calling 'filter' */
00269 /* ---------------------------------------------------------------------- */
00270 int add_Filter::filter()
00271 {
00272     phFUNCTION("add_Filter::filter")
00273     uint32_t    i = 0;
00274     uint32_t    j = 0;
00275     uint32_t    index = 0;
00276     uint8_t    *frameX = NULL;
00277     uint8_t    *frameY = NULL;
00278     int32_t     Z = 0;
00279 
00280     /* defined before being called:
00281      *  width
00282      *  height
00283      *  depth
00284      *  Image
00285      */
00286 
00287     /* 0.) Allocate the required space to store up nFrames before 
00288      * differencing them */
00289     this->check_buffers();
00290     
00291     /* Begin Filter */
00292     
00293     /* copy the current frame into the buffer and adjust the 
00294      * index pointers to the first and last frames */
00295     phMemcpy(this->m_imgptrs[this->m_current_frame_index],
00296              Image,
00297              this->m_frame_size);
00298     
00299     /* Increment the total_stored variable to keep track of when
00300      * we've seen enough frames to complete the sequence */
00301     if (this->m_total_stored < this->m_buf_nframes)
00302     {
00303         this->m_total_stored++;
00304     }
00305     
00306     if (this->m_total_stored == this->m_buf_nframes)
00307     {
00308         /* add all the frames from the first buffer to the last
00309          * buffer, in order. m_first_frame_index is either initialized
00310          * from check_buffers() or updated from the previous iteration
00311          * of add_Filter::filter() */
00312         index = this->m_first_frame_index;
00313         
00314         /* 'nFrames - 1' because we only make 1 addition for
00315          * every pairing of consecutive frames:
00316          *  Y - X
00317          *      Y - X
00318          *          Y - X
00319          *  \/  \/  \/  \/-----5 frames, 4 additions 
00320          * 1...2...3...4...5                                            */
00321         for (i = 0; i < this->m_add_nframes - 1; i++ )
00322         {
00323             /* When we're adding, after the first addition we can add
00324              * to the cumulative sum of the output workspace pointed to
00325              * by Image */
00326             if (i > 0)
00327                 frameY = Image;
00328             /* The first time through we need to the first image to begin
00329              * the cumulative addition in the workspace. The index value
00330              * will always be within bounds because the addition/incrementing
00331              * of index will be %ed into the bounds. */
00332             else
00333                 frameY = this->m_imgptrs[index];
00334             
00335             /* Since we're using the current index buffer for frameY when
00336              * i == 0, we need to increment index for frameX so it points to 
00337              * next buffer in the sequence. Otherwise we just need to
00338              * increment it so that we're adding a different frame than the
00339              * last iteration of the add_Filter::filter method */
00340             index = (index + this->m_buf_step) % this->m_buf_nframes;
00341             
00342             /* This is the second,third,fouth,etc. frame being added
00343              * to the cumulative workspace value. */
00344             frameX = this->m_imgptrs[index];
00345         
00346             for (j = 0; j < this->m_frame_elems; j++)
00347             {
00348                 Z = ((int32_t)frameX[j]) + ((int32_t)frameY[j]);
00349                 Image[j] = (Z > 255) ? 255 : Z;
00350             }
00351         }
00352 
00353         /* set the first buffer to one ahead so that there is room
00354          * next time around for the current_frame */
00355         /* set the current_frame_index one ahead to overwrite the 
00356          * oldest frame. (this is a circular buffer) */
00357         this->m_first_frame_index = (this->m_first_frame_index+1) %
00358                                      this->m_buf_nframes;
00359     }    
00360        
00361     /* Update where we'll write Image to during the next iteration */
00362     this->m_current_frame_index = (this->m_current_frame_index+1) %
00363                                    this->m_buf_nframes;
00364     
00365     /* End Filter */
00366     
00367     /* make sure to free up any space here, not including Image */
00368     
00369     return phSUCCESS;
00370 #if 0
00371 error:
00372     /* make sure to free up any space here, not including Image */
00373     
00374     return phFAIL;
00375 #endif
00376 }
00377 
00378 




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