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

subtract_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 <subtract_Filter.h>
00033 
00034 #include <phError.h>
00035 #include <phMemory.h>
00036 #include <phPrint.h>
00037 
00038 /* ---------------------------------------------------------------------- */
00039 /* ---------------------------------------------------------------------- */
00040 subtract_Filter::subtract_Filter(uint32_t nFrames,
00041                                  uint32_t frame_step,
00042                                  uint32_t group_step ) :
00043     phFilter("subtract_Filter")
00044 
00045 {
00046     this->m_nFrames = 2;
00047     this->m_frame_step = 1;
00048     this->m_total_stored = 0;
00049     this->m_first_frame_index = 0;
00050     this->m_current_frame_index = 0;
00051     
00052     this->m_frame_elems = 0;
00053     this->m_frame_size = 0;
00054     
00055     this->m_imgptrs = NULL;
00056     this->m_imgptrs_size = 0;
00057     this->m_buffer = NULL;
00058     this->m_buffer_size = 0;
00059     this->m_outputBuffer = NULL;
00060     this->m_outputBuffer_size = 0;
00061 
00062     this->m_buf_height  = 0;
00063     this->m_buf_width   = 0;
00064     this->m_buf_depth   = 0;
00065     this->m_buf_format  = phImageNOFORMAT;
00066     this->m_buf_nframes = 2;
00067     this->m_buf_step    = 1;
00068     this->m_group_step  = 1;
00069 
00070     
00071     this->m_format = phImageRGB24 | phImageRGBA32 | phImageBGR24 | phImageABGR32 |
00072                      phImageGREY8 | phImageHSV24;
00073     this->set(nFrames,frame_step,group_step);
00074 }
00075 
00076 /* ---------------------------------------------------------------------- */
00077 subtract_Filter::~subtract_Filter()
00078 {
00079     phFree(this->m_buffer);
00080     phFree(this->m_imgptrs);
00081 }
00082 
00083 /* ------------------------------------------------------------------------ */
00084 phFilter *subtract_Filter::cloneFilter()
00085 {
00086     return (phFilter *)new subtract_Filter( this->m_nFrames,
00087                                             this->m_frame_step,
00088                                             this->m_group_step );
00089 }
00090 
00091 /* ---------------------------------------------------------------------- */
00092 int subtract_Filter::set( uint32_t nFrames,
00093                           uint32_t frame_step,
00094                           uint32_t group_step )
00095 {
00096     phFUNCTION("subtract_Filter::set")
00097 
00098     rc = this->lock();
00099     phPRINT_RC(rc,NULL,"this->lock()");
00100 
00101     if (frame_step > nFrames)
00102         nFrames = frame_step;
00103         
00104     this->m_nFrames     = nFrames;
00105     this->m_frame_step  = frame_step;
00106     this->m_group_step  = group_step;
00107     
00108     rc = this->unlock();
00109     phPRINT_RC(rc,NULL,"this->unlock()");
00110     
00111     return phSUCCESS;
00112 }
00113 /* ---------------------------------------------------------------------- */
00114 /* this method resets all the variables required to start the filter anew */
00115 /* ---------------------------------------------------------------------- */
00116 int subtract_Filter::flush()
00117 {
00118     phFUNCTION("subtract_Filter::flush")
00119 
00120     rc = this->lock();
00121     phPRINT_RC(rc,NULL,"this->lock()");
00122 
00123     /* erased the buffers and reset all the vars */
00124     this->check_buffers(1);
00125     
00126     rc = this->unlock();
00127     phPRINT_RC(rc,NULL,"this->unlock()");
00128 
00129     return phSUCCESS;
00130 }
00131 
00132 /* ---------------------------------------------------------------------- */
00133 /* This function checks to make sure the buffers have been initialized
00134  * and allocates memory if they haven't. This also checks to see if the
00135  * size of the image has changed: if it has, then it has to flush the 
00136  * buffers. */
00137 /* ---------------------------------------------------------------------- */
00138 int subtract_Filter::check_buffers(uint32_t alloc)
00139 {
00140     phFUNCTION("subtract_Filter::check_buffers")
00141     uint32_t i = 0;
00142 
00143     /* check to see if the buffer needs to be allocated */
00144     if (this->m_buffer == NULL)
00145     {
00146         alloc = 1;
00147     }
00148     /* Check to see if one of the parameters has changed */
00149     else if ((this->m_buf_height != height) ||
00150              (this->m_buf_width != width) ||
00151              (this->m_buf_depth != depth) || 
00152              (this->m_buf_format != format) ||
00153              ((this->m_buf_nframes / this->m_buf_step) != this->m_nFrames) || 
00154              (this->m_buf_step != this->m_frame_step))
00155     {
00156         alloc = 1;
00157     }
00158     
00159     /* height, width and depth are set by 'process' */
00160     if (((height > 0) && (width > 0) && (depth > 0)) && (alloc))
00161     {
00162         this->m_frame_elems = height * width * depth;
00163         this->m_buf_nframes = this->m_nFrames * this->m_frame_step;
00164 
00165         /* allocate one chunk of memory for all the stored frame buffers
00166          * being differenced */
00167         phDALLOC_RESIZE(this->m_buffer,
00168                         this->m_buffer_size,
00169                         (this->m_frame_elems * this->m_buf_nframes),
00170                         uint8_t);
00171         phDALLOC_RESIZE(this->m_imgptrs,
00172                         this->m_imgptrs_size,
00173                         this->m_buf_nframes,
00174                         uint8_t * );
00175         
00176         this->m_frame_size = this->m_frame_elems * sizeof(uint8_t);
00177         
00178         for (i = 0; i < this->m_buf_nframes; i++)
00179         {
00180             this->m_imgptrs[i] = this->m_buffer + 
00181                                  (this->m_frame_size * i);
00182         }
00183 
00184         this->m_buf_height  = height;
00185         this->m_buf_width   = width;
00186         this->m_buf_depth   = depth;
00187         this->m_buf_format  = format;
00188         this->m_buf_step    = this->m_frame_step;
00189 /* Not being used; If one decides they want to use this, instead of writing
00190  * to Image below (in the 'filter') function, write to this buffer and then
00191  * maybe phMemcpy to Image */
00192 /*
00193         phDALLOC_RESIZE( this->m_outputBuffer,
00194                     this->m_outputBuffer_size,
00195                     this->m_frame_elems,
00196                     uint8_t );
00197 */        
00198         /* preping the filter to wait for nFrames again before differencing 
00199          * those frames.
00200          * Need to reset this if we've reallocated buffers. Something TODO
00201          * might be to find out if this is really necessary or a 
00202          * way to allow reallocation without complete reset. Currently,
00203          * this is just being super-extra-doubly sure things work right
00204          * by limiting the filter with such an action. */
00205         this->m_total_stored = 0;
00206         this->m_first_frame_index = 0;
00207         this->m_current_frame_index = 0;
00208     }
00209     
00210     return phSUCCESS;
00211 error:
00212     return phFAIL;
00213 }
00214 
00215 /* ---------------------------------------------------------------------- */
00216 /* 'process' locks the object before calling 'filter' */
00217 /* ---------------------------------------------------------------------- */
00218 int subtract_Filter::filter()
00219 {
00220     phFUNCTION("subtract_Filter::filter")
00221     uint32_t i = 0;
00222     uint32_t j = 0;
00223     uint32_t index = 0;
00224     uint8_t *frameX = NULL;
00225     uint8_t *frameY = NULL;
00226     int32_t X = 0;
00227     int32_t Y = 0;
00228     int32_t Z = 0;
00229 
00230     /* defined before being called:
00231      *  width
00232      *  height
00233      *  depth
00234      *  Image
00235      */
00236 
00237     /* 0.) Allocate the required space to store up nFrames before 
00238      * differencing them */
00239     this->check_buffers();
00240     
00241     /* Begin Filter */
00242     
00243     /* copy the current frame into the buffer and adjust the 
00244      * index pointers to the first and last frames */
00245     phMemcpy(this->m_imgptrs[this->m_current_frame_index],
00246            Image,
00247            this->m_frame_size);
00248     
00249     if (this->m_total_stored < this->m_buf_nframes)
00250     {
00251         this->m_total_stored++;
00252     }
00253     
00254     if (this->m_total_stored == this->m_buf_nframes)
00255     {
00256         /* subtract all the frames from the first buffer to the last
00257          * buffer, in order */
00258         index = this->m_first_frame_index;
00259         
00260         /* 'nFrames - 1' because we only make 1 subtraction for
00261          * every pairing of consecutive frames:
00262          *  Y - X
00263          *      Y - X
00264          *          Y - X
00265          *  \/  \/  \/  \/-----5 frames, 4 subtractions 
00266          * 1...2...3...4...5                                            */
00267         for (i = 0; i < (this->m_buf_nframes - 1); i += this->m_buf_step)
00268         {
00269             if (i > 0)
00270                 frameY = Image;
00271             else
00272                 frameY = this->m_imgptrs[index % this->m_buf_nframes];
00273             
00274             frameX = this->m_imgptrs[((index + 1) % this->m_buf_nframes)];
00275         
00276             for (j = 0; j < this->m_frame_elems; j++)
00277             {
00278                 X = frameX[j];
00279                 Y = frameY[j];
00280                 Z = X-Y;
00281                 
00282                 /* X FROM Y : CURRENT FROM PREVIOUS */
00283                 Image[j] = phMAX(Y-X,0);
00284                 
00285 
00286                 /* These 2 don't work right for some reason */
00287                 
00288                 /* Y FROM X : PREVIOUS FROM CURRENT */
00289                 //Image[j] = phMAX(X-Y,0);
00290                 
00291                 /* Absolute difference */
00292                 //if (Z < 0) Z *= -1;
00293                 //Image[j] = Z;
00294             }
00295             
00296             index++;
00297             index = index % this->m_buf_nframes;
00298         }
00299 
00300         /* set the first buffer to one ahead so that there is room
00301          * next time around for the current_frame */
00302         /* set the current_frame_index one ahead to overwrite the 
00303          * oldest frame. (this is a circular buffer) */
00304         this->m_first_frame_index = (this->m_first_frame_index+this->m_group_step) %
00305                                     this->m_buf_nframes;
00306 
00307         if ((this->m_group_step) >= this->m_buf_nframes)
00308         {
00309             this->m_total_stored = 0;
00310         }
00311         else
00312         {
00313             this->m_total_stored -= (this->m_group_step);
00314         }
00315     }    
00316         
00317     this->m_current_frame_index = (this->m_current_frame_index+1) %
00318                                       this->m_buf_nframes;
00319     
00320     /* End Filter */
00321     
00322     /* make sure to free up any space here, not including Image */
00323     
00324     return phSUCCESS;
00325 }
00326 
00327 




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:11 2007 for phission by  doxygen 1.4.4