Go to the documentation of this file.00001
00002 #ifndef vimt_gaussian_pyramid_builder_2d_general_txx_
00003 #define vimt_gaussian_pyramid_builder_2d_general_txx_
00004
00005
00006
00007
00008
00009 #include "vimt_gaussian_pyramid_builder_2d_general.h"
00010 #include <vcl_cmath.h>
00011 #include <vcl_cassert.h>
00012 #include <vcl_string.h>
00013 #include <vcl_iostream.h>
00014 #include <vil/algo/vil_gauss_reduce.h>
00015 #include <vgl/vgl_point_2d.h>
00016 #include <vgl/vgl_vector_2d.h>
00017 #include <vimt/vimt_image_pyramid.h>
00018 #include <vimt/vimt_crop.h>
00019
00020
00021
00022 template <class T>
00023 vimt_gaussian_pyramid_builder_2d_general<T>::vimt_gaussian_pyramid_builder_2d_general():
00024 scale_params_(2.0)
00025 {}
00026
00027
00028 template <class T>
00029 vimt_gaussian_pyramid_builder_2d_general<T>::vimt_gaussian_pyramid_builder_2d_general(double scale_step):
00030 scale_params_(scale_step)
00031 {}
00032
00033
00034
00035 template <class T>
00036 vimt_gaussian_pyramid_builder_2d_general<T>::~vimt_gaussian_pyramid_builder_2d_general()
00037 {}
00038
00039
00040 template <class T>
00041 void vimt_gaussian_pyramid_builder_2d_general<T>::set_scale_step(double scaleStep)
00042 {
00043 scale_params_ = vil_gauss_reduce_params(scaleStep);
00044 }
00045
00046
00047
00048 template <class T>
00049 void vimt_gaussian_pyramid_builder_2d_general<T>::build(
00050 vimt_image_pyramid& im_pyr,
00051 const vimt_image& im) const
00052 {
00053 assert(im.is_class(vimt_image_2d_of<T>().is_a()));
00054
00055 const vimt_image_2d_of<T>& base_image = static_cast<const vimt_image_2d_of<T>&>(im);
00056
00057 int ni = base_image.image().ni();
00058 int nj = base_image.image().nj();
00059
00060
00061
00062 double s = scale_step();
00063 int maxlevels = 1;
00064 while (((unsigned int)(ni/s+0.5)>=this->min_x_size()) &&
00065 ((unsigned int)(nj/s+0.5)>=this->min_y_size()))
00066 {
00067 maxlevels++;
00068 s *= scale_step();
00069 }
00070
00071 if (maxlevels > this->max_levels())
00072 maxlevels=this->max_levels();
00073
00074 worka_.set_size(ni,nj);
00075 workb_.set_size(ni,nj);
00076
00077
00078 this->check_pyr(im_pyr,maxlevels);
00079
00080 vimt_image_2d_of<T>& im0 = static_cast<vimt_image_2d_of<T>&>(im_pyr(0));
00081
00082
00083 im0 = vimt_crop(base_image,0,ni,0,nj);
00084
00085 s = scale_step();
00086 for (int i=1;i<maxlevels;i++)
00087 {
00088 vimt_image_2d_of<T>& dest = static_cast<vimt_image_2d_of<T>&>(im_pyr(i));
00089 const vimt_image_2d_of<T>& src = static_cast<const vimt_image_2d_of<T>&>(im_pyr(i-1));
00090
00091 s*=scale_step();
00092 vil_gauss_reduce_general(src.image(), dest.image(), worka_, workb_, scale_params_);
00093
00094
00095 vimt_transform_2d scaling;
00096
00097
00098
00099 const double init_x = 0.5 * (src.image().ni() - 1 - (dest.image().ni()-1)*scale_params_.scale_step());
00100 const double init_y = 0.5 * (src.image().nj() - 1 - (dest.image().nj()-1)*scale_params_.scale_step());
00101
00102 scaling.set_zoom_only(1/scale_params_.scale_step(),-init_x,-init_y);
00103 dest.set_world2im(scaling * src.world2im());
00104 }
00105
00106
00107 vgl_point_2d<double> c0(0.5*(ni-1),0.5*(nj-1));
00108 vgl_point_2d<double> c1 = c0 + vgl_vector_2d<double> (1,1);
00109 vimt_transform_2d im2world = base_image.world2im().inverse();
00110 vgl_vector_2d<double> dw = im2world(c1) - im2world(c0);
00111
00112 double base_pixel_width = vcl_sqrt(0.5*(dw.x()*dw.x() + dw.y()*dw.y()));
00113
00114 im_pyr.set_widths(base_pixel_width,scale_step());
00115 }
00116
00117
00118
00119
00120
00121 template<class T>
00122 void vimt_gaussian_pyramid_builder_2d_general<T>::extend(vimt_image_pyramid& image_pyr) const
00123 {
00124
00125 assert(image_pyr(0).is_class(vimt_image_2d_of<T>().is_a()));
00126
00127 assert(image_pyr.scale_step() == scale_step());
00128
00129 const vimt_image_2d_of<T>& base_image = static_cast<const vimt_image_2d_of<T>&>(image_pyr(0));
00130
00131
00132 const int ni = base_image.image().ni();
00133 const int nj = base_image.image().nj();
00134
00135
00136
00137 double s = scale_step();
00138 int maxlevels = 1;
00139 while (((unsigned int)(ni/s+0.5) >= this->min_x_size()) &&
00140 ((unsigned int)(nj/s+0.5) >= this->min_y_size()))
00141 {
00142 maxlevels++;
00143 s*=scale_step();
00144 }
00145
00146 if (maxlevels > this->max_levels())
00147 maxlevels=this->max_levels();
00148
00149 worka_.set_size(ni,nj);
00150 workb_.set_size(ni,nj);
00151
00152
00153 int oldsize = image_pyr.n_levels();
00154 if (oldsize<maxlevels)
00155 {
00156 image_pyr.data().resize(maxlevels);
00157
00158 s = vcl_pow(scale_step(), oldsize);
00159 for (int i=oldsize;i<maxlevels;i++)
00160 {
00161 image_pyr.data()[i] = new vimt_image_2d_of<T>;
00162 vimt_image_2d_of<T>& im_i0 = static_cast<vimt_image_2d_of<T>&>(image_pyr(i));
00163 vimt_image_2d_of<T>& im_i1 = static_cast<vimt_image_2d_of<T>&>(image_pyr(i-1));
00164 im_i0.image().set_size((unsigned)(ni/s+0.5),(unsigned)(nj/s+0.5),
00165 im_i1.image().nplanes());
00166
00167 s*=scale_step();
00168 vil_gauss_reduce_general(im_i1.image(), im_i0.image(), worka_, workb_, scale_params_);
00169 }
00170 }
00171 }
00172
00173
00174
00175 #if 0
00176 template <class T>
00177 vcl_string vimt_gaussian_pyramid_builder_2d_general<T>::is_a() const
00178 {
00179 return vcl_string("vimt_gaussian_pyramid_builder_2d_general<T>");
00180 }
00181 #endif // 0
00182
00183
00184 template <class T>
00185 bool vimt_gaussian_pyramid_builder_2d_general<T>::is_class(vcl_string const& s) const
00186 {
00187 return s==vimt_gaussian_pyramid_builder_2d_general<T>::is_a() ||
00188 vimt_gaussian_pyramid_builder_2d<T>::is_class(s);
00189 }
00190
00191
00192
00193 template <class T>
00194 short vimt_gaussian_pyramid_builder_2d_general<T>::version_no() const
00195 {
00196 return 1;
00197 }
00198
00199
00200
00201 template <class T>
00202 vimt_image_pyramid_builder* vimt_gaussian_pyramid_builder_2d_general<T>::clone() const
00203 {
00204 return new vimt_gaussian_pyramid_builder_2d_general(*this);
00205 }
00206
00207
00208
00209 template <class T>
00210 void vimt_gaussian_pyramid_builder_2d_general<T>::print_summary(vcl_ostream& os) const
00211 {
00212 vimt_gaussian_pyramid_builder_2d<T>::print_summary(os);
00213 }
00214
00215
00216
00217 template <class T>
00218 void vimt_gaussian_pyramid_builder_2d_general<T>::b_write(vsl_b_ostream& bfs) const
00219 {
00220 vsl_b_write(bfs,version_no());
00221 vimt_gaussian_pyramid_builder_2d<T>::b_write(bfs);
00222 vsl_b_write(bfs,scale_step());
00223 }
00224
00225
00226
00227 template <class T>
00228 void vimt_gaussian_pyramid_builder_2d_general<T>::b_read(vsl_b_istream& bfs)
00229 {
00230 if (!bfs) return;
00231
00232 short version;
00233 vsl_b_read(bfs,version);
00234 double scale;
00235
00236 switch (version)
00237 {
00238 case 1:
00239 vimt_gaussian_pyramid_builder_2d<T>::b_read(bfs);
00240
00241 vsl_b_read(bfs,scale);
00242 set_scale_step(scale);
00243 break;
00244 default:
00245 vcl_cerr << "I/O ERROR: vimt_gaussian_pyramid_builder_2d_general<T>::b_read(vsl_b_istream&)\n"
00246 << " Unknown version number "<< version << '\n';
00247 bfs.is().clear(vcl_ios::badbit);
00248 return;
00249 }
00250 }
00251
00252 #define VIMT_GAUSSIAN_PYRAMID_BUILDER_2D_GENERAL_INSTANTIATE(T) \
00253 VCL_DEFINE_SPECIALIZATION vcl_string vimt_gaussian_pyramid_builder_2d_general<T >::is_a() const \
00254 { return vcl_string("vimt_gaussian_pyramid_builder_2d_general<" #T ">"); }\
00255 template class vimt_gaussian_pyramid_builder_2d_general<T >
00256
00257
00258 #endif // vimt_gaussian_pyramid_builder_2d_general_txx_