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