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

Dist34Image.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  Dist34Image.C
00030  * @brief Implementation of class Dist34Image.
00031  *
00032  *        See file Dist34Image.H for the interface.
00033  *
00034  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Perrin & Kheder">Julien Perrin & Sami Kheder</a>
00035  * @date   March 24,  2003  16:16
00036  * @since  Qgar 2.1.1
00037  */
00038 
00039 
00040 // STL
00041 #include <algorithm>
00042 #include <limits>
00043 // QGAR
00044 #include <qgarlib/Dist34Image.H>
00045 #include <qgarlib/GenImage.H>
00046 
00047 
00048 
00049 namespace qgar
00050 {
00051 
00052 // -------------------------------------------------------------------
00053 // C O N S T R U C T O R
00054 // -------------------------------------------------------------------
00055 
00056 
00057 Dist34Image::Dist34Image(const BinaryImage& anImg)
00058 
00059   : IntImage(anImg.width(), anImg.height())
00060 
00061 {
00062   // ''neutral'' pixel value for the distance transformation
00063   const int DIST34_NEUTRAL = INT_MAX;
00064 
00065   // Pointer to source and result pixmaps
00066   const BinaryImage::value_type* pMapImg;
00067   IntImage::value_type*          pMapRes = _pPixMap;
00068 
00069   // Top to bottom, left to right
00070 
00071   // First line
00072   for (int iCnt = 0 ; iCnt < _width ; ++iCnt)
00073     {
00074       *pMapRes = DIST34_NEUTRAL;
00075       ++pMapRes;
00076     }
00077 
00078   // First and last columns
00079   for (int iCnt = 1 ; iCnt < (_height - 1) ; ++iCnt, pMapRes += _width)
00080     {
00081       *pMapRes = DIST34_NEUTRAL;
00082       *(pMapRes + _width - 1) = DIST34_NEUTRAL;
00083     }
00084  
00085   // Last line
00086   for (int iCnt = 0 ; iCnt < _width ; ++iCnt)
00087     {
00088       *pMapRes = DIST34_NEUTRAL;
00089       ++pMapRes;
00090     }
00091  
00092 
00093   // TOP TO BOTTOM, LEFT TO RIGHT NEIGHBORHOOD
00094   //
00095   //         +--+--+--+
00096   //         |P2|P3|P4|
00097   //         +--+--+--+
00098   //         |P1| x|  |
00099   //         +--+--+--+
00100   //         |  |  |  |
00101   //         +--+--+--+
00102 
00103 
00104   pMapImg =  anImg.pPixMap() + anImg.width() + 1;
00105   pMapRes =  pPixMap() + _width + 1;
00106  
00107   for (int iCnt = 1 ; iCnt < (_height -1); ++iCnt)
00108     {
00109       for (int jCnt = 1 ; jCnt < (_width -1); ++jCnt, ++pMapImg, ++pMapRes)
00110         {  
00111 
00112           if (*pMapImg == QGE_BW_WHITE)
00113             {
00114               // ======================
00115               // CURRENT PIXEL IS WHITE
00116               // ======================
00117 
00118               // ******** P1 ********
00119 
00120               if ((*(pMapImg - 1)) == QGE_BW_WHITE)
00121                 {
00122                   if (*(pMapRes - 1) != DIST34_NEUTRAL)
00123                     {
00124                       *pMapRes = *(pMapRes - 1) + 3;
00125                     }
00126                   else
00127                     {
00128                       *pMapRes = DIST34_NEUTRAL;
00129                     }
00130                 }
00131               else 
00132                 {
00133                   *pMapRes = 3;
00134                 }
00135 
00136               // ******** P2 ********
00137 
00138               if ( (*(pMapImg - _width - 1)) == QGE_BW_WHITE)
00139                 { 
00140                   if (*(pMapRes - _width - 1) != DIST34_NEUTRAL)
00141                     {
00142                       *pMapRes = std::min(*pMapRes, *(pMapRes - _width - 1) + 4);
00143                     }
00144                   else
00145                     {
00146                       *pMapRes = std::min(*pMapRes, DIST34_NEUTRAL);
00147                     }
00148                 }
00149               else 
00150                 {
00151                   *pMapRes = std::min(*pMapRes, 4);
00152                 }
00153 
00154               // ******** P3 ********
00155 
00156               if ((*(pMapImg - _width)) == QGE_BW_WHITE)
00157                 {
00158                   if (*(pMapRes - _width) != DIST34_NEUTRAL)
00159                     {
00160                       *pMapRes = std::min(*pMapRes, *(pMapRes - _width) + 3);
00161                     }
00162                   else
00163                     {
00164                       *pMapRes = std::min(*pMapRes, DIST34_NEUTRAL);
00165                     }
00166                 }
00167               else 
00168                 {
00169                   *pMapRes = 3;
00170                 }
00171 
00172               // ******** P4 ********
00173 
00174               if ((*(pMapImg - _width + 1)) == QGE_BW_WHITE)
00175                 {
00176                   if (*(pMapRes - _width + 1) != DIST34_NEUTRAL)
00177                     {
00178                       *pMapRes = std::min(*pMapRes, *(pMapRes - _width + 1) + 4);
00179                     }
00180                   else
00181                     {
00182                       *pMapRes = std::min(*pMapRes, DIST34_NEUTRAL);
00183                     }
00184                 }
00185               else 
00186                 {
00187                   *pMapRes = std::min(*pMapRes, 4);
00188                 }
00189 
00190               // ==================
00191               // END OF WHITE PIXEL
00192               // ==================
00193             }
00194 
00195           else 
00196 
00197             {
00198               // ======================
00199               // CURRENT PIXEL IS BLACK
00200               // ======================
00201 
00202               // ******** P1 ********
00203 
00204               if ((*( pMapImg - 1)) == QGE_BW_BLACK)
00205                 {
00206                   if (*(pMapRes - 1) != DIST34_NEUTRAL)
00207                     {
00208                       *pMapRes = *(pMapRes - 1) + 3;
00209                     }
00210                   else
00211                     {
00212                       *pMapRes = DIST34_NEUTRAL;
00213                     }
00214                 }
00215               else 
00216                 {
00217                   *pMapRes = 3;
00218                 }
00219 
00220               // ******** P2 ********
00221 
00222               if ((*(pMapImg - _width - 1)) == QGE_BW_BLACK)
00223                 {
00224                   if (*(pMapRes - _width - 1) != DIST34_NEUTRAL)
00225                     {
00226                       *pMapRes = std::min(*pMapRes, *(pMapRes - _width - 1) + 4);
00227                     }
00228                   else
00229                     {
00230                       *pMapRes = std::min(*pMapRes, DIST34_NEUTRAL);
00231                     }
00232                 }
00233               else 
00234                 {
00235                   *pMapRes = std::min(*pMapRes, 4);
00236                 }
00237 
00238               // ******** P3 ********
00239 
00240               if ((*(pMapImg - _width)) == QGE_BW_BLACK)
00241                 {
00242                   if (*(pMapRes - _width) != DIST34_NEUTRAL)
00243                     {
00244                       *pMapRes = std::min(*pMapRes, *(pMapRes - _width) + 3);
00245                     }
00246                   else
00247                     {
00248                       *pMapRes = std::min(*pMapRes, DIST34_NEUTRAL);
00249                     }
00250                 }
00251               else 
00252                 {
00253                   *pMapRes = 3;
00254                 }
00255 
00256               // ******** P4 ********
00257 
00258               if ( (*(pMapImg - _width + 1)) == QGE_BW_BLACK)
00259                 {
00260                   if (*(pMapRes - _width + 1) != DIST34_NEUTRAL)
00261                     {
00262                       *pMapRes = std::min(*pMapRes, *(pMapRes - _width + 1) + 4);
00263                     }
00264                   else
00265                     {
00266                       *pMapRes = std::min(*pMapRes, DIST34_NEUTRAL);
00267                     }
00268                 }
00269               else 
00270                 {
00271                   *pMapRes = std::min(*pMapRes, 4);
00272                 }
00273 
00274               // ==================
00275               // END OF BLACK PIXEL
00276               // ==================
00277             }
00278         } // END for jCnt
00279 
00280       pMapImg += 2;
00281       pMapRes += 2;
00282 
00283     } // END for iCnt
00284 
00285 
00286   //  BOTTOM TO TOP, RIGHT TO LEFT NEIGHBORHOOD
00287   //
00288   //        +--+--+--+
00289   //        |  |  |  |
00290   //        +--+--+--+
00291   //        |  | x|P5|
00292   //        +--+--+--+
00293   //        |P6|P7|P8|
00294   //        +--+--+--+
00295 
00296   int size = _width * _height;  // Image size
00297 
00298   pMapImg = anImg.pPixMap() + size - anImg.width() - 2; 
00299   pMapRes = _pPixMap + size - _width - 2;
00300 
00301 
00302   for (int iCnt = _height - 2; iCnt > 0; --iCnt)
00303     {
00304       for (int jCnt = _width - 2; jCnt > 0; --jCnt, --pMapImg, --pMapRes)
00305         {
00306 
00307           if (*pMapImg == QGE_BW_WHITE)
00308             {
00309               // ======================
00310               // CURRENT PIXEL IS WHITE
00311               // ======================
00312 
00313               // ******** P5 ********
00314 
00315               if ((*(pMapImg + 1)) == QGE_BW_WHITE)
00316                 {
00317                   if (*(pMapRes + 1) != DIST34_NEUTRAL)
00318                     {
00319                       *pMapRes = std::min(*pMapRes, *(pMapRes + 1) + 3);
00320                     }
00321                 }
00322               else 
00323                 {
00324                   *pMapRes = 3;
00325                 }
00326 
00327               // ******** P6 ********
00328 
00329               if ((*(pMapImg + _width - 1)) == QGE_BW_WHITE)
00330                 { 
00331                   if (*(pMapRes + _width - 1) != DIST34_NEUTRAL)
00332                     {
00333                       *pMapRes = std::min(*pMapRes, *(pMapRes + _width - 1) + 4);
00334                     }
00335                 }
00336               else 
00337                 {
00338                   *pMapRes = std::min(*pMapRes, 4);
00339                 }
00340 
00341               // ******** P7 ********
00342 
00343               if ((*(pMapImg + _width)) == QGE_BW_WHITE)
00344                 {
00345                   if (*(pMapRes + _width) != DIST34_NEUTRAL)
00346                     {
00347                       *pMapRes = std::min(*pMapRes, *(pMapRes + _width) + 3);
00348                     }
00349                 }
00350               else 
00351                 {
00352                   *pMapRes = 3;
00353                 }
00354 
00355               // ******** P8 ********
00356 
00357               if ((*(pMapImg + _width + 1)) == QGE_BW_WHITE)
00358                 {
00359                   if (*(pMapRes + _width + 1) != DIST34_NEUTRAL)
00360                     {
00361                       *pMapRes = std::min(*pMapRes, *(pMapRes + _width + 1) + 4);
00362                     }
00363                 }
00364               else 
00365                 {
00366                   *pMapRes = std::min(*pMapRes, 4);
00367                 }
00368               
00369               // ==================
00370               // END OF WHITE PIXEL
00371               // ==================
00372             }
00373 
00374           else
00375 
00376             {
00377               // ======================
00378               // CURRENT PIXEL IS BLACK
00379               // ======================
00380 
00381               // ******** P5 ********
00382 
00383               if ((*(pMapImg + 1)) == QGE_BW_BLACK)
00384                 {
00385                   if (*(pMapRes + 1) != DIST34_NEUTRAL)
00386                     {
00387                       *pMapRes = std::min(*pMapRes, *(pMapRes + 1) + 3);
00388                     }
00389                 }
00390               else 
00391                 {
00392                   *pMapRes = 3;
00393                 }
00394 
00395               // ******** P6 ********
00396 
00397               if ( (*(pMapImg + _width - 1)) == QGE_BW_BLACK)
00398                 {
00399                   if (*(pMapRes + _width - 1))
00400                     {
00401                       *pMapRes = std::min(*pMapRes, *(pMapRes + _width - 1) + 4);
00402                     }
00403                 }
00404               else 
00405                 {
00406                   *pMapRes = std::min(*pMapRes, 4);
00407                 }
00408 
00409               // ******** P7 ********
00410 
00411               if ((*(pMapImg + _width)) == QGE_BW_BLACK)
00412                 { 
00413                   if (*(pMapRes + _width) != DIST34_NEUTRAL)
00414                     {
00415                       *pMapRes = std::min(*pMapRes, *(pMapRes + _width) + 3);
00416                     }
00417                 }
00418               else 
00419                 {
00420                   *pMapRes = 3;
00421                 }
00422 
00423               // ******** P8 ********
00424 
00425               if ((*(pMapImg + _width + 1)) == QGE_BW_BLACK)
00426                 {
00427                   if (*(pMapRes + _width + 1) != DIST34_NEUTRAL)
00428                     {
00429                       *pMapRes = std::min(*pMapRes, *(pMapRes + _width + 1) + 4);
00430                     }
00431                 }
00432               else 
00433                 {
00434                   *pMapRes = std::min(*pMapRes, 4);
00435                 }
00436 
00437               // ==================
00438               // END OF BLACK PIXEL
00439               // ==================
00440             }
00441           
00442         } // END for jCnt
00443 
00444       pMapImg -= 2;
00445       pMapRes -= 2;
00446 
00447     } // END for iCnt
00448 }
00449 
00450 
00451 // -------------------------------------------------------------------
00452 
00453 } // namespace qgar
00454 
00455 
00456