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

canny_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     This file is part of Phission.
00010 
00011     Phission is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU Lesser General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     Phission is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU Lesser General Public License for more details.
00020 
00021     You should have received a copy of the GNU Lesser General Public License
00022     along with Phission; if not, write to the Free Software
00023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025  ---------------------------------------------------------------------------*/
00026 #ifdef HAVE_CONFIG_H
00027     #include <phissionconfig.h>
00028 #endif
00029 
00030 #include <phStandard.h>
00031 
00032 #include <canny_Filter.h>
00033 
00034 #define UNROLL_LOOP 1
00035     
00036 #define TIMESTUFF() 0
00037 
00038 #include <phMath.h>
00039 #include <phError.h>
00040 #include <phMemory.h>
00041 #include <phPrint.h>
00042 
00043 /* ---------------------------------------------------------------------- */
00044 canny_Filter::canny_Filter( uint32_t lowThreshold,
00045                             uint32_t highThreshold ) :
00046     phFilter("canny_Filter")
00047 
00048 {
00049     this->m_format = (  phImageRGB24 |
00050                         phImageRGBA32 |
00051                         phImageGREY8 );
00052 
00053     this->m_gauss       = NULL;
00054     this->m_edge        = NULL;
00055     this->m_gaussSize   = 0;
00056     this->m_edgeSize    = 0;
00057 
00058     this->m_useGaussian     = 1;
00059     this->m_useSobelApprox  = 1;
00060     
00061     this->set(lowThreshold, highThreshold);
00062 }
00063 
00064 /* ---------------------------------------------------------------------- */
00065 canny_Filter::~canny_Filter()
00066 {
00067     phFree(this->m_gauss);
00068     phFree(this->m_edge);
00069 }
00070 
00071 /* ------------------------------------------------------------------------ */
00072 phFilter *canny_Filter::cloneFilter()
00073 {
00074     phFUNCTION("canny_Filter::cloneFilter")
00075     int locked = 0;
00076     canny_Filter *canny = new canny_Filter();
00077 
00078     phTHIS_LOOSE_LOCK(locked);
00079 
00080     canny->set(this->m_highThreshold, this->m_lowThreshold);
00081 
00082     phTHIS_LOOSE_UNLOCK(locked);
00083     
00084     return (phFilter *)canny;
00085 }
00086 
00087 /* ---------------------------------------------------------------------- */
00088 int canny_Filter::set( uint32_t lowThreshold,
00089                        uint32_t highThreshold )
00090 {
00091     phFUNCTION("canny_Filter::set")
00092     int locked = 0;
00093     
00094     phTHIS_LOOSE_LOCK(locked);
00095     
00096     this->m_highThreshold = highThreshold;
00097     this->m_lowThreshold = lowThreshold;
00098 
00099     phTHIS_LOOSE_UNLOCK(locked);
00100     
00101     return phSUCCESS;
00102 }
00103 
00104 /* ------------------------------------------------------------------------ */
00105 void canny_Filter::enableGaussian( int enable )
00106 { 
00107     this->m_useGaussian = (enable ? 1 : 0); 
00108 }
00109 
00110 /* ------------------------------------------------------------------------ */
00111 void canny_Filter::disableGaussian( int disable )
00112 { 
00113     this->m_useGaussian = (disable ? 0 : 1); 
00114 }
00115 
00116 /* ------------------------------------------------------------------------ */
00117 void canny_Filter::enableSobelApprox( int enable )
00118 { 
00119     this->m_useSobelApprox = (enable ? 1 : 0); 
00120 }
00121 
00122 /* ------------------------------------------------------------------------ */
00123 void canny_Filter::disableSobelApprox( int disable )
00124 { 
00125     this->m_useSobelApprox = (disable ? 0 : 1); 
00126 }
00127 
00128 /* ---------------------------------------------------------------------- */
00129 int canny_Filter::filter()
00130 {
00131     phFUNCTION("canny_Filter::filter")
00132 
00133     /* Filter variables */
00134     uint32_t    r, c = 0;
00135     uint32_t    row, col, offset = 0;
00136     uint32_t    inrow, incol = 0;
00137     uint32_t    row_length = 0;
00138     uint8_t    *addr = NULL;
00139     uint8_t    *toaddr = NULL;
00140     uint8_t    *fromaddr = NULL;
00141     double      Y = 0.0;
00142     int         I, J = 0;
00143     int         sumX = 0;
00144     int         sumY = 0;
00145     int         SUM = 0;
00146     int         leftPixel = 0;
00147     int         rightPixel = 0;
00148     int         P1, P2, P3, P4, P5, P6, P7, P8 = 0;
00149     float       ORIENT = 0.0;
00150     int         edgeDirection = 0;
00151     /* 5x5 Gaussian mask.  Ref: http://www.cee.hw.ac.uk/hipr/html/gsmooth.html */
00152     int GAUSS_MASK[5][5] = {
00153         { 2, 4, 5, 4, 2},
00154         { 4, 9,12, 9, 4},
00155         { 5,12,15,12, 5},
00156         { 4, 9,12, 9, 4},
00157         { 2, 4, 5, 4, 2}
00158     };
00159     /* 3x3 GX Sobel mask.  Ref: www.cee.hw.ac.uk/hipr/html/sobel.html */
00160     int            GX[3][3] = {
00161         {-1,0,1},
00162         {-2,0,2},
00163         {-1,0,1}
00164     };
00165     /* 3x3 GY Sobel mask.  Ref: www.cee.hw.ac.uk/hipr/html/sobel.html */
00166     int            GY[3][3] = {
00167         { 1, 2, 1},
00168         { 0, 0, 0},
00169         {-1,-2,-1}
00170     };
00171 #if TIMESTUFF()
00172     /* timing structures */
00173 #endif
00174     /* End filter variables */
00175     
00176     /* Begin Filter */
00177     phDALLOC_RESIZE(this->m_gauss,
00178                     this->m_gaussSize,
00179                     width * height * depth,
00180                     uint8_t );
00181     phDALLOC_RESIZE(this->m_edge,
00182                     this->m_edgeSize,
00183                     width * height * depth,
00184                     uint8_t );
00185 
00186     row_length = width * depth;
00187     
00188     /*
00189      * Source of code for Canny edge detector: canny.c by Bill Green
00190      *
00191      * Code altered to be faster and easier to read.
00192      * The code is also relatively generic with only 
00193      * 
00194      * 6 inputs: 
00195      *      width, 
00196      *      height, 
00197      *      depth, 
00198      *      *data, 
00199      *      high threshold,
00200      *      low threshold
00201      *
00202      * Program Steps:
00203      *  1.) 5x5 Gaussian mask for noise removal
00204      *  2.) Use Sobel masks to approximate gradient
00205      *  3.) Find orientation of gradient
00206      *  4.) Implement nonmaximum suppression to assign edges
00207      *  5.) Hysteresis thresholding (2 thresholds)
00208      */
00209    
00210     /* RGB to Grey scale */
00211     /* Common Luminance equation: Y = 0.3R + 0.59G + 0.11B */
00212     if (this->m_workspaceImage->getFormat() & (phImageRGB24 | phImageRGBA32))
00213     {
00214         uint32_t limit = height * width;
00215 #if TIMESTUFF()
00216         /* phPROGRESS("Luminance Conversion\n"); */
00217         /* time start */
00218 #endif
00219         addr = Image;
00220         for( r = 0; r < limit; r++, addr += depth )
00221         {
00222             Y = (0.3 *  (*(addr))    ) + /* R */
00223                 (0.59 * (*(addr + 1))) + /* G */
00224                 (0.11 * (*(addr + 2)));  /* B */
00225             
00226             if (Y > 255) Y = 255;
00227             phMemset((void *)addr,
00228                     (uint8_t)Y,
00229                     sizeof(uint8_t)*depth);
00230         }
00231 #if TIMESTUFF()
00232         /* time end */
00233 #endif
00234     }
00235    
00236     if (this->m_useGaussian)
00237     {
00238         /* Gaussian */
00239         uint32_t r_limit = height - 2;
00240         uint32_t c_limit = width  - 2;
00241 #if TIMESTUFF()
00242         /* phPROGRESS("Gaussian Blur\n"); */
00243         /* time start */
00244 #endif
00245         
00246         /* Start 2 rows down and 2 pixels in */
00247         toaddr = this->m_gauss + (2 * row_length) + (2 * depth);
00248             
00249         /* toaddr += 4 * depth: skip border 2 pixels on end of row 
00250          * and front of next row */
00251         for( r = 2; r < r_limit; r++, toaddr += 4 * depth )
00252         {
00253             /* toaddr += depth: goto the next pixel */
00254             for( c = 2; c < c_limit; c++, toaddr += depth )
00255             {
00256                 SUM = 0;
00257                 
00258                 fromaddr = Image + 
00259                     ((r - 2) * row_length) + 
00260                     ((c - 2) * depth);
00261 #if UNROLL_LOOP            
00262                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 0 ][ 0 ]));
00263                 fromaddr += depth;
00264                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 0 ][ 1 ]));
00265                 fromaddr += depth;
00266                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 0 ][ 2 ]));
00267                 fromaddr += depth;
00268                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 0 ][ 3 ]));
00269                 fromaddr += depth;
00270                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 0 ][ 4 ]));
00271                 fromaddr += row_length - (4 * depth);
00272                 
00273                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 1 ][ 0 ]));
00274                 fromaddr += depth;
00275                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 1 ][ 1 ]));
00276                 fromaddr += depth;
00277                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 1 ][ 2 ]));
00278                 fromaddr += depth;
00279                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 1 ][ 3 ]));
00280                 fromaddr += depth;
00281                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 1 ][ 4 ]));
00282                 fromaddr += (row_length - (4 * depth));
00283                 
00284                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 2 ][ 0 ]));
00285                 fromaddr += depth;
00286                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 2 ][ 1 ]));
00287                 fromaddr += depth;
00288                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 2 ][ 2 ]));
00289                 fromaddr += depth;
00290                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 2 ][ 3 ]));
00291                 fromaddr += depth;
00292                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 2 ][ 4 ]));
00293                 fromaddr += (row_length - (4 * depth));
00294                 
00295                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 3 ][ 0 ]));
00296                 fromaddr += depth;
00297                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 3 ][ 1 ]));
00298                 fromaddr += depth;
00299                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 3 ][ 2 ]));
00300                 fromaddr += depth;
00301                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 3 ][ 3 ]));
00302                 fromaddr += depth;
00303                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 3 ][ 4 ]));
00304                 fromaddr += (row_length - (4 * depth));
00305 
00306                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 4 ][ 0 ]));
00307                 fromaddr += depth;
00308                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 4 ][ 1 ]));
00309                 fromaddr += depth;
00310                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 4 ][ 2 ]));
00311                 fromaddr += depth;
00312                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 4 ][ 3 ]));
00313                 fromaddr += depth;
00314                 SUM += (int)((*fromaddr) * (GAUSS_MASK[ 4 ][ 4 ]));
00315 #else /* UNROLL_LOOP */     
00316                 for( I = 0; I < 5; I++ )
00317                 {
00318                     for( J = 0; J < 5; J++ )
00319                     {
00320                         SUM += (int)((*fromaddr) * (GAUSS_MASK[I][J]));
00321                         fromaddr += depth;
00322                     }
00323                     /* one row down - width of MASKing box */
00324                     fromaddr += row_length - (5 * depth);
00325                 }
00326 #endif /* UNROLL_LOOP */
00327 
00328                 SUM = SUM / 115;
00329                 if (SUM > 255)  SUM = 255;
00330                 
00331                 phMemset((void *)(toaddr), SUM,
00332                          sizeof(uint8_t)*depth);
00333             }
00334         }
00335 #if TIMESTUFF()
00336         /* time end */
00337 #endif
00338     }
00339     else
00340     {
00341         phMemcpy(this->m_gauss,
00342                 Image,
00343                 width*height*depth*sizeof(uint8_t));
00344     }
00345     
00346     
00347     if (this->m_useSobelApprox)
00348     {
00349         /* Sobel gradient appox. */
00350 #if TIMESTUFF()
00351         /* phPROGRESS("Sobel gradient approximation\n"); */
00352         /* time start */
00353 #endif
00354         for( r = 2; r < (height - 2); r++ )
00355         {
00356             row = r * row_length;
00357             for(c = 2; c < (width - 2); c++ )
00358             {
00359                 col = c * depth;
00360                 
00361                 sumX = 0;
00362                 sumY = 0;
00363                 
00364                 /* image boundaries */
00365                 if((r == 0) || (r == (height-1)))
00366                 {
00367                     SUM = 0;
00368                 }
00369                 else if ((c == 0) || (c == (width-1)))
00370                 {
00371                     SUM = 0;
00372                 }
00373                 /* Convolution starts here */
00374                 else
00375                 {
00376                     /* pthoren - I think 'J' and 'I' are being applied backwards */
00377                     /* gradient approximations */
00378                     for( I = -1; I <= 1; I++ )
00379                     {
00380                         inrow = (r + I) * row_length;
00381                         for( J = -1; J <= 1; J++ )
00382                         {
00383                             incol = (c + J) * depth;
00384                             offset = inrow + incol;
00385                             /* X gradient approximation */
00386                             sumX += (int)( (*(this->m_gauss + offset)) * GX[I+1][J+1]);
00387                             /* Y gradient approximation */
00388                             sumY += (int)( (*(this->m_gauss + offset)) * GY[I+1][J+1]);
00389                         }
00390                     }
00391                     
00392                     /* GRADIENT MAGNITUDE APPROXIMATION (Myler p.218) */
00393                     SUM = abs(sumX) + abs(sumY);
00394                     
00395                     if ( SUM > 255 )    SUM=255;
00396                     /* SUm can not be negative */
00397                     /* if ( SUM < 0 )      SUM=0; */
00398                     
00399                     /* Magnitude orientation */
00400                     /* Cannot divide by zero */
00401                     if(sumX == 0)   
00402                     {
00403                         if ( sumY == 0 )
00404                         {
00405                             ORIENT = 0.0;
00406                         }
00407                         else if (sumY<0)
00408                         {
00409                             sumY = -sumY;
00410                             ORIENT = 90.0;
00411                         }
00412                         else 
00413                         {
00414                             ORIENT = 90.0;
00415                         }
00416                     }
00417                     /* Can't take invtan of angle in 2nd Quad */
00418                     else if ((sumX < 0) && (sumY > 0))
00419                     {
00420                         sumX = -sumX;
00421                         ORIENT = 180 - ((atan((float)(sumY)/(float)(sumX))) * (float)(180/M_PI));
00422                     }
00423                     
00424                     /* Can't take invtan of angle in 4th Quad */
00425                     else if((sumX > 0) && (sumY < 0))
00426                     {
00427                         sumY = -sumY;
00428                         ORIENT = 180 - ((atan((float)(sumY)/(float)(sumX))) * (float)(180/M_PI));
00429                     }
00430                     /* else angle is in 1st or 3rd Quad */
00431                     else 
00432                     {
00433                         ORIENT = (atan((float)(sumY)/(float)(sumX))) * (float)(180/M_PI);
00434                     }
00435                     
00436                     /*-----------------------------------------------------
00437                      * Find edgeDirection by assigning ORIENT a value of
00438                      * either 0, 45, 90 or 135 degrees, depending on which
00439                      * value ORIENT is closest to
00440                      * ---------------------------------------------------*/
00441                     if (ORIENT < 22.5) 
00442                         edgeDirection = 0;
00443                     
00444                     else if (ORIENT < 67.5) 
00445                         edgeDirection = 45;
00446                     
00447                     else if (ORIENT < 112.5) 
00448                         edgeDirection = 90;
00449                     
00450                     else if (ORIENT < 157.5) 
00451                         edgeDirection = 135;
00452                     
00453                     else 
00454                         edgeDirection = 0;
00455                     
00456                     /* Obtain values of 2 adjacent pixels in edge direction. */
00457                     addr = this->m_gauss + row + col;
00458                     if(edgeDirection == 0)   
00459                     {
00460                         /* one pixel to the left */
00461                         leftPixel = (int)(*((addr - depth)));
00462                         /* one pixel to the rigby */
00463                         rightPixel = (int)(*((addr + depth)));
00464                     }
00465                     else if(edgeDirection == 45)   
00466                     {
00467                         /* one row down, one pixel to the left */
00468                         leftPixel = (int)(*((addr + row_length - depth)));
00469                         /* one row up, one pixel to the right */
00470                         rightPixel = (int)(*((addr - row_length + depth)));
00471                     }
00472                     else if(edgeDirection == 90)   
00473                     {
00474                         /* one row up */
00475                         leftPixel = (int)(*((addr - row_length)));
00476                         /* one row down */
00477                         rightPixel = (int)(*((addr + row_length)));
00478                     }
00479                     else   
00480                     {
00481                         /* One row up, one pixel to the left */
00482                         leftPixel = (int)(*((addr - row_length - depth)));
00483                         /* One row down, one pixel to the right */
00484                         rightPixel = (int)(*((addr + row_length + depth)));
00485                     }
00486                     /* -------------------------------------------------
00487                      * Compare current magnitude to both adjacent
00488                      * pixel values.  And if it is less than either
00489                      * of the 2 adjacent values - suppress it and make
00490                      * a nonedge.
00491                      * ------------------------------------------------- */
00492                     
00493                     if ((SUM < leftPixel) || (SUM < rightPixel))
00494                     {
00495                         SUM = 0;
00496                     }
00497                     else   
00498                     {
00499                         /* Hysteresis */
00500                         if ( SUM >= this->m_highThreshold )
00501                         {
00502                             SUM = 255; /* edge */
00503                         }
00504                         else if ( SUM <= this->m_lowThreshold )
00505                         {
00506                             SUM = 0;  /* nonedge */
00507                         }
00508                         /* SUM is between T1 & T2 */
00509                         else   
00510                         {
00511                             /* This is the old way to do it, as you can see
00512                              * there are a lot more calculations performed
00513                              * in the following as opposed to the newer version
00514                              * below.
00515                              */
00516                             
00517                             #if 0
00518                             addr = this->m_gauss + r * row_length;
00519                             /* Determine values of neighboring pixels */
00520                             P1 = (int)(*(addr  + ((c - width - 1) * depth)));
00521                             P2 = (int)(*(addr  + ((c - width)     * depth)));
00522                             P3 = (int)(*(addr  + ((c - width + 1) * depth)));
00523                             P4 = (int)(*(addr  + ((c - 1)         * depth)));
00524                             P5 = (int)(*(addr  + ((c + 1)         * depth)));
00525                             P6 = (int)(*(addr  + ((c + width - 1) * depth)));
00526                             P7 = (int)(*(addr  + ((c + width)     * depth)));
00527                             P8 = (int)(*(addr  + ((c + width + 1) * depth)));
00528                             #else
00529                             
00530                             /* Old way- subs:6 adds:15 muls:9
00531                              *          potential-loads: 33
00532                              *          
00533                              * New way- subs:4 adds:7 muls:3
00534                              *          potential-loads: 28
00535                              *
00536                              * += requires 2 loads, one for the target before and
00537                              * one for the operand.
00538                              *
00539                              * This could still be improved by making 'addr'
00540                              * change very little by taking it's calculation from
00541                              * here to outside the loop and incrementing it by
00542                              * depth. TODO
00543                              */
00544 
00545                             addr = (this->m_gauss + r * row_length) -  
00546                                    ((width - c - 1) * depth);
00547                             
00548                             /* 
00549                              *  + ((c - width - 1) * depth);
00550                              *
00551                              *  Using the following when adding to the address
00552                              * will not work as expected. The left-hand side will
00553                              * evaluate to a negative number and doesn't get added
00554                              * correctly to the address type. However, if you switch
00555                              * to "width - c", the value will always be positive and
00556                              * the addition is performed correctly.
00557                              */
00558 
00559                             /* [R,   C   ] *
00560                              * [0,[0,1,2]] *
00561                              * [1,[0,x,2]] *
00562                              * [2,[0,1,2]] */
00563                             
00564                             /* [0,0] first pixel of kernel */
00565                             P1 = (int)*(addr);
00566                            
00567                             /* [0,1] next column:pixel */
00568                             addr += depth;
00569                             P2 = (int)*(addr);
00570                             
00571                             /* [0,2] next column:pixel */
00572                             addr += depth;
00573                             P3 = (int)*(addr);
00574                             
00575                             /* [1,2] next row */
00576                             addr += row_length;
00577                             P5 = (int)*(addr);
00578                             
00579                             /* [1,0] first pixel of row */
00580                             addr -= 2 * depth;
00581                             P4 = (int)*(addr);
00582                             
00583                             /* [2,0] next row */
00584                             addr += row_length;
00585                             P6 = (int)*(addr);
00586 
00587                             /* [2,1] next column:pixel */
00588                             addr += depth;
00589                             P7 = (int)*(addr);
00590 
00591                             /* [2,2] next column:pixel */
00592                             addr += depth;
00593                             P8 = (int)*(addr);
00594                             #endif
00595                                 
00596                             /* Check to see if neighboring pixel values are edges */
00597                             if ((P1 > this->m_highThreshold) || 
00598                                 (P2 > this->m_highThreshold) || 
00599                                 (P3 > this->m_highThreshold) || 
00600                                 (P4 > this->m_highThreshold) ||
00601                                 (P5 > this->m_highThreshold) || 
00602                                 (P6 > this->m_highThreshold) || 
00603                                 (P7 > this->m_highThreshold) || 
00604                                 (P8 > this->m_highThreshold))
00605                             {
00606                                 SUM = 0; /* make edge */
00607                             }
00608                             else 
00609                             {
00610                                 SUM = 255; /* make nonedge */
00611                             }
00612                         }
00613                     }
00614                 } /* else loop ends here (starts after b.c.) */
00615                 
00616                 /* Set an edge for all channels of the image */
00617                 phMemset((void *)(this->m_edge + row + col),
00618                         255 - (uint8_t)(SUM),
00619                         sizeof(uint8_t) * depth);
00620             }
00621         }
00622        
00623         /* copy the edge image to the Image output */
00624         phMemcpy(Image,
00625                 this->m_edge,
00626                 width * height * depth * sizeof(uint8_t));
00627         
00628 #if TIMESTUFF()
00629         /* time end */
00630 #endif
00631     } 
00632     else        
00633     {
00634         /* If we just want to see the output of the 5x5 gaussian, just copy
00635          * the gaussian to the Image */
00636         phMemcpy(Image,
00637                  this->m_gauss,
00638                  width * height * depth * sizeof(uint8_t));
00639     }
00640     
00641     /* End Filter */
00642 
00643     return phSUCCESS;
00644 
00645 error:
00646     /* make sure to free up any space here, not including Image */
00647 
00648     return phFAIL;
00649 }
00650 




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:09 2007 for phission by  doxygen 1.4.4