/home/oan/prosjekt/gotools/segmentation/gpl_distro/lsseg_1.0_gpl/src/cimg_dependent.C

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: cimg_dependent.C                                                    
00037 //                                                                           
00038 // Created: Tue Oct 25 13:29:10 2005                                         
00039 //                                                                           
00040 // Author: Odd A. Andersen <Odd.Andersen@sintef.no>
00041 //                                                                           
00042 // Revision: $Id: cimg_dependent.C,v 1.22 2006/11/25 20:08:28 oan Exp $
00043 //                                                                           
00044 // Description:
00047 //                                                                           
00048 //===========================================================================
00049 
00050 #include <set>
00051 #include <string>
00052 #include "errormacros.h"
00053 #include "CImg.h"
00054 #include "Image.h"
00055 #include "cimg_dependent.h"
00056 #include "simple_tools.h"
00057 //#include "GoBorrowedMVGrid.h"
00058 //#include "GoSelfcontainedGrid.h"
00059 
00060 //using namespace Go;
00061 using namespace std;
00062 using namespace cimg_library;
00063 using namespace lsseg;
00064 
00065 //===========================================================================
00066 namespace 
00067 //===========================================================================
00068 {
00069 
00070 
00071     void image2cimg(const Image<double>& img, CImg<double>& target, int z = -1)
00072     {
00073         if (z < 0) { // copy everything
00074             CImg<double> tmpImg(img.dimx(), img.dimy(), img.dimz(), img.numChannels());
00075             copy(img.begin(), img.end(), tmpImg.data);
00076             tmpImg.swap(target);
00077         } else { // copy only one image
00078             CImg<double> tmpImg(img.dimx(), img.dimy(), 1, img.numChannels());
00079             for (int c = 0; c < img.numChannels(); ++c) {
00080                 //cout << z << endl;
00081                 unsigned int offset = c * img.channelSize() + z * img.graySize2D();
00082                 //cout << offset << " " << offset + img.graySize2D() << endl;
00083                 copy(img.begin() + offset, 
00084                      img.begin() + offset + img.graySize2D(),
00085                      tmpImg.data + c * img.graySize2D());
00086             }
00087             tmpImg.swap(target);
00088         }
00089     }
00090 
00091     template<typename T>
00092     void cimg2image(const CImg<T>& img, Image<T>& target) 
00093     {
00094         target.resize(img.dimx(), img.dimy(), img.dimz(), img.dimv());
00095         copy(img.data, img.data + img.size(), target.begin());
00096     }
00097 
00098 }; // end anonymous namespace
00099 
00100 
00101 namespace lsseg {
00102 
00103 //===========================================================================
00104 void load_image(const char* name, Image<double>& target, bool convert_to_grayscale)
00105 //===========================================================================
00106 {
00107     CImg<double> tmp(name);
00108     cimg2image(tmp, target);
00109     if (convert_to_grayscale) {
00110         to_grayscale(target);
00111     }
00112 }
00113 
00114 //===========================================================================
00115 void load_image(const char* name, Image<int>& target, bool convert_to_grayscale)
00116 //===========================================================================
00117 {
00118     CImg<int> tmp(name);
00119     cimg2image(tmp, target);
00120     if (convert_to_grayscale) {
00121         to_grayscale(target);
00122     }
00123 }
00124 
00125 //===========================================================================
00126 void save_image(const char* name, const Image<double>& img)
00127 //===========================================================================
00128 {
00129     CImg<double> tmp(1, 1, 1, 1);
00130     image2cimg(img, tmp);
00131     tmp.save(name);
00132 }
00133 
00134 //===========================================================================
00135 void display_image(const Image<double>& img, int z)
00136 //===========================================================================
00137 {
00138     //   return;
00139 //#ifdef NDEBUG
00140     CImg<double> tmp(1, 1, 1, 1);
00141     image2cimg(img, tmp, z);
00142     tmp.display();
00143 //#endif
00144 }
00145 
00146 
00147 
00148 //===========================================================================
00149 void permanent_display(const Image<double>& img)
00150 //===========================================================================
00151 {
00152     //  the pointer to the display window will be lost, so there WILL be 
00153     // a memory leak.  However, this function is only intended for debug
00154     // purposes, and the display window is expected to live throughout the
00155     // execution of whatever test program uses this function.
00156     CImg<double> tmp(1, 1, 1, 1);
00157     image2cimg(img, tmp);
00158     new CImgDisplay(tmp);
00159 }
00160 
00161 //===========================================================================
00162 void blur_image(Image<double>& img, double rho)
00163 //===========================================================================
00164 {
00165     CImg<double> tmp(1,1,1,1);
00166     image2cimg(img,tmp);
00167     tmp.blur(rho);
00168     cimg2image(tmp, img);
00169 }
00170 
00171 //===========================================================================
00172 void blur_1D(double* data, unsigned int data_size, double rho)
00173 //===========================================================================
00174 {
00175     CImg<double> tmp(data_size, 1, 1, 1);
00176     std::copy(data, data + data_size, tmp.data);
00177     tmp.blur(rho);
00178     std::copy(tmp.data, tmp.data + data_size, data);
00179 }
00180 
00181 //===========================================================================
00182 void gaussian_noise(Image<double>& img, double sigma)
00183 //===========================================================================
00184 {
00185     CImg<double> tmp(1,1,1,1);
00186     image2cimg(img,tmp);
00187     tmp.noise(sigma, 0);
00188     cimg2image(tmp, img);
00189 }
00190 //
00192 //void display_distribution(const Image<double>& img)
00194 //{
00195 //    // only applied on the first image in the stack represented by 'img'
00196 //    MESSAGE_IF(img.dimz() != 1,
00197 //             "Warning: displaying distribution only on first image of stack.");
00198 //    
00199 //    CImg<double> tmp(1, 1, 1, 1);
00200 //    const unsigned int level_size = img.dimx() * img.dimy();
00201 //    for (int d = 0; d < img.numChannels(); ++d) {
00202 //      Image<double> tmp_img(img.dimx(), img.dimy());
00203 //      copy(img.begin() + d * level_size, img.begin() + (d+1) * level_size, tmp_img.begin());
00204 //      image2cimg(tmp_img, tmp);
00205 //      CImg<double> hist = tmp.get_histogram();
00206 //      display_graph(hist.dimx(), hist.data);
00207 //    }
00208 //}
00209 
00210 //===========================================================================
00212 struct Pimpl  // implementation of UpdatableImage
00213 //===========================================================================
00214 {
00215     Pimpl(const Image<double>& img, const char* name) : 
00216         disp_(img.dimx(), img.dimy(), name), name_(name)
00217     {
00218         update(img, false);
00219     }
00220 
00221     void update(const Image<double>& img, bool reshape) {
00222         image2cimg(img, i_);
00223         if (disp_.is_resized) {
00224             resize(); // this will also display the new i_
00225         } else {
00226             disp_.display(i_);
00227         }
00228         if (reshape) {
00229             resize(img.dimx(), img.dimy());
00230         }
00231         disp_.show();   
00232     }
00233 
00234     void callbackLoop() 
00235     {
00236         while(true) {
00237             int mouse_state = disp_.button;
00238             if (mouse_state & 1 ) { // left button or space
00239                 int x, y;
00240                 getMouseXY(x, y);
00241                 cout << "(" << x << ", " << y << ") : " << endl;
00242                 printColorInfo(x, y);
00243                 set<Pimpl*>::iterator it;
00244                 for (it = connecteds_.begin(); it != connecteds_.end(); ++it) {
00245                     (*it)->printColorInfo(x, y);
00246                 }
00247                 cout << endl;
00248                 disp_.wait();
00249             }
00250             if (mouse_state & 2 || disp_.key == cimg::keySPACE) { // right button or space
00251                 disp_.key =0;
00252                 break; // handle control to program
00253             }
00254             if (mouse_state & 4) { // middle button
00255                 cout << "no function for the middle button yet" << endl; // print friendly message
00256             }
00257             if (disp_.is_resized) {
00258                 resize();
00259                 set<Pimpl*>::iterator it;
00260                 for (it = connecteds_.begin(); it != connecteds_.end(); ++it) {
00261                     (*it)->resize(disp_.window_width, disp_.window_height);
00262                 }
00263             }
00264         } 
00265     }
00266 
00267     void connect(Pimpl* rhs) {
00268         connecteds_.insert(rhs);
00269         rhs->connecteds_.insert(this);
00270     }
00271 
00272     void resize(int x = -1, int y = -1) 
00273     {
00274         if (x > 0 && y > 0) {
00275             disp_.resize(x, y);
00276         } else {
00277             disp_.resize();
00278         }
00279         disp_.display(i_);
00280     }
00281 
00282 private:
00283     // data members 
00284     CImg<double> i_;
00285     CImgDisplay disp_;
00286     string name_;
00287     set<Pimpl*> connecteds_;
00288 
00289     void getMouseXY(int& x, int& y) 
00290     {
00291         x = disp_.mouse_x;
00292         y = disp_.mouse_y;
00293         
00294         x *= i_.dimx();
00295         y *= i_.dimy();
00296         
00297         x /= disp_.window_width;
00298         y /= disp_.window_height;
00299     }
00300 
00301     void printColorInfo(int x, int y) {
00302         cout << name_ << ": ";
00303         cout << "[ ";
00304         for (int i = 0; i < i_.dimv(); ++i) {
00305             cout << i_(x, y, 0, i) << " ";
00306         }
00307         cout << "]" << endl;
00308     }
00309 };
00311 
00312 //===========================================================================
00313 UpdatableImage::UpdatableImage(const Image<double>& img, 
00314                                const char* name) : p_(new Pimpl(img, name)) {}
00315 UpdatableImage::~UpdatableImage() { delete p_;}
00316 void UpdatableImage::update(const Image<double>& img, bool reshape) { p_->update(img, reshape);}
00317 void UpdatableImage::interact() { p_->callbackLoop();}
00318 void UpdatableImage::connect(UpdatableImage& rhs) { p_->connect(rhs.p_);}
00319 //===========================================================================
00320  
00321 }; // end namespace lsseg

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