00001
00002 #ifndef vil3d_convert_h_
00003 #define vil3d_convert_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #include <vcl_cassert.h>
00059 #include <vcl_limits.h>
00060 #include <vil/vil_convert.h>
00061 #include <vil3d/vil3d_transform.h>
00062 #include <vil3d/vil3d_math.h>
00063 #include <vil3d/vil3d_plane.h>
00064 #include <vil3d/vil3d_copy.h>
00065
00066
00067
00068
00069
00070
00071
00072
00073 template <class inP, class outP>
00074 inline void vil3d_convert_cast(const vil3d_image_view<inP >&src,
00075 vil3d_image_view<outP >&dest)
00076 {
00077 if (vil_pixel_format_of(inP()) == vil_pixel_format_of(outP()))
00078 dest = src;
00079 else
00080 vil3d_transform2(src, dest, vil_convert_cast_pixel<inP, outP>());
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 template <class inP, class outP>
00093 inline void vil3d_convert_round(const vil3d_image_view<inP >&src,
00094 vil3d_image_view<outP >&dest)
00095 {
00096 if (vil_pixel_format_of(inP()) == vil_pixel_format_of(outP()))
00097 dest = src;
00098 else
00099 vil3d_transform2(src, dest, vil_convert_round_pixel<inP, outP>());
00100 }
00101
00102
00103
00104
00105 template <class T>
00106 inline void vil3d_convert_stretch_range(const vil3d_image_view<T>& src,
00107 vil3d_image_view<vxl_byte>& dest)
00108 {
00109 T min_b,max_b;
00110 vil3d_math_value_range(src,min_b,max_b);
00111 double a = -1.0*double(min_b);
00112 double b = 0.0;
00113 if (max_b-min_b >0) b = 255.0/(max_b-min_b);
00114 dest.set_size(src.ni(), src.nj(), src.nk(), src.nplanes());
00115 for (unsigned p = 0; p < src.nplanes(); ++p)
00116 for (unsigned k = 0; k < src.nk(); ++k)
00117 for (unsigned j = 0; j < src.nj(); ++j)
00118 for (unsigned i = 0; i < src.ni(); ++i)
00119 dest(i,j,k,p) = static_cast<vxl_byte>( b*( src(i,j,k,p)+ a ) );
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 template <class inP>
00132 inline void vil3d_convert_stretch_range(const vil3d_image_view<inP>& src,
00133 vil3d_image_view<double>& dest,
00134 double lo, double hi)
00135 {
00136 inP min_b=0, max_b=0;
00137 vil3d_math_value_range(src,min_b,max_b);
00138 double b = 0.0;
00139 if (max_b-min_b >0)
00140 b = (hi-lo)/static_cast<double>(max_b-min_b);
00141 double a = -1.0*min_b*b + lo;
00142 dest.set_size(src.ni(), src.nj(), src.nk(), src.nplanes());
00143 for (unsigned p = 0; p < src.nplanes(); ++p)
00144 for (unsigned k = 0; k < src.nk(); ++k)
00145 for (unsigned j = 0; j < src.nj(); ++j)
00146 for (unsigned i = 0; i < src.ni(); ++i)
00147 dest(i,j,k,p) = b*src(i,j,k,p) + a;
00148 }
00149
00150
00151
00152
00153 template <class inP>
00154 inline void vil3d_convert_stretch_range_limited(const vil3d_image_view<inP>& src,
00155 vil3d_image_view<double>& dest,
00156 const inP src_lo,
00157 const inP src_hi,
00158 const double dest_lo,
00159 const double dest_hi)
00160 {
00161 double ddest = dest_hi - dest_lo;
00162 double dsrc = static_cast<double>(src_hi - src_lo);
00163 double dds = ddest / dsrc;
00164
00165 dest.set_size(src.ni(), src.nj(), src.nk(), src.nplanes());
00166 for (unsigned p = 0; p < src.nplanes(); ++p)
00167 for (unsigned k = 0; k < src.nk(); ++k)
00168 for (unsigned j = 0; j < src.nj(); ++j)
00169 for (unsigned i = 0; i < src.ni(); ++i)
00170 {
00171 inP s = src(i,j,k,p);
00172 dest(i,j,k,p) = s<=src_lo ? dest_lo :
00173 s>=src_hi ? dest_hi :
00174 dest_lo + dds*static_cast<double>(s-src_lo);
00175 }
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 template <class outP>
00188 inline vil3d_image_view_base_sptr vil3d_convert_cast(outP ,
00189 const vil3d_image_view_base_sptr& src)
00190 {
00191 if (!src) return vil3d_image_view_base_sptr();
00192
00193 vil3d_image_view_base_sptr dest = new vil3d_image_view<outP>;
00194 vil3d_image_view<outP> & dest_ref = static_cast<vil3d_image_view<outP> &>(*dest);
00195
00196 switch ( vil_pixel_format_component_format(src->pixel_format()) )
00197 {
00198 #define macro(F , T) \
00199 case F: \
00200 vil3d_convert_cast( vil3d_image_view<T >( src ), dest_ref );\
00201 break;
00202
00203 macro( VIL_PIXEL_FORMAT_UINT_32, vxl_uint_32 )
00204 macro( VIL_PIXEL_FORMAT_INT_32, vxl_int_32 )
00205 macro( VIL_PIXEL_FORMAT_UINT_16, vxl_uint_16 )
00206 macro( VIL_PIXEL_FORMAT_INT_16, vxl_int_16 )
00207 macro( VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00208 macro( VIL_PIXEL_FORMAT_SBYTE, vxl_sbyte )
00209 macro( VIL_PIXEL_FORMAT_FLOAT, float )
00210 macro( VIL_PIXEL_FORMAT_DOUBLE, double )
00211 macro( VIL_PIXEL_FORMAT_BOOL, bool )
00212 #undef macro
00213 default: dest=0;
00214 }
00215 return dest;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 template <class outP>
00232 inline vil3d_image_view_base_sptr vil3d_convert_round(
00233 outP , const vil3d_image_view_base_sptr &src)
00234 {
00235 assert(vil_pixel_format_num_components(vil_pixel_format_of(outP()))==1);
00236
00237 if (!src) return vil3d_image_view_base_sptr();
00238
00239 if (vil_pixel_format_component_format(src->pixel_format()) ==
00240 vil_pixel_format_of(outP()))
00241 return src;
00242
00243 vil3d_image_view_base_sptr dest = new vil3d_image_view<outP >;
00244 vil3d_image_view<outP > &dest_ref = static_cast<vil3d_image_view<outP >&>(*dest);
00245
00246 switch (vil_pixel_format_component_format(src->pixel_format()))
00247 {
00248 #define macro( F , T ) \
00249 case F: { \
00250 vil3d_image_view<T > src1 = src; \
00251 vil3d_transform2(src1, dest_ref, vil_convert_round_pixel<T , outP>()); \
00252 break; }
00253
00254 macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00255 macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00256 macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00257 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00258 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00259 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00260 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00261 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00262 #undef macro
00263 default: dest=0;
00264 }
00265 return dest;
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 inline vil3d_image_view_base_sptr vil3d_convert_to_grey_using_average(
00280 const vil3d_image_view_base_sptr &src)
00281 {
00282 if (!src) return vil3d_image_view_base_sptr();
00283
00284
00285 switch (vil_pixel_format_component_format(src->pixel_format()))
00286 {
00287 #define macro( F , T ) \
00288 case F: { \
00289 \
00290 if (src->nplanes() == 1 && \
00291 vil_pixel_format_component_format(src->pixel_format())==1) \
00292 return src; \
00293 \
00294 vil3d_image_view<T > dest; \
00295 vil3d_image_view<T > src1 = *src; \
00296 vil3d_math_mean_over_planes(src1, dest, double()); \
00297 return vil3d_image_view_base_sptr(new vil3d_image_view<T >(dest)); }
00298
00299 macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00300 macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00301 macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00302 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00303 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00304 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00305 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00306 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00307 #undef macro
00308 default:
00309 return vil3d_image_view_base_sptr();
00310 }
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 inline vil3d_image_view_base_sptr vil3d_convert_to_n_planes(
00326 unsigned n_planes, const vil3d_image_view_base_sptr &src)
00327 {
00328 if (!src || n_planes == 0)
00329 return vil3d_image_view_base_sptr();
00330
00331
00332 switch (vil_pixel_format_component_format(src->pixel_format()))
00333 {
00334 #define macro( F, T ) \
00335 case F: { \
00336 vil3d_image_view<T > src_ref = src; \
00337 if (!src_ref) return vil3d_image_view_base_sptr(); \
00338 \
00339 if (src_ref.nplanes() >= n_planes) \
00340 return vil3d_image_view_base_sptr( new vil3d_image_view<T >( \
00341 vil3d_planes(vil3d_image_view<T > (src),0,1,n_planes) )); \
00342 else { \
00343 vil3d_image_view_base_sptr dest = new vil3d_image_view<T >( \
00344 src_ref.ni(), src_ref.nj(), src_ref.nk(), n_planes); \
00345 vil3d_image_view<T > & dest_ref = \
00346 static_cast<vil3d_image_view<T > &>(*dest); \
00347 vil3d_image_view<T > dest_slices = \
00348 vil3d_planes(dest_ref, 0, 1, src_ref.nplanes()); \
00349 vil3d_copy_reformat(src_ref, dest_slices); \
00350 vil3d_image_view<T > src_slice(vil3d_plane(src_ref, 0)); \
00351 for (unsigned i=src_ref.nplanes(); i<n_planes; ++i) { \
00352 dest_slices = vil3d_plane(dest_ref, i); \
00353 vil3d_copy_reformat(src_slice, dest_slices); } \
00354 return dest; } } \
00355
00356 macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00357 macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00358 macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00359 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00360 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00361 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00362 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00363 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00364 #undef macro
00365
00366 default:
00367 return vil3d_image_view_base_sptr();
00368 }
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 template <class outP>
00382 inline vil3d_image_view_base_sptr vil3d_convert_stretch_range(
00383 outP , const vil3d_image_view_base_sptr &src)
00384 {
00385
00386 assert (vil_pixel_format_num_components(vil_pixel_format_of(outP())) == 1);
00387
00388 if (!src)
00389 return vil3d_image_view_base_sptr();
00390
00391 double hi,lo;
00392
00393 if (vcl_numeric_limits<outP>::is_integer)
00394 {
00395 hi = vcl_numeric_limits<outP>::max()+0.999;
00396 lo = vcl_numeric_limits<outP>::min();
00397 }
00398 else
00399 {
00400 hi=1.0;
00401 lo=0.0;
00402 }
00403
00404 vil3d_image_view_base_sptr dest = new vil3d_image_view<outP>;
00405 vil3d_image_view<outP> & dest_ref = static_cast<vil3d_image_view<outP> &>(*dest);
00406 vil3d_image_view<double> inter;
00407 switch (vil_pixel_format_component_format(src->pixel_format()))
00408 {
00409 #define macro( F , T ) \
00410 case F: { \
00411 vil3d_image_view<T> src_ref = src; \
00412 if (!src_ref) return vil3d_image_view_base_sptr(); \
00413 vil3d_convert_stretch_range(src_ref, inter, lo, hi); \
00414 vil3d_convert_cast(inter, dest_ref); \
00415 break; }
00416
00417 macro(VIL_PIXEL_FORMAT_BYTE, vxl_byte )
00418 macro(VIL_PIXEL_FORMAT_SBYTE , vxl_sbyte )
00419 macro(VIL_PIXEL_FORMAT_UINT_32 , vxl_uint_32 )
00420 macro(VIL_PIXEL_FORMAT_UINT_16 , vxl_uint_16 )
00421 macro(VIL_PIXEL_FORMAT_INT_32 , vxl_int_32 )
00422 macro(VIL_PIXEL_FORMAT_INT_16 , vxl_int_16 )
00423 macro(VIL_PIXEL_FORMAT_FLOAT , float )
00424 macro(VIL_PIXEL_FORMAT_DOUBLE , double )
00425 #undef macro
00426 default:
00427 dest_ref.clear();
00428 }
00429 return dest;
00430 }
00431
00432
00433 #endif // vil3d_convert_h_