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

HysteresisBinaryImage.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  | The implementation of the hysteresis algorithm is strongly inspired |
00030  | by that made by Simon A.J. Winder in the IMG* package. Here is his  |
00031  | copyright notice:                                                   |
00032  |                                                                     |
00033  |             IMG* Image Processing Toolset and C Library             |
00034  |                                                                     |
00035  |                   Copyright 1994 Simon A.J. Winder                  |
00036  |                        All Rights Reserved                          |
00037  |                                                                     |
00038  | Permission to use, copy, and modify this software and its           |
00039  | documentation is hereby granted only under the following terms and  |
00040  | conditions.  Both the above copyright notice and this permission    |
00041  | notice must be included along with all copies of the software,      |
00042  | derivative works or modified versions, and any portions thereof,    |
00043  | and both notices must appear in supporting documentation.           |
00044  |                                                                     |
00045  | This software may be distributed (but not offered for sale or       |
00046  | transferred for compensation) to third parties, provided such third |
00047  | parties agree to abide by the terms and conditions of this notice.  |
00048  |                                                                     |
00049  | The software is provided "as is" and the author disclaims all       |
00050  | warranties with regard to this software, including all implied      |
00051  | warranties of merchantability and fitness. In no event shall the    |
00052  | author  be liable for any special, direct, indirect, or             |
00053  | consequential damages or any damages whatsoever resulting from loss |
00054  | of use, data or profits, whether in an action of contract,          |
00055  | negligence or other tortious action, arising out of or in           |
00056  | connection with the use or performance of this software.            |
00057  *---------------------------------------------------------------------*/
00058 
00059 
00060 /**
00061  * @file   HysteresisBinaryImage.C
00062  * @brief  Implementation of class qgar::HysteresisBinaryImage.
00063  *
00064  *         See file HysteresisBinaryImage.H for the interface.
00065  *
00066  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Karl Tombre">Karl Tombre</a>
00067  * @date   July 3, 2001  16:30
00068  * @since  Qgar 1.0
00069  */
00070 
00071 
00072 
00073 // STD
00074 #include <stack>
00075 #include <vector>
00076 // QGAR
00077 #include <qgarlib/GradientLocalMaxImage.H>
00078 #include <qgarlib/HysteresisBinaryImage.H>
00079 #include <qgarlib/primitives.H>
00080 
00081 
00082 
00083 using namespace std;
00084 
00085 
00086 
00087 namespace qgar
00088 {
00089 
00090 // -------------------------------------------------------------------
00091 // C O N S T R U C T O R
00092 // -------------------------------------------------------------------
00093 HysteresisBinaryImage::HysteresisBinaryImage
00094   (const GradientLocalMaxImage& aGradImg,
00095    unsigned int aLowThrsl,
00096    unsigned int aHighThrsl)
00097 
00098     : BinaryImage(aGradImg.width(), aGradImg.height())  // Allocate binary image
00099   
00100 {
00101   // Stack of points
00102   stack< Point, vector<Point> >  stackPt;
00103 
00104   // Create two images for low and high thresholded images
00105   BinaryImage lowImg (_width, _height);
00106   BinaryImage highImg(_width, _height);
00107   
00108   // Fill them with 1's and 0's
00109   int size = _width * _height;
00110   BinaryImage::value_type* pMapLow  = lowImg.pPixMap();
00111   BinaryImage::value_type* pMapHigh = highImg.pPixMap();
00112   float* pMapGrad = aGradImg.pPixMap();
00113 
00114   for (int iCnt = 0 ;
00115        iCnt < size ;
00116        ++iCnt, ++pMapLow, ++pMapHigh, ++pMapGrad)
00117     {
00118       float pix = *pMapGrad;
00119 
00120       if ((pix == 0.0) || (pix < aLowThrsl))
00121         {
00122           (*pMapLow) = QGE_BW_WHITE;
00123         }
00124       else
00125         {
00126           (*pMapLow) = QGE_BW_BLACK;
00127         }
00128 
00129       if ((pix == 0.0) || (pix < aHighThrsl))
00130         {
00131           (*pMapHigh) = QGE_BW_WHITE;
00132         }
00133       else
00134         {
00135           (*pMapHigh) = QGE_BW_BLACK;
00136         }
00137     }
00138 
00139   // highImg is seed of final result
00140   BinaryImage::operator=(highImg);
00141 
00142   // Add all points on edges with a gradient lower than high but
00143   // higher than low that are connected to strong edges
00144   for (int y = 0 ; y < _height ; ++y)
00145     {
00146       for (int x = 0; x < _width ; ++x)
00147         {
00148 
00149           // if we have a seed
00150           if (highImg.pixel(x, y) != QGE_BW_WHITE)
00151             {
00152               // Push starting point and clear from lowImg
00153               Point pt(x, y);
00154               stackPt.push(pt);
00155               lowImg.setPixel(x, y, QGE_BW_WHITE);
00156 
00157               // Trace the line from this point
00158               while (! stackPt.empty())
00159                 {
00160                   pt = stackPt.top();
00161                   stackPt.pop();
00162                   // write point to output and delete from highImg
00163                   int ptX = pt.x();
00164                   int ptY = pt.y();
00165                   setPixel(ptX, ptY, QGE_BW_BLACK);
00166 
00167                   highImg.setPixel(ptX, ptY, QGE_BW_WHITE);
00168                   
00169                   // Stack and delete points we want to go to next
00170                   for (int yCnt = ptY - 1 ; yCnt < (ptY + 2) ; ++yCnt)
00171                     {
00172                       for (int xCnt = ptX - 1 ; xCnt < (ptX + 2) ; ++xCnt)
00173                         {
00174                           if (   (yCnt >= 0)
00175                               && (yCnt < _height)
00176                               && (xCnt >= 0)
00177                               && (xCnt < _width)
00178                               && (lowImg.pixel(xCnt, yCnt) != QGE_BW_WHITE))
00179                               {
00180                                 pt.setXY(xCnt, yCnt);
00181                                 stackPt.push(pt);
00182                                 lowImg.setPixel(xCnt, yCnt, QGE_BW_WHITE);
00183                               }
00184                         } // END for xCnt
00185                     } // END for yCnt
00186                 } // END while
00187             } // END if
00188 
00189         } // END for x
00190     } // END for y
00191 }
00192 // -------------------------------------------------------------------
00193 
00194 } // namespace qgar