/home/oan/prosjekt/gotools/segmentation/gpl_distro/lsseg_1.0_gpl/include/simple_tools_templates.h

Go to the documentation of this file.
00001 //===========================================================================
00002 // The Level-Set Segmentation Library (LSSEG)
00003 //
00004 //
00005 // Copyright (C) 2000-2005 SINTEF ICT, Applied Mathematics, Norway.
00006 //
00007 // This program is free software; you can redistribute it and/or          
00008 // modify it under the terms of the GNU General Public License            
00009 // as published by the Free Software Foundation version 2 of the License. 
00010 //
00011 // This program is distributed in the hope that it will be useful,        
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of         
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
00014 // GNU General Public License for more details.                           
00015 //
00016 // You should have received a copy of the GNU General Public License      
00017 // along with this program; if not, write to the Free Software            
00018 // Foundation, Inc.,                                                      
00019 // 59 Temple Place - Suite 330,                                           
00020 // Boston, MA  02111-1307, USA.                                           
00021 //
00022 // Contact information: e-mail: tor.dokken@sintef.no                      
00023 // SINTEF ICT, Department of Applied Mathematics,                         
00024 // P.O. Box 124 Blindern,                                                 
00025 // 0314 Oslo, Norway.                                                     
00026 // 
00027 //
00028 // Other licenses are also available for this software, notably licenses
00029 // for:
00030 // - Building commercial software.                                        
00031 // - Building software whose source code you wish to keep private.        
00032 //
00033 //===========================================================================
00034 //===========================================================================
00035 //                                                                           
00036 // File: simple_tools_templates.h                                            
00037 //                                                                           
00038 // Created: Wed Dec 14 09:16:15 2005                                         
00039 //                                                                           
00040 // Author: Odd A. Andersen <Odd.Andersen@sintef.no>
00041 //                                                                           
00042 // Revision: $Id: simple_tools_templates.h,v 1.6 2006/11/25 20:08:24 oan Exp $
00043 //                                                                           
00044 // Description:
00047 //                                                                           
00048 //===========================================================================
00049 
00050 #ifndef _SIMPLE_TOOLS_TEMPLATES_H
00051 #define _SIMPLE_TOOLS_TEMPLATES_H
00052 
00053 //#include "GoTensorProductSpline.h"
00054 #include <stdexcept>
00055 
00056 namespace {
00057 //===========================================================================
00058 template<typename T>
00059 T interpolate_value(const lsseg::Image<T>& img, 
00060                     int channel,
00061                     int x_pixel,
00062                     int y_pixel,
00063                     int z_pixel,
00064                     double x_off,
00065                     double y_off,
00066                     double z_off,
00067                     bool linear);
00068 //===========================================================================
00069 };
00070 
00071 namespace lsseg {
00072 
00073 //==============================================================================
00074 template<typename ImgType>
00075 void downsample_series(const ImgType& input, 
00076                        std::vector<ImgType >& result,
00077                        int min_num_pixels,
00078                        bool downscale_z,
00079                        double factor,
00080                        bool only_grayscale,
00081                        bool linear)
00082 //==============================================================================
00083 {
00084     // downsample in x and y (and possibly z)
00085     assert(input.dimx() >= min_num_pixels &&  input.dimy() >= min_num_pixels);
00086     if (downscale_z) {
00087         assert(input.dimz() >= min_num_pixels);
00088     }
00089     if (only_grayscale) {
00090         assert(input.numChannels() == 1 || input.numChannels() == 3);
00091     }
00092     assert(factor > 1);
00093 
00094     result.clear();
00095     result.push_back(input);
00096     if (only_grayscale && result[0].numChannels() != 1) {
00097         assert(result[0].numChannels() == 3);
00098         to_grayscale(result[0]);
00099     }
00100     if (factor <= 1) {
00101         return; // nothing more to do
00102     }
00103     
00104     int img_size[4];
00105     img_size[0] = result.front().dimx();
00106     img_size[1] = result.front().dimy();
00107     img_size[2] = result.front().dimz();
00108     img_size[3] = result.front().numChannels();
00109     // downscaling
00110     img_size[0] = int(img_size[0] / factor);
00111     img_size[1] = int(img_size[1] / factor);
00112     if (downscale_z) {
00113         img_size[2] = int(img_size[2] / factor);
00114     }
00115     while (img_size[0] >= min_num_pixels && 
00116            img_size[1] >= min_num_pixels && 
00117            (!downscale_z || img_size[2] >= min_num_pixels)) {
00118         result.push_back(ImgType(img_size[0], img_size[1], img_size[2], img_size[3]));
00119         resample_into(result.front(), result.back(), linear);
00120         img_size[0] = int(img_size[0] / factor);
00121         img_size[1] = int(img_size[1] / factor);
00122         if (downscale_z) {
00123             img_size[2] = int(img_size[2] / factor);
00124         }
00125     }
00126 }
00127 
00128 //===========================================================================
00129 template<typename ImgType>
00130 void resample_into(const ImgType& input, ImgType& target, bool linear)
00131 //===========================================================================
00132 {
00133     assert(target.numChannels() == input.numChannels());
00134     double input_len[3];
00135     double target_len_inv[3];
00136     input_len[0] = input.dimx() - 1;
00137     input_len[1] = input.dimy() - 1;
00138     input_len[2] = input.dimz() - 1;
00139     target_len_inv[0] = (target.dimx() > 1) ? double(1) / (target.dimx() - 1) : 0;
00140     target_len_inv[1] = (target.dimy() > 1) ? double(1) / (target.dimy() - 1) : 0;
00141     target_len_inv[2] = (target.dimz() > 1) ? double(1) / (target.dimz() - 1) : 0;
00142 
00143     typename ImgType::value_type *dp = target.begin();
00144 
00145     for (int c = 0; c != target.numChannels(); ++c) {
00146         for (int z = 0; z != target.dimz(); ++z) {
00147             const double z_rel_pos = z * target_len_inv[2];
00148             const int z_pix = int(input_len[2] * z_rel_pos);
00149             const double z_off = (input_len[2] * z_rel_pos) - z_pix;
00150             for (int y = 0; y != target.dimy(); ++y) {
00151                 const double y_rel_pos = y * target_len_inv[1];
00152                 const int y_pix = int(input_len[1] * y_rel_pos);
00153                 const double y_off = (input_len[1] * y_rel_pos) - y_pix;
00154                 for (int x = 0; x != target.dimx(); ++x) {
00155                     const double x_rel_pos = x * target_len_inv[0]; // in interval [0, 1]
00156                     const int x_pix = int(input_len[0] * x_rel_pos);
00157                     const double x_off = (input_len[0] * x_rel_pos) - x_pix;
00158                     *dp++ = interpolate_value(input, c, x_pix, y_pix, z_pix, x_off, y_off, z_off, linear);
00159                 }
00160             }
00161         }
00162     }
00163 }
00164 
00165 //===========================================================================
00166 template<typename T>
00167 void to_grayscale(Image<T>& img)
00168 //===========================================================================
00169 {
00170     ALWAYS_ERROR_IF(img.numChannels() != 1 && 
00171                     img.numChannels() != 3, "Image dimension must be 1 or 3");
00172     if (img.numChannels() == 1) {
00173         return;
00174     }
00175     // img.dim == 3
00176     Image<T> res(img.dimx(), img.dimy(), img.dimz(), 1);
00177     for (int z = 0; z < img.dimz(); ++z) {
00178         for (int y = 0; y < img.dimy(); ++y) {
00179             for (int x = 0; x < img.dimx(); ++x) {
00180                 double r = img(x, y, z, 0);
00181                 double g = img(x, y, z, 1);
00182                 double b = img(x, y, z, 2);
00183                 res(x, y, z, 0) = T(0.3 * r + 0.59 * g + 0.11 * b);
00184             }
00185         }
00186     }
00187     img.swap(res);
00188 }
00189 
00190 }; // end namespace lsseg
00191 
00192 namespace {
00193 
00194 //===========================================================================
00195 template<typename T>
00196 T interpolate_value(const lsseg::Image<T>& img, 
00197                     int ch,
00198                     int x_px,
00199                     int y_px,
00200                     int z_px,
00201                     double x_off,
00202                     double y_off,
00203                     double z_off,
00204                     bool linear)
00205 //===========================================================================
00206 {
00207     if (!linear) {
00208         // piecewise constant
00209         x_px = (x_off >= 0.5 && x_px < (img.dimx() - 1)) ? x_px + 1 : x_px;
00210         y_px = (y_off >= 0.5 && y_px < (img.dimy() - 1)) ? y_px + 1 : y_px;
00211         z_px = (z_off >= 0.5 && z_px < (img.dimz() - 1)) ? z_px + 1 : z_px;
00212         return img(x_px, y_px, z_px, ch);
00213     }
00214     // we will apply linear interpolation
00215     const int x_top = (x_px < (img.dimx() - 1)) ? x_px + 1 : x_px;
00216     const int y_top = (y_px < (img.dimy() - 1)) ? y_px + 1 : y_px;
00217     const int z_top = (z_px < (img.dimz() - 1)) ? z_px + 1 : z_px;
00218 
00219     // m/M ~ min/Max in y and z
00220     const T x_mm = x_off * img(x_top, y_px, z_px, ch) + (1 - x_off) * img(x_px, y_px, z_px, ch) ; 
00221     const T x_mM = x_off * img(x_top, y_px, z_top, ch) + (1 - x_off) * img(x_px, y_px, z_top, ch) ; 
00222     const T x_Mm = x_off * img(x_top, y_top, z_px, ch) + (1 - x_off) * img(x_px, y_top, z_px, ch) ; 
00223     const T x_MM = x_off * img(x_top, y_top, z_top, ch) + (1 - x_off) * img(x_px, y_top, z_top, ch) ; 
00224 
00225     const T y_m = y_off * x_Mm + (1 - y_off) * x_mm; // m ~ min, M ~ max in z coordinate
00226     const T y_M = y_off * x_MM + (1 - y_off) * x_mM; 
00227     
00228     const T z_res = z_off * y_M + (1 - z_off) * y_m;
00229 
00230     return z_res;
00231 }
00232 
00233 };
00234 
00235 #endif // _SIMPLE_TOOLS_TEMPLATES_H
00236 

Generated on Tue Nov 28 18:35:47 2006 for lsseg by  doxygen 1.4.7