contrib/brl/bseg/brip/brip_vil1_float_ops.h
Go to the documentation of this file.
00001 //--*-c++-*--
00002 // This is brl/bseg/brip/brip_vil1_float_ops.h
00003 #ifndef brip_vil1_float_ops_h_
00004 #define brip_vil1_float_ops_h_
00005 //-----------------------------------------------------------------------------
00006 //:
00007 // \file
00008 // \author J.L. Mundy
00009 // \brief operations on memory_image_of<float> operands
00010 //
00011 // These methods are similar to the VanDuc gevd_float_ops methods. However,
00012 // they use vil1_image_of<float> buffers rather than the old bufferxy
00013 // structure. The purpose is to provide efficient foundational
00014 // segmentation routines. They are not meant to be generic.
00015 //
00016 // \verbatim
00017 //  Modifications
00018 //   Initial version February 15, 2003
00019 //   Renamed to brip_vil1_float_ops January 24, 2004, In order to support
00020 //   moving from vil1 to vil.
00021 // \endverbatim
00022 //
00023 //-----------------------------------------------------------------------------
00024 #include <vcl_vector.h>
00025 #include <vcl_complex.h>
00026 #include <vnl/vnl_matrix.h>
00027 #include <vbl/vbl_array_2d.h>
00028 #include <vsol/vsol_box_2d_sptr.h>
00029 #include <vgl/algo/vgl_h_matrix_2d.h>
00030 #include <vil1/vil1_image.h>
00031 #include <vil1/vil1_memory_image_of.h>
00032 #include <vil1/vil1_rgb.h>
00033 #include <brip/brip_roi_sptr.h>
00034 
00035 class brip_vil1_float_ops
00036 {
00037  public:
00038   ~brip_vil1_float_ops() {}
00039 
00040   //: convolves with the specified kernel
00041   static vil1_memory_image_of<float>
00042     convolve(vil1_memory_image_of<float> const & input,
00043              vbl_array_2d<float> const & kernel);
00044 
00045   //: convolves with a Gaussian kernel
00046   static vil1_memory_image_of<float>
00047     gaussian(vil1_memory_image_of<float> const & input, float sigma);
00048 
00049   //: non-maximum suppression on a NxN neighborhood, with sub-pixel location
00050   static void non_maximum_suppression(vil1_memory_image_of<float> const & input,
00051                                       const int n,
00052                                       const float thresh,
00053                                       vcl_vector<float>& x_pos,
00054                                       vcl_vector<float>& y_pos,
00055                                       vcl_vector<float>& value);
00056 
00057   //: downsamples the input using the Bert-Adelson algorithm
00058   static vil1_memory_image_of<float>
00059   half_resolution(vil1_memory_image_of<float> const & input,
00060                   float filter_coef=0.359375);
00061 
00062   //: downsamples the color input image using the Bert-Adelson algorithm
00063   static vil1_memory_image_of<vil1_rgb<unsigned char> >
00064   half_resolution(vil1_memory_image_of<vil1_rgb<unsigned char> > const & input,
00065                   float filter_coef=0.359375);
00066 
00067 
00068 #if 0
00069   //: interpolates the input using the Bert-Adelson algorithm
00070   static vil1_memory_image_of<float>
00071     double_resolution(vil1_memory_image_of<float> const & input,
00072                       float filter_coef=0.359375);
00073 #endif
00074 
00075   //: subtracts image_1 from image_2
00076   static vil1_memory_image_of<float>
00077     difference(vil1_memory_image_of<float> const & image_1,
00078                vil1_memory_image_of<float> const & image_2);
00079 
00080   //: sets absolute values greater than thresh to specified level
00081   static vil1_memory_image_of<float>
00082     abs_clip_to_level(vil1_memory_image_of<float> const & image,
00083                       const float thresh, const float level = 0.0);
00084 
00085   //: The gradient using a 3x3 kernel
00086   static void gradient_3x3(vil1_memory_image_of<float> const & input,
00087                            vil1_memory_image_of<float>& grad_x,
00088                            vil1_memory_image_of<float>& grad_y);
00089 
00090   static void hessian_3x3(vil1_memory_image_of<float> const & input,
00091                           vil1_memory_image_of<float>& Ixx,
00092                           vil1_memory_image_of<float>& Ixy,
00093                           vil1_memory_image_of<float>& Iyy);
00094 
00095   static vil1_memory_image_of<float>
00096   beaudet(vil1_memory_image_of<float> const & Ixx,
00097           vil1_memory_image_of<float> const & Ixy,
00098           vil1_memory_image_of<float> const & Iyy);
00099 
00100 
00101   //: IxIx.transpose gradient matrix elements (N = 2n+1)
00102   static void grad_matrix_NxN(vil1_memory_image_of<float> const & input,
00103                               const int n,
00104                               vil1_memory_image_of<float>& IxIx,
00105                               vil1_memory_image_of<float>& IxIy,
00106                               vil1_memory_image_of<float>& IyIy);
00107 
00108   //: Computes the Harris corner measure
00109   static vil1_memory_image_of<float>
00110   harris(vil1_memory_image_of<float> const & IxIx,
00111          vil1_memory_image_of<float> const & IxIy,
00112          vil1_memory_image_of<float> const & IyIy,
00113          double scale=0.04);
00114 
00115 
00116   //: computes the conditioning of the 2n+1 x 2n+1 gradient neighborhood
00117   static vil1_memory_image_of<float>
00118     sqrt_grad_singular_values(vil1_memory_image_of<float> & input, int n);
00119 
00120   //: computes Lucas-Kanade optical flow on a 2n+1 neighborhood
00121   static void Lucas_KanadeMotion(vil1_memory_image_of<float> & current_frame,
00122                                  vil1_memory_image_of<float> & previous_frame,
00123                                  int n, double thresh,
00124                                  vil1_memory_image_of<float>& vx,
00125                                  vil1_memory_image_of<float>& vy);
00126 
00127   //: fills a border of width w on left and right of image with value
00128   static void fill_x_border(vil1_memory_image_of<float> & image,
00129                             int w, float value);
00130 
00131   //: fills a border of width h on top and bottom of image with value
00132   static void fill_y_border(vil1_memory_image_of<float> & image,
00133                             int h, float value);
00134 
00135   //: converts a float image to a byte value range
00136   static vil1_memory_image_of<unsigned char>
00137     convert_to_byte(vil1_memory_image_of<float> const & image);
00138 
00139   //: converts a float image to a byte value range within a specified range
00140   static vil1_memory_image_of<unsigned char>
00141     convert_to_byte(vil1_memory_image_of<float> const & image,
00142                     const float min_val, const float max_val);
00143 
00144   //: converts a float image to an unsigned short image within a range
00145   static vil1_memory_image_of<unsigned short>
00146     convert_to_short(vil1_memory_image_of<float> const & image,
00147                      const float min_val, const float max_val);
00148 
00149   //: converts a float image to a color rgb image with all equal planes
00150   static vil1_memory_image_of<vil1_rgb<unsigned char> >
00151     convert_to_rgb(vil1_memory_image_of<float> const & image);
00152 
00153   //: converts a float image with specified range to a color rgb image with all equal planes
00154   static vil1_memory_image_of<vil1_rgb<unsigned char> >
00155     convert_to_rgb(vil1_memory_image_of<float> const & image,
00156                    const float min_val, const float max_val);
00157 
00158 
00159   //: converts a vil1_image to a float image
00160   static vil1_memory_image_of<float>
00161     convert_to_float(vil1_image const & image);
00162 
00163   //: converts a byte image to a float image
00164   static vil1_memory_image_of<float>
00165     convert_to_float(vil1_memory_image_of<unsigned char> const & image);
00166 
00167   //: converts an RGB image to a float image
00168   static vil1_memory_image_of<float>
00169     convert_to_float(vil1_memory_image_of<vil1_rgb<unsigned char> > const& image);
00170   //: convert a color image to float IHS images
00171   static void
00172     convert_to_IHS(vil1_memory_image_of<vil1_rgb<unsigned char> >const& image,
00173                    vil1_memory_image_of<float>& I,
00174                    vil1_memory_image_of<float>& H,
00175                    vil1_memory_image_of<float>& S);
00176 
00177   //: display IHS images as RGB (not conversion from IHS to RGB)
00178   static void
00179     display_IHS_as_RGB(vil1_memory_image_of<float> const& I,
00180                        vil1_memory_image_of<float> const& H,
00181                        vil1_memory_image_of<float> const& S,
00182                        vil1_memory_image_of<vil1_rgb<unsigned char> >& image);
00183 
00184   //: converts a generic image to greyscale (RGB<unsigned char>)
00185   static vil1_memory_image_of<unsigned char>
00186   convert_to_grey(vil1_image const& img);
00187 
00188   //: converts a vnl_matrix<float> to a float image
00189   static vil1_memory_image_of<float>
00190   convert_to_float(vnl_matrix<float> const & matrix);
00191 
00192   //: loads a 2n+1 x 2n+1 convolution kernel (see .cxx for file format)
00193   static vbl_array_2d<float> load_kernel(vcl_string const & file);
00194 
00195   //: compute basis images for a set of input images
00196   static
00197     void basis_images(vcl_vector<vil1_memory_image_of<float> > const & input_images,
00198                       vcl_vector<vil1_memory_image_of<float> > & basis);
00199 
00200   //: compute the Fourier transform using the vnl FFT algorithm
00201   static bool fourier_transform(vil1_memory_image_of<float> const & input,
00202                                 vil1_memory_image_of<float>& mag,
00203                                 vil1_memory_image_of<float>& phase);
00204 
00205   //: compute the inverse Fourier transform using the vnl FFT algorithm
00206   static
00207     bool inverse_fourier_transform(vil1_memory_image_of<float> const& mag,
00208                                    vil1_memory_image_of<float> const& phase,
00209                                    vil1_memory_image_of<float>& output);
00210 
00211   //: resize to specified dimensions, fill with zeros if output is larger
00212   static
00213     void resize(vil1_memory_image_of<float> const & input,
00214                 const int width, const int height,
00215                 vil1_memory_image_of<float>& output);
00216 
00217 
00218   //: resize to closest power of two larger dimensions than the input
00219   static
00220     bool resize_to_power_of_two(vil1_memory_image_of<float> const & input,
00221                                 vil1_memory_image_of<float>& output);
00222 
00223   //: filter the input image with a Gaussian blocking filter
00224   static bool
00225     spatial_frequency_filter(vil1_memory_image_of<float> const & input,
00226                              const float dir_fx, const float dir_fy,
00227                              const float f0, const float radius,
00228                              const bool output_fourier_mag,
00229                              vil1_memory_image_of<float> & output);
00230   //: 2x2 bilinear interpolation of image at specified location
00231   static float
00232     bilinear_interpolation(vil1_memory_image_of<float> const & input,
00233                            const double x, const double y);
00234   //: map the input to the output by a homography.
00235   // \note if the output size is fixed then only the corresponding
00236   // input image space is transformed.
00237   static bool homography(vil1_memory_image_of<float> const & input,
00238                          vgl_h_matrix_2d<double>const& H,
00239                          vil1_memory_image_of<float>& output,
00240                          bool output_size_fixed = false,
00241                          float output_fill_value = 0.0);
00242 
00243   //: rotate the input image counter-clockwise about the image origin
00244   static
00245   vil1_memory_image_of<float> rotate(vil1_memory_image_of<float> const & input,
00246                                      const double theta_deg);
00247 
00248   static bool chip(vil1_memory_image_of<float> const & input,
00249                    vsol_box_2d_sptr const& roi,
00250                    vil1_memory_image_of<float>& chip);
00251 
00252   static bool chip(vil1_image const & input,
00253                    brip_roi_sptr const& roi,
00254                    vil1_image& chip);
00255 
00256   static vil1_image insert_chip_in_image(vil1_image const & image,
00257                                          vil1_image const & chip,
00258                                          brip_roi_sptr const& roi);
00259 
00260   //: cross-correlate two images at a given sub-pixel location
00261   static float
00262   cross_correlate(vil1_memory_image_of<float> const & image1,
00263                   vil1_memory_image_of<float> const & image2,
00264                   const float x, const float y,
00265                   const int radius = 5,
00266                   const float intensity_thresh=25.0);
00267 
00268   //: Cross-correlate two images using faster running sums
00269   static bool
00270   cross_correlate(vil1_memory_image_of<float> const & image1,
00271                   vil1_memory_image_of<float> const & image2,
00272                   vil1_memory_image_of<float>& out,
00273                   const int radius = 5,
00274                   const float intensity_thresh=25.0);
00275 
00276  private:
00277 
00278   //: find if the center pixel of a neighborhood is the maximum value
00279   static bool local_maximum(vbl_array_2d<float> const & nighborhood,
00280                             int n, float& value);
00281 
00282   //: find the sub-pixel offset to the maximum using a 3x3 quad interpolation
00283   static void interpolate_center(vbl_array_2d<float> const & neighborhood,
00284                                  float& dx, float& dy);
00285 
00286   //: sub-sample a 1-d array using the Bert-Adelson algorithm
00287   static void half_resolution_1d(const float* input, int n,
00288                                  const float k0, const float k1,
00289                                  const float k2, float* output);
00290 
00291   //: One-dimensional fft
00292   static bool fft_1d(int dir, int m, double* x, double* y);
00293 
00294   //: Two-dimensional fft
00295   static bool fft_2d(vnl_matrix<vcl_complex<double> >& c, int nx,int ny,int dir);
00296   //: Transform the fft coefficients from/to fft/frequency order(self inverse).
00297   static
00298     void ftt_fourier_2d_reorder(vnl_matrix<vcl_complex<double> > const& F1,
00299                                 vnl_matrix<vcl_complex<double> > & F2);
00300   //: Blocking filter function
00301   static float gaussian_blocking_filter(const float dir_fx,
00302                                         const float dir_fy,
00303                                         const float f0, const float radius,
00304                                         const float fx, const float fy);
00305   //: Default constructor is private
00306   brip_vil1_float_ops() {}
00307 };
00308 
00309 #endif // brip_vil1_float_ops_h_