contrib/oxl/osl/osl_convolve.cxx
Go to the documentation of this file.
00001 // This is oxl/osl/osl_convolve.cxx
00002 #include "osl_convolve.h"
00003 //:
00004 //  \file
00005 
00006 #include <osl/osl_roi_window.h>
00007 #include <vcl_cassert.h>
00008 
00009 //-----------------------------------------------------------------------------
00010 
00011 // Depending on the mask size, this routine will call the
00012 // appropriate float_mask? routine.
00013 void osl_convolve (osl_roi_window const *window,
00014                    osl_1d_half_kernel<double> const *mask,
00015                    vil1_memory_image_of<float> *image,
00016                    vil1_memory_image_of<float> *scratch)
00017 {
00018   switch (mask->count) {
00019   case 2:
00020     osl_convolve2 (window, mask, image, scratch);
00021     break;
00022   case 3:
00023     osl_convolve3 (window, mask, image, scratch);
00024     break;
00025   case 4:
00026     osl_convolve4 (window, mask, image, scratch);
00027     break;
00028   case 5:
00029     osl_convolve5 (window, mask, image, scratch);
00030     break;
00031   case 6:
00032     osl_convolve6 (window, mask, image, scratch);
00033     break;
00034   default:
00035     osl_convolven (window, mask, image, scratch);
00036     break;
00037   }
00038 }
00039 
00040 //-----------------------------------------------------------------------------
00041 
00042 //: A convolution routine for masks of size 2.
00043 void osl_convolve2 (osl_roi_window const *window,
00044                     osl_1d_half_kernel<double> const *mask,
00045                     vil1_memory_image_of<float> *image,
00046                     vil1_memory_image_of<float> *scratch)
00047 {
00048   assert(mask->count == 2);
00049   int row_min = window->row_start_index;
00050   int col_min = window->col_start_index+1;
00051   int row_max = window->row_end_index;
00052   int col_max = window->col_end_index-1;
00053 
00054   double mask0 = mask->array [0];
00055   double mask1 = mask->array [1];
00056 
00057   // horizontal convolution.
00058 
00059   for (int row = row_min; row < row_max; row++) {
00060     for (int col = col_min; col < col_max; col++) {
00061       (*scratch) [row][col] = float(
00062           (*image) [row][col] * mask0
00063         +((*image) [row][col-1]+(*image) [row][col+1]) * mask1);
00064     }
00065   }
00066 
00067   // vertical convolution on top of the horizontal convolution.
00068 
00069   row_min += 1;
00070   row_max -= 1;
00071 
00072   for (int row = row_min; row < row_max; row++) {
00073     for (int col = col_min; col < col_max; col++) {
00074       (*image) [row][col] = float(
00075           (*scratch) [row][col] * mask0
00076         +((*scratch) [row-1][col]+(*scratch) [row+1][col]) * mask1);
00077     }
00078   }
00079 }
00080 
00081 
00082 //-----------------------------------------------------------------------------
00083 
00084 //: A convolution routine for masks of size 3.
00085 void osl_convolve3 (osl_roi_window const *window,
00086                     osl_1d_half_kernel<double> const *mask,
00087                     vil1_memory_image_of<float> *image,
00088                     vil1_memory_image_of<float> *scratch)
00089 {
00090   assert(mask->count == 3);
00091   int row_min = window->row_start_index;
00092   int col_min = window->col_start_index+2;
00093   int row_max = window->row_end_index;
00094   int col_max = window->col_end_index-2;
00095 
00096   double mask0 = mask->array [0];
00097   double mask1 = mask->array [1];
00098   double mask2 = mask->array [2];
00099 
00100   // horizontal convolution.
00101 
00102   for (int row = row_min; row < row_max; row++) {
00103     for (int col = col_min; col < col_max; col++) {
00104       (*scratch) [row][col] = float(
00105            (*image) [row][col] * mask0
00106         + ((*image) [row][col-1]+(*image) [row][col+1]) * mask1
00107         + ((*image) [row][col-2]+(*image) [row][col+2]) * mask2);
00108     }
00109   }
00110 
00111   // vertical convolution on top of the horizontal convolution.
00112 
00113   row_min += 2;
00114   row_max -= 2;
00115 
00116   for (int row = row_min; row < row_max; row++) {
00117     for (int col = col_min; col < col_max; col++) {
00118       (*image) [row][col] = float(
00119            (*scratch) [row][col] * mask0
00120         + ((*scratch) [row-1][col]+(*scratch) [row+1][col]) * mask1
00121         + ((*scratch) [row-2][col]+(*scratch) [row+2][col]) * mask2);
00122     }
00123   }
00124 }
00125 
00126 
00127 //-----------------------------------------------------------------------------
00128 
00129 //: -- A convolution routine for masks of size 4.
00130 void osl_convolve4 (osl_roi_window const *window,
00131                     osl_1d_half_kernel<double> const *mask,
00132                     vil1_memory_image_of<float> *image,
00133                     vil1_memory_image_of<float> *scratch)
00134 {
00135   assert(mask->count == 4);
00136   int row_min = window->row_start_index;
00137   int col_min = window->col_start_index+3;
00138   int row_max = window->row_end_index;
00139   int col_max = window->col_end_index-3;
00140 
00141   double mask0 = mask->array [0];
00142   double mask1 = mask->array [1];
00143   double mask2 = mask->array [2];
00144   double mask3 = mask->array [3];
00145 
00146   // horizontal convolution.
00147 
00148   for (int row = row_min; row < row_max; row++) {
00149     for (int col = col_min; col < col_max; col++) {
00150       (*scratch) [row][col] = float(
00151           (*image) [row][col] * mask0
00152         +((*image) [row][col-1]+(*image) [row][col+1]) * mask1
00153         +((*image) [row][col-2]+(*image) [row][col+2]) * mask2
00154         +((*image) [row][col-3]+(*image) [row][col+3]) * mask3);
00155     }
00156   }
00157 
00158   // vertical convolution on top of the horizontal convolution.
00159 
00160   row_min += 3;
00161   row_max -= 3;
00162 
00163   for (int row = row_min; row < row_max; row++) {
00164     for (int col = col_min; col < col_max; col++) {
00165       (*image) [row][col] = float(
00166           (*scratch) [row][col] * mask0
00167         +((*scratch) [row-1][col]+(*scratch) [row+1][col]) * mask1
00168         +((*scratch) [row-2][col]+(*scratch) [row+2][col]) * mask2
00169         +((*scratch) [row-3][col]+(*scratch) [row+3][col]) * mask3);
00170     }
00171   }
00172 }
00173 
00174 
00175 //-----------------------------------------------------------------------------
00176 
00177 //: A convolution routine for masks of size 5.
00178 void osl_convolve5 (osl_roi_window const *window,
00179                     osl_1d_half_kernel<double> const *mask,
00180                     vil1_memory_image_of<float> *image,
00181                     vil1_memory_image_of<float> *scratch)
00182 {
00183   assert(mask->count == 5);
00184   int row_min = window->row_start_index;
00185   int col_min = window->col_start_index+4;
00186   int row_max = window->row_end_index;
00187   int col_max = window->col_end_index-4;
00188 
00189   double mask0 = mask->array [0];
00190   double mask1 = mask->array [1];
00191   double mask2 = mask->array [2];
00192   double mask3 = mask->array [3];
00193   double mask4 = mask->array [4];
00194 
00195   // horizontal convolution.
00196 
00197   for (int row = row_min; row < row_max; row++) {
00198     for (int col = col_min; col < col_max; col++) {
00199       (*scratch) [row][col] = float(
00200            (*image) [row][col] * mask0
00201         + ((*image) [row][col-1]+(*image) [row][col+1]) * mask1
00202         + ((*image) [row][col-2]+(*image) [row][col+2]) * mask2
00203         + ((*image) [row][col-3]+(*image) [row][col+3]) * mask3
00204         + ((*image) [row][col-4]+(*image) [row][col+4]) * mask4);
00205     }
00206   }
00207 
00208   // vertical convolution on top of the horizontal convolution.
00209 
00210   row_min += 4;
00211   row_max -= 4;
00212 
00213   for (int row = row_min; row < row_max; row++) {
00214     for (int col = col_min; col < col_max; col++) {
00215       (*image) [row][col] = float(
00216            (*scratch) [row][col] * mask0
00217         + ((*scratch) [row-1][col]+(*scratch) [row+1][col]) * mask1
00218         + ((*scratch) [row-2][col]+(*scratch) [row+2][col]) * mask2
00219         + ((*scratch) [row-3][col]+(*scratch) [row+3][col]) * mask3
00220         + ((*scratch) [row-4][col]+(*scratch) [row+4][col]) * mask4);
00221     }
00222   }
00223 }
00224 
00225 
00226 //-----------------------------------------------------------------------------
00227 
00228 //: A convolution routine for masks of size 6.
00229 void osl_convolve6 (osl_roi_window const *window,
00230                     osl_1d_half_kernel<double> const *mask,
00231                     vil1_memory_image_of<float> *image,
00232                     vil1_memory_image_of<float> *scratch)
00233 {
00234   assert(mask->count == 6);
00235   int row_min = window->row_start_index;
00236   int col_min = window->col_start_index+5;
00237   int row_max = window->row_end_index;
00238   int col_max = window->col_end_index-5;
00239 
00240   double mask0 = mask->array [0];
00241   double mask1 = mask->array [1];
00242   double mask2 = mask->array [2];
00243   double mask3 = mask->array [3];
00244   double mask4 = mask->array [4];
00245   double mask5 = mask->array [5];
00246 
00247   // horizontal convolution.
00248 
00249   for (int row = row_min; row < row_max; row++) {
00250     for (int col = col_min; col < col_max; col++) {
00251       (*scratch) [row][col] = float(
00252            (*image) [row][col] * mask0
00253         + ((*image) [row][col-1]+(*image) [row][col+1]) * mask1
00254         + ((*image) [row][col-2]+(*image) [row][col+2]) * mask2
00255         + ((*image) [row][col-3]+(*image) [row][col+3]) * mask3
00256         + ((*image) [row][col-4]+(*image) [row][col+4]) * mask4
00257         + ((*image) [row][col-5]+(*image) [row][col+5]) * mask5);
00258     }
00259   }
00260 
00261   // vertical convolution on top of the horizontal convolution.
00262 
00263   row_min += 5;
00264   row_max -= 5;
00265 
00266   for (int row = row_min; row < row_max; row++) {
00267     for (int col = col_min; col < col_max; col++) {
00268       (*image) [row][col] = float(
00269            (*scratch) [row][col] * mask0
00270         + ((*scratch) [row-1][col]+(*scratch) [row+1][col]) * mask1
00271         + ((*scratch) [row-2][col]+(*scratch) [row+2][col]) * mask2
00272         + ((*scratch) [row-3][col]+(*scratch) [row+3][col]) * mask3
00273         + ((*scratch) [row-4][col]+(*scratch) [row+4][col]) * mask4
00274         + ((*scratch) [row-5][col]+(*scratch) [row+5][col]) * mask5);
00275     }
00276   }
00277 }
00278 
00279 //--------------------------------------------------------------------------------
00280 
00281 //: A convolution routine for masks of any size.
00282 void osl_convolven (osl_roi_window const *window,
00283                     osl_1d_half_kernel<double> const *mask,
00284                     vil1_memory_image_of<float> *image,
00285                     vil1_memory_image_of<float> *scratch)
00286 {
00287   int row_min = window->row_start_index;
00288   int col_min = window->col_start_index+mask->count-1;
00289   int row_max = window->row_end_index;
00290   int col_max = window->col_end_index-(mask->count-1);
00291 
00292   /* horizontal convolution. */
00293 
00294   for (int row = row_min; row < row_max; row++) {
00295     for (int col = col_min; col < col_max; col++) {
00296       double v = (*image) [row][col] * mask->array [0];
00297 
00298       for (unsigned int mask_index = 1; mask_index < mask->count; mask_index++)
00299         v += ((*image) [row][col-mask_index]
00300              +(*image) [row][col+mask_index]) * mask->array [mask_index];
00301       (*scratch) [row][col] = float(v);
00302     }
00303   }
00304 
00305   /* vertical convolution on top of the horizontal convolution. */
00306 
00307   row_min += mask->count-1;
00308   row_max -= mask->count-1;
00309 
00310   for (int row = row_min; row < row_max; row++) {
00311     for (int col = col_min; col < col_max; col++) {
00312       double v = (*scratch) [row][col] * mask->array [0];
00313 
00314       for (unsigned int mask_index = 1; mask_index < mask->count; mask_index++)
00315         v += ((*scratch) [row-mask_index][col]+
00316               (*scratch) [row+mask_index][col]) * mask->array [mask_index];
00317       (*image) [row][col] = float(v);
00318     }
00319   }
00320 }
00321 
00322 //--------------------------------------------------------------------------------