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

Modules/ImageProcessor/ImageProcessorTools/FastSUSANNoiseReduction.h

Go to the documentation of this file.
00001 
00002 /** 
00003 * @file FastSUSANNoiseReduction.h
00004 * Declaration of file FastSUSANNoiseReduction.
00005 *
00006 * @author <A href=mailto:walter.nistico@uni-dortmund.de>Walter Nistico</A>
00007 */
00008 
00009 #ifndef _FastSUSANNoiseReduction_h_
00010 #define _FastSUSANNoiseReduction_h_
00011 
00012 #include "Representations/Perception/Image.h"
00013 
00014 /**
00015 * @class FastSUSANNoiseReduction
00016 *
00017 * This class represents a non-linear image noise-reduction filter.
00018 * The main feature of S.U.S.A.N. filters is their capability to smooth out the noise while preserving image structures
00019 * like lines, edges, borders, and so on, hence if the smoothing threshold is set correctly, the resulting image tipically exhibits no blur.
00020 * This implementation has been significantly modified from the original SUSAN algorithm, in order to reach a vastly reduced
00021 * computational cost making it suitable for real-time processing, so strictly speaking, this is NOT a SUSAN filter, yet it shares the same basic idea.
00022 *
00023 * @author <A href=mailto:walter.nistico@uni-dortmund.de>Walter Nistico</A>
00024 */
00025 
00026 class FastSUSANNoiseReduction 
00027 {
00028 
00029 public:
00030 
00031   //~ enum ColorSpectra {componentA=0, componentB, componentC};
00032   
00033   /** Constructor */
00034   FastSUSANNoiseReduction(int smoothingThreshold);
00035 
00036   /** Destructor */
00037   ~FastSUSANNoiseReduction();
00038 
00039   /** 
00040   * Filters a chosen pixel of an image.
00041   * IMPORTANT NOTE: since it's a filter which makes use of a convolution kernel of size 3x3, 
00042   * always make sure that you don't access the 1 pixel wide beavel of the image,
00043   * (so it should always be x>0, x<width-1, y>0, y<width-1)
00044   * otherwise you'll be accessing memory out of the allocated space, with obvious consequences.
00045   * @param source the source image to be filtered
00046   * @param posX the x coordinate of the chosen pixel
00047   * @param posY the y coordinate of the chosen pixel
00048   * @param valA the first spectrum (ex. Y (luminance)) of the filtered pixel, returned
00049   * @param valB the second spectrum (ex. U (crominance)) of the filtered pixel, returned
00050   * @param valC the third spectrum (ex. V (crominance)) of the filtered pixel, returned
00051   */
00052   inline void getFilteredPixel(const Image& source, int posX, int posY, unsigned char& valA, unsigned char& valB, unsigned char& valC) const
00053   {
00054     valA = getFilteredPixelSpectrum(source, posX, posY, 0);
00055     valB = getFilteredPixelSpectrum(source, posX, posY, 1);
00056     valC = getFilteredPixelSpectrum(source, posX, posY, 2);
00057   }
00058 
00059   /** 
00060   * Filters a chosen pixel of an image, directly modifying it.
00061   * IMPORTANT NOTE: since it's a filter which makes use of a convolution kernel of size 3x3, 
00062   * always make sure that you don't access the 1 pixel wide beavel of the image,
00063   * (so it should always be x>0, x<width-1, y>0, y<width-1)
00064   * otherwise you'll be accessing memory out of the allocated space, with obvious consequences.
00065   * @param source the source image to be filtered
00066   * @param posX the x coordinate of the chosen pixel
00067   * @param posY the y coordinate of the chosen pixel
00068   */
00069   inline void filterPixel(Image& source, int posX, int posY) const
00070   {
00071     source.image[posY][0][posX] = getFilteredPixelSpectrum(source, posX, posY, 0);
00072     source.image[posY][1][posX] = getFilteredPixelSpectrum(source, posX, posY, 1);
00073     source.image[posY][2][posX] = getFilteredPixelSpectrum(source, posX, posY, 2);
00074   }
00075 
00076   /** 
00077   * Filters a whole image.
00078   * IMPORTANT NOTE: since it's a filter which makes use of a convolution kernel of size 3x3, 
00079   * always make sure that you don't access the 1 pixel wide beavel of the image,
00080   * (so it should always be x>0, x<width-1, y>0, y<width-1)
00081   * otherwise you'll be accessing memory out of the allocated space, with obvious consequences.
00082   * @param source the source image to be filtered
00083   * @param destination the resulting image
00084   */
00085   void getFilteredImage(const Image& source, Image& destination) const;
00086   
00087 private:
00088 
00089   /**
00090   * A LookUpTable containing a correlation function, in this implementation it's a "rect" for efficiency reasons
00091   */
00092   char Susan_LUT[127];
00093 
00094   /**
00095   * Initializes the LookUpTable
00096   */
00097   void setupSusanLUT(int threshold);
00098 
00099   /**
00100   * The correlation function, precomputed
00101   */
00102   inline char correlation(int delta) const
00103   {
00104     return Susan_LUT[(delta>>2)+63];
00105   }
00106 
00107   /** 
00108   * Filters a single spectrum (ex. Y or U or V) of a chosen pixel of an image.
00109   * IMPORTANT NOTE: since it's a filter which makes use of a convolution kernel of size 3x3, 
00110   * always make sure that you don't access the 1 pixel wide beavel of the image,
00111   * (so it should always be x>0, x<width-1, y>0, y<width-1)
00112   * otherwise you'll be accessing memory out of the allocated space, with obvious consequences.
00113   * @param image the source image to be filtered
00114   * @param posx the x coordinate of the chosen pixel
00115   * @param posy the y coordinate of the chosen pixel
00116   * @param spectrum the chosen image spectrum
00117   * @return the filtered value
00118   */
00119   inline unsigned char getFilteredPixelSpectrum(const Image& image, int posx, int posy, int spectrum) const
00120   {
00121     register unsigned int USAN;
00122     register int counter;
00123     register unsigned char center;
00124     register int tempCorrelation;
00125     register unsigned char neighbours0;
00126     register unsigned char neighbours1;
00127     register unsigned char neighbours2;
00128     register unsigned char neighbours3;
00129     
00130     unsigned char resp; 
00131     int sp = static_cast<int> (spectrum);
00132     
00133     center = image.image[posy][sp][posx];          
00134     neighbours0 = image.image[posy-1][sp][posx];          
00135     neighbours1 = image.image[posy+1][sp][posx];          
00136     neighbours2 = image.image[posy][sp][posx-1];          
00137     neighbours3 = image.image[posy][sp][posx+1];          
00138     
00139     tempCorrelation = correlation(neighbours0-center);
00140     USAN = neighbours0 & tempCorrelation;
00141     counter = tempCorrelation;
00142     tempCorrelation = correlation(neighbours1-center);
00143     USAN += neighbours1 & tempCorrelation;
00144     counter += tempCorrelation;
00145     tempCorrelation = correlation(neighbours2-center);
00146     USAN += neighbours2 & tempCorrelation;
00147     counter += tempCorrelation;
00148     tempCorrelation = correlation(neighbours3-center);
00149     USAN += neighbours3 & tempCorrelation;
00150     counter += tempCorrelation;
00151     
00152     if (counter == -4) { // most likely situation, typically above 85% for smoothin threshold >= 8 (which usually is the case) 
00153       resp = (unsigned char) (USAN>>2);
00154     }
00155     else 
00156     if (counter == -3) {// second most likely situation 
00157       USAN += center;
00158       resp = (unsigned char) (USAN>>2);
00159     }
00160     else 
00161     if (counter == -2) {
00162       resp = (unsigned char) (USAN>>1);
00163     }
00164     else 
00165     if (counter == -1) {
00166       USAN += center;
00167       resp = (unsigned char) (USAN>>1);
00168     }
00169     else 
00170     { // counter == 0
00171       unsigned char swap;
00172       if (neighbours0>neighbours1){
00173         swap = neighbours1;
00174         neighbours1 = neighbours0;
00175         neighbours0 = swap;
00176       }
00177       if (neighbours2>neighbours3){
00178         swap = neighbours3;
00179         neighbours3 = neighbours2;
00180         neighbours2 = swap;
00181       }
00182       if (neighbours2>neighbours0){
00183         neighbours0 = neighbours2;
00184       }
00185       if (neighbours3<neighbours1){
00186         neighbours1 = neighbours3;
00187       }
00188       USAN = neighbours0 + neighbours1;
00189       resp = (unsigned char) (USAN>>1);
00190     }
00191     return resp;
00192   }
00193 
00194 };
00195 
00196 #endif   //  _FastSUSANNoiseReduction_h_

Generated on Mon Mar 20 21:59:49 2006 for GT2005 by doxygen 1.3.6