Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

GeodesicRecEroBinaryImage.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------*
00002  | Library QgarLib, graphics analysis and recognition                  |
00003  | Copyright (C) 2002  Qgar Project, LORIA                             |
00004  |                                                                     |
00005  | This library is free software; you can redistribute it and/or       |
00006  | modify it under the terms of the GNU Lesser General Public          |
00007  | License version 2.1, as published by the Free Software Foundation.  |
00008  |                                                                     |
00009  | This library is distributed in the hope that it will be useful,     |
00010  | but WITHOUT ANY WARRANTY; without even the implied warranty of      |
00011  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                |
00012  | See the GNU Lesser General Public License for more details.         |
00013  |                                                                     |
00014  | The GNU Lesser General Public License is included in the file       |
00015  | LICENSE.LGPL, in the root directory of the Qgar packaging. See      |
00016  | http://www.gnu.org/licenses/lgpl.html for the terms of the licence. |
00017  | To receive a paper copy, write to the Free Software Foundation,     |
00018  | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.       |
00019  |                                                                     |
00020  | Contact Project Qgar for any information:                           |
00021  |   LORIA - équipe Qgar                                               |
00022  |   B.P. 239, 54506 Vandoeuvre-lès-Nancy Cedex, France                |
00023  |   email: qgar-contact@loria.fr                                      |
00024  |   http://www.qgar.org/                                              |
00025  *---------------------------------------------------------------------*/
00026 
00027 
00028 /**
00029  * @file  GeodesicRecEroBinaryImage.C
00030  * @brief Implementation of class qgar::GeodesicRecEroBinaryImage.
00031  *
00032  *        See file GeodesicRecEroBinaryImage.H for the interface.
00033  *
00034  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Mathieu Baeumler">Mathieu Baeumler</a>
00035  * @date   August 13, 2002  14:57
00036  * @since  Qgar 2.0
00037  */
00038 
00039 
00040 
00041 // STD
00042 #include <queue>
00043 #include <sstream>
00044 // QGAR
00045 #include <qgarlib/GeodesicRecEroBinaryImage.H>
00046 #include <qgarlib/QgarErrorDomain.H>
00047 
00048 
00049 
00050 using namespace std;
00051 
00052 
00053 namespace qgar
00054 {
00055 
00056 // ---------------------------------------------------------------------
00057 // C O N S T R U C T O R S
00058 // ---------------------------------------------------------------------
00059 
00060 GeodesicRecEroBinaryImage::GeodesicRecEroBinaryImage(BinaryImage& aMarkImg,
00061                                                      BinaryImage& aResImg)
00062   throw(QgarErrorDomain)
00063  : BinaryImage(aMarkImg)
00064 {
00065   if (   (aMarkImg.width()  != aResImg.width())
00066       || (aMarkImg.height() != aResImg.height()))
00067     {
00068       std::ostringstream os;
00069       os << "Marker image size ["
00070          << aMarkImg.width()
00071          << " X "
00072          << aMarkImg.height()
00073          << "] does not match result image size ["
00074          << aResImg.width()
00075          << " X "
00076          << aResImg.height()
00077          << "]";
00078       throw QgarErrorDomain(__FILE__, __LINE__,
00079                             "qgar::GeodesicRecEroBinaryImage::GeodesicRecEroBinaryImage(qgar::BinaryImage&, qgar::BinaryImage&)",
00080                             os.str());
00081     }
00082 
00083   perform(this, &aResImg);
00084 }
00085 
00086 
00087 // -------------------------------------------------------------------
00088 // G E O D E S I C   R E C O N S T R U C T I O N
00089 // -------------------------------------------------------------------
00090 
00091 void GeodesicRecEroBinaryImage::perform(BinaryImage* aMarkImg,
00092                                         BinaryImage* aResImg)
00093 {
00094 
00095   int width = aMarkImg->width(); // just some shortcuts
00096   int height = aMarkImg->height();
00097 
00098   // first enqueue the boundaries of marker image.
00099 
00100   // as we have to compare marker and goal image in the same time,
00101   // we won't enqueue the pointers on marker's pixels, but their
00102   // indice in pixMap (which are the same in goal's pixMap)
00103   queue< long > boundary;
00104   
00105   long indice; // indice in the queue
00106 
00107   BinaryImage::value_type* Jp; // pointer on marker image
00108   BinaryImage::value_type* Ip; // pointer on goal image
00109   BinaryImage::value_type* Jq; // pointer on current boundary pixel
00110   BinaryImage::value_type* Iq; // pointer on current goal boundary pixel
00111 
00112   BinaryImage::value_type* markerPixMap = aMarkImg->pPixMap(); // just some shortcuts
00113   BinaryImage::value_type* goalPixMap = aResImg->pPixMap();
00114  
00115   Jp = markerPixMap;
00116   Ip = goalPixMap;
00117 
00118   int minK, minL;
00119   int maxK, maxL;
00120 
00121   for (int i = 0; i < height; ++i)
00122     {
00123       for (int j = 0; j < width; ++j, ++Jp, ++Ip)
00124         {
00125           if (!*Jp && !*Ip)
00126             {
00127               // is this pixel in the boundary of marker image?
00128 
00129               /*** definition of current pixel's neighborhood ***/
00130 
00131               // between the first and the last line
00132               if ( (i > 0) && (i < height - 1) )
00133                 {
00134                   minK = -1;
00135                   maxK = 2;
00136 
00137                   // first pixel
00138                   if (j == 0)
00139                     {
00140                       minL = 0;
00141                       maxL = 2;
00142                     }
00143                   // between these two pixels
00144                   else if (j < width - 1)
00145                     {
00146                       minL = -1;
00147                       maxL = 2;
00148                     }
00149                   else
00150                     {
00151                       minL = -1;
00152                       maxL = 1;
00153                     }
00154                 }
00155               // first pixel
00156               else if (Jp == markerPixMap)
00157                 {
00158                   minK = minL = 0;
00159                   maxK = maxL = 2;
00160                 }
00161               // before last pixel of first line
00162               else if (Jp < markerPixMap + width - 1)
00163                 {
00164                   minK = 0;
00165                   minL = -1;
00166                   maxK = maxL = 2;
00167                 }
00168               // last pixel of first line
00169               else if (Jp ==  markerPixMap + width - 1)
00170                 {
00171                   minK = 0;
00172                   minL = -1;
00173                   maxK = 2;
00174                   maxL = 1;
00175                 }
00176               // first pixel of last line
00177               else if (j == 0)
00178                 {
00179                   minK = -1;
00180                   minL = 0;
00181                   maxK = 1;
00182                   maxL = 2;
00183                 }
00184               // before last pixel of last line
00185               else if (j < width - 1)
00186                 {
00187                   minK = minL = -1;
00188                   maxL = 2;
00189                   maxK = 1;
00190                 }
00191               // last pixel
00192               else
00193                 {
00194                   minL = minK = -1;
00195                   maxL = maxK = 1;
00196                 }
00197               
00198               for (int k = minK; k < maxK; ++k)
00199                 {
00200                   for (int l = minL ; l < maxL; ++l)
00201                     {
00202                       Jq = Jp + k*width + l;
00203 
00204                       if (*Jq)
00205                         {
00206                           boundary.push(Jp - markerPixMap);
00207                           // -----------------------------------------------
00208                           // HORROR! HORROR! HORROR! HORROR! HORROR! HORROR!
00209                           // -----------------------------------------------
00210                           k = 2;
00211                           break;
00212                           // -----------------------------------------------
00213                         }
00214                     } // END for l
00215                 } // END for k
00216 
00217             } // endif
00218 
00219         } // END for j
00220   } // END for i (end of scan)
00221 
00222   
00223   /*** propagation ***/
00224   
00225   //**** APPARENTLY NOT USED!
00226   //**** BinaryImage::value_type *minIndice = markerPixMap;
00227   //**** BinaryImage::value_type *maxIndice = minIndice + width*height - 1;
00228 
00229   while (!boundary.empty())
00230     {
00231       indice = boundary.front();
00232       boundary.pop();
00233     
00234       Jp = markerPixMap + indice;
00235       Ip = goalPixMap + indice;
00236 
00237       /*** definition of current pixel's neighborhood ***/
00238 
00239       // between the first and the last line
00240       if ( (Jp > markerPixMap + width - 1) && 
00241            (Jp < markerPixMap + (height - 1)*width) )
00242         {
00243           minK = -1;
00244           maxK = 2;
00245 
00246           // first pixel
00247           if ((Jp - markerPixMap) % width == 0)
00248             {
00249               minL = 0;
00250               maxL = 2;
00251             }
00252           // last pixel
00253           else if ((Jp - markerPixMap) % width == width - 1)
00254             {
00255               minL = -1;
00256               maxL = 1;
00257             }
00258       // between these two pixels
00259           else
00260             {
00261               minL = -1;
00262               maxL = 2;
00263             }
00264         }
00265       // first pixel
00266       else if (Jp == markerPixMap)
00267         {
00268           minK = minL = 0;
00269           maxK = maxL = 2;
00270         }
00271       // before last pixel of first line
00272       else if (Jp < markerPixMap + width - 1)
00273         {
00274           minK = 0;
00275           minL = -1;
00276           maxK = maxL = 2;
00277         }
00278       // last pixel of first line
00279       else if (Jp ==  markerPixMap + width - 1)
00280         {
00281           minK = 0;
00282           minL = -1;
00283           maxK = 2;
00284           maxL = 1;
00285         }
00286     // first pixel of last line
00287       else if (Jp == markerPixMap + (height - 1)*width)
00288         {
00289           minK = -1;
00290           minL = 0;
00291           maxK = 1;
00292           maxL = 2;
00293         }
00294       // before last pixel of last line
00295       else if (Jp < markerPixMap + height*width - 1)
00296         {
00297           minK = minL = -1;
00298           maxL = 2;
00299           maxK = 1;
00300         }
00301       // last pixel
00302       else
00303         {
00304           minL = minK = -1;
00305           maxL = maxK = 1;
00306         }
00307         
00308     for (int k = minK; k < maxK; ++k)
00309       {
00310         for (int l = minL ; l < maxL; ++l)
00311           {
00312             indice = (k * width) + l;
00313             Jq = Jp + indice;
00314             Iq = Ip + indice;
00315         
00316             if ( *Jq && (!*Iq) )
00317               {
00318                 *Jq = 0;
00319                 boundary.push(Jq - markerPixMap);       
00320               }
00321 
00322           } // END for l
00323       } // END for k
00324 
00325     } // END while
00326 }
00327 
00328 // ----------------------------------------------------------------------
00329 
00330 } // namespace qgar
00331