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

sobel3x3_Filter.cpp

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission :
00003         Realtime Vision Processing System
00004 
00005     Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008 
00009  ---------------------------------------------------------------------------
00010     sobel 3x3
00011     
00012     * This code is part of IPL, and is released under version 2 of the GPL.
00013     * Copyright (c) 2003 John R. Watson.  See README and COPYING for more
00014     * information.
00015  ---------------------------------------------------------------------------
00016 
00017     This file is part of Phission.
00018 
00019     Phission is free software; you can redistribute it and/or modify
00020     it under the terms of the GNU Lesser General Public License as published by
00021     the Free Software Foundation; either version 2 of the License, or
00022     (at your option) any later version.
00023 
00024     Phission is distributed in the hope that it will be useful,
00025     but WITHOUT ANY WARRANTY; without even the implied warranty of
00026     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00027     GNU Lesser General Public License for more details.
00028 
00029     You should have received a copy of the GNU Lesser General Public License
00030     along with Phission; if not, write to the Free Software
00031     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00032 
00033  ---------------------------------------------------------------------------*/
00034 #ifdef HAVE_CONFIG_H
00035     #include <phissionconfig.h>
00036 #endif
00037 
00038 #include <phStandard.h>
00039 
00040 #include <math.h>
00041 #include <sobel3x3_Filter.h>
00042 
00043 #include <phError.h>
00044 #include <phMemory.h>
00045 #include <phPrint.h>
00046 
00047 /* ---------------------------------------------------------------------- *
00048  * From John R. Watson's IPL, included with Phission:                     *
00049  *          phission/filter/packages/ipl-1.0.0.tar.gz                     *
00050  * ---------------------------------------------------------------------- */
00051 #ifdef __cplusplus
00052 extern "C" 
00053 {
00054 #endif /* __cplusplus */
00055 /* ----------------------------------------------------------------------------
00056  * sobel.c -- Sobel edge detection
00057  * ----------------------------------------------------------------------------
00058  * John R. Watson (jwatson@cs.uml.edu)
00059  * 91.549 Robotics II, Vision Project 1
00060  * DUE 11/13/03
00061  * ----------------------------------------------------------------------------
00062  * This code is part of IPL, and is released under version 2 of the GPL.
00063  * Copyright (c) 2003 John R. Watson.  See README and COPYING for more
00064  * information.
00065  */
00066 
00067 
00068 /* ----------------------------------------------------------------------------
00069  * sobel - Sobel edge detection
00070  * ----------------------------------------------------------------------------
00071  * This algorithm is about as optimized as I can get it without resorting to
00072  * assembly language tricks.  Sobel edge detection is usually performed by
00073  * doing two 3x3 convolutions over the image (gx & gy), and then taking
00074  * sqrt(gx*gx + gy*gy).  However, we can quickly compute the gradient
00075  * magnitude by performing a single pseudo-convolution instead.
00076  * ------------------------------------------------------------------------- */
00077 int ipl_edge_sobel(uint8_t *src, uint8_t *dst, int w, int h)
00078 {
00079     uint8_t *srcp;
00080     uint8_t p1; /*  --------------  */
00081     uint8_t p2; /* | P1 | P2 | P3 | */
00082     uint8_t p3; /* |----|----|----| */
00083     uint8_t p4; /* | P4 | P5 | P6 | */
00084     uint8_t p5; /* |----|----|----| */
00085     uint8_t p6; /* | P7 | P8 | P9 | */
00086     uint8_t p7; /*  --------------  */
00087     uint8_t p8;
00088     uint8_t p9;
00089     int stride;
00090     int g;
00091     int x;
00092     int y;
00093     int i;
00094     int j;
00095 
00096     /* we can't filter the edge pixels in a 3x3 convolution, so we end up
00097      * with a 1-pixel border around the destination image.  we move the
00098      * dst pointer in 1 pixel in the X and Y dimensions.  we also
00099      * pre-compute the row stride for this image
00100      */
00101     dst   += (w + 1) * 3;
00102     stride = w * 3;
00103 
00104     /* instead of convolving a 2 3x3 kernels with a 3x3 window in the src
00105      * image, we take the values of the 9 pixels in that window and use
00106      * the following formula to approximate the gradient magnitude:
00107      *  |G| = |(p1 + (p2 * 2) + p3) - (p7 + (p8 * 2) + p9)| +
00108      *        |(p3 + (p6 * 2) + p9) - (p1 + (p4 * 2) + p7)|
00109      *
00110      * I should mention that I'm only performing edge-detection in the red
00111      * color channel.
00112      */
00113     for (y=0; y<h-2; y++)
00114     {
00115         for (x=0; x<w-2; x++)
00116         {
00117             /* get a pointer to our current 3x3 window, and then
00118              * bump the src to the next pixel
00119              */
00120             srcp = src;
00121             src += 3;
00122 
00123             /* this is called "loop unrolling."  It's a synonym
00124              * for "I hate you."
00125              */
00126             p1 = *srcp;
00127             p2 = *(srcp + 3);
00128             p3 = *(srcp + 6);
00129         
00130             /* move down to the next row */ 
00131             srcp += stride;
00132             
00133             p4 = *srcp;
00134             p5 = *(srcp + 3);
00135             p6 = *(srcp + 6);
00136 
00137             srcp += stride;
00138             
00139             p7 = *srcp;
00140             p8 = *(srcp + 3);
00141             p9 = *(srcp + 6);
00142 
00143             i = p1 + (p2 * 2) + p3;
00144             j = p7 + (p8 * 2) + p9;
00145                 g = abs(i - j);
00146 
00147             i = p3 + (p6 * 2) + p9;
00148             j = p1 + (p4 * 2) + p7;
00149             g += abs(i - j);
00150 
00151             g = 255 - phCLIP(g);
00152 
00153             *dst++ = g;
00154             *dst++ = g;
00155             *dst++ = g;
00156         }
00157 
00158         /* move down to the next row */
00159         dst += 6;
00160         src += 6;
00161     }
00162 
00163     return 0;
00164 }
00165 
00166 #ifdef __cplusplus
00167 }; /* extern "C" */
00168 #endif /* __cplusplus */
00169 
00170 /* ---------------------------------------------------------------------- */
00171 sobel3x3_Filter::sobel3x3_Filter() :
00172     phFilter("sobel3x3_Filter")
00173 
00174 {
00175     this->m_format = phImageRGB24;
00176     this->m_output = NULL;
00177     this->m_outputSize = 0;
00178 }
00179 
00180 /* ---------------------------------------------------------------------- */
00181 sobel3x3_Filter::~sobel3x3_Filter()
00182 {
00183     phFree(this->m_output);
00184 }
00185 
00186 /* ------------------------------------------------------------------------ */
00187 phFilter *sobel3x3_Filter::cloneFilter()
00188 {
00189     return (phFilter *)new sobel3x3_Filter();
00190 }
00191 
00192 /* ---------------------------------------------------------------------- */
00193 int sobel3x3_Filter::filter()
00194 {
00195     phFUNCTION("sobel3x3_Filter::filter")
00196 
00197     phDALLOC_RESIZE(this->m_output,
00198                     this->m_outputSize,
00199                     width*height*depth,
00200                     uint8_t);
00201 
00202     rc = ipl_edge_sobel((uint8_t *)Image, 
00203                         (uint8_t *)this->m_output,
00204                         width,
00205                         height);
00206     phCHECK_RC(rc,NULL,"ipl_edge_sobel returned error.");
00207     
00208     phMemcpy(Image,
00209            this->m_output,
00210            this->m_outputSize);
00211     
00212     return phSUCCESS;
00213 error:
00214     return phFAIL;
00215 }
00216 
00217 




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:11 2007 for phission by  doxygen 1.4.4