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   /** Constructor */
00032   FastSUSANNoiseReduction(int smoothingThreshold);
00033 
00034   /** Destructor */
00035   ~FastSUSANNoiseReduction();
00036 
00037   /** 
00038   * Filters a chosen pixel of an image.
00039   * IMPORTANT NOTE: since it's a filter which makes use of a convolution kernel of size 3x3, 
00040   * always make sure that you don't access the 1 pixel wide border of the image,
00041   * (so it should always be x>0, x<width-1, y>0, y<width-1)
00042   * otherwise you'll be accessing memory out of the allocated space, with obvious consequences.
00043   * @param source the source image to be filtered
00044   * @param posX the x coordinate of the chosen pixel
00045   * @param posY the y coordinate of the chosen pixel
00046   * @param valA the first spectrum (ex. Y (luminance)) of the filtered pixel, returned
00047   * @param valB the second spectrum (ex. U (crominance)) of the filtered pixel, returned
00048   * @param valC the third spectrum (ex. V (crominance)) of the filtered pixel, returned
00049   */
00050   inline void getFilteredPixel(const Image& source, int posX, int posY, unsigned char& valA, unsigned char& valB, unsigned char& valC) const
00051   {
00052     valA = getFilteredPixelSpectrum(source, posX, posY, 0);
00053     valB = getFilteredPixelSpectrum(source, posX, posY, 1);
00054     valC = getFilteredPixelSpectrum(source, posX, posY, 2);
00055   }
00056 
00057   /** 
00058   * Filters a chosen pixel of an image, directly modifying it.
00059   * IMPORTANT NOTE: since it's a filter which makes use of a convolution kernel of size 3x3, 
00060   * always make sure that you don't access the 1 pixel wide border of the image,
00061   * (so it should always be x>0, x<width-1, y>0, y<width-1)
00062   * otherwise you'll be accessing memory out of the allocated space, with obvious consequences.
00063   * @param source the source image to be filtered
00064   * @param posX the x coordinate of the chosen pixel
00065   * @param posY the y coordinate of the chosen pixel
00066   */
00067   inline void filterPixel(Image& source, int posX, int posY) const
00068   {
00069     source.image[posY][0][posX] = getFilteredPixelSpectrum(source, posX, posY, 0);
00070     source.image[posY][1][posX] = getFilteredPixelSpectrum(source, posX, posY, 1);
00071     source.image[posY][2][posX] = getFilteredPixelSpectrum(source, posX, posY, 2);
00072   }
00073 
00074   /** 
00075   * Filters a whole image.
00076   * IMPORTANT NOTE: since it's a filter which makes use of a convolution kernel of size 3x3, 
00077   * always make sure that you don't access the 1 pixel wide border of the image,
00078   * (so it should always be x>0, x<width-1, y>0, y<width-1)
00079   * otherwise you'll be accessing memory out of the allocated space, with obvious consequences.
00080   * @param source the source image to be filtered
00081   * @param destination the resulting image
00082   */
00083   void getFilteredImage(const Image& source, Image& destination) const;
00084   
00085 private:
00086 
00087   /**
00088   * A LookUpTable containing a correlation function, in this implementation it's a "rect" for efficiency reasons
00089   */
00090   char Susan_LUT[127];
00091 
00092   /**
00093   * Initializes the LookUpTable
00094   */
00095   void setupSusanLUT(int threshold);
00096 
00097   /**
00098   * The correlation function, precomputed
00099   */
00100   inline char correlation(int delta) const
00101   {
00102     return Susan_LUT[(delta>>2)+63];
00103   }
00104 
00105   /** 
00106   * Filters a single spectrum (ex. Y or U or V) of a chosen pixel of an image.
00107   * IMPORTANT NOTE: since it's a filter which makes use of a convolution kernel of size 3x3, 
00108   * always make sure that you don't access the 1 pixel wide border of the image,
00109   * (so it should always be x>0, x<width-1, y>0, y<width-1)
00110   * otherwise you'll be accessing memory out of the allocated space, with obvious consequences.
00111   * @param image the source image to be filtered
00112   * @param posx the x coordinate of the chosen pixel
00113   * @param posy the y coordinate of the chosen pixel
00114   * @param spectrum the chosen image spectrum
00115   * @return the filtered value
00116   */
00117   inline unsigned char getFilteredPixelSpectrum(const Image& image, int posx, int posy, int spectrum) const
00118   {
00119     register unsigned int USAN;
00120     register int counter;
00121     register unsigned char center;
00122     register int tempCorrelation;
00123     register unsigned char neighbours0;
00124     register unsigned char neighbours1;
00125     register unsigned char neighbours2;
00126     register unsigned char neighbours3;
00127     
00128     unsigned char resp; 
00129     int sp = static_cast<int> (spectrum);
00130     
00131     center = image.image[posy][sp][posx];          
00132     neighbours0 = image.image[posy-1][sp][posx];          
00133     neighbours1 = image.image[posy+1][sp][posx];          
00134     neighbours2 = image.image[posy][sp][posx-1];          
00135     neighbours3 = image.image[posy][sp][posx+1];          
00136     
00137     tempCorrelation = correlation(neighbours0-center);
00138     USAN = neighbours0 & tempCorrelation;
00139     counter = tempCorrelation;
00140     tempCorrelation = correlation(neighbours1-center);
00141     USAN += neighbours1 & tempCorrelation;
00142     counter += tempCorrelation;
00143     tempCorrelation = correlation(neighbours2-center);
00144     USAN += neighbours2 & tempCorrelation;
00145     counter += tempCorrelation;
00146     tempCorrelation = correlation(neighbours3-center);
00147     USAN += neighbours3 & tempCorrelation;
00148     counter += tempCorrelation;
00149     
00150     if (counter == -4) { // most likely situation, typically above 85% for smoothin threshold >= 8 (which usually is the case) 
00151       resp = (unsigned char) (USAN>>2);
00152     }
00153     else 
00154     if (counter == -3) {// second most likely situation 
00155       USAN += center;
00156       resp = (unsigned char) (USAN>>2);
00157     }
00158     else 
00159     if (counter == -2) {
00160       resp = (unsigned char) (USAN>>1);
00161     }
00162     else 
00163     if (counter == -1) {
00164       USAN += center;
00165       resp = (unsigned char) (USAN>>1);
00166     }
00167     else 
00168     { // counter == 0
00169       unsigned char swap;
00170       if (neighbours0>neighbours1){
00171         swap = neighbours1;
00172         neighbours1 = neighbours0;
00173         neighbours0 = swap;
00174       }
00175       if (neighbours2>neighbours3){
00176         swap = neighbours3;
00177         neighbours3 = neighbours2;
00178         neighbours2 = swap;
00179       }
00180       if (neighbours2>neighbours0){
00181         neighbours0 = neighbours2;
00182       }
00183       if (neighbours3<neighbours1){
00184         neighbours1 = neighbours3;
00185       }
00186       USAN = neighbours0 + neighbours1;
00187       resp = (unsigned char) (USAN>>1);
00188     }
00189     return resp;
00190   }
00191 
00192 };
00193 
00194 #endif   //  _FastSUSANNoiseReduction_h_
00195 
00196 /*
00197 * Change log :
00198 * 
00199 * $Log: FastSUSANNoiseReduction.h,v $
00200 * Revision 1.3  2004/09/03 08:55:40  nistico
00201 * Cleaned
00202 *
00203 * Revision 1.2  2004/08/31 09:12:38  nistico
00204 * Documentation error fixed
00205 *
00206 * Revision 1.1.1.1  2004/05/22 17:19:48  cvsadm
00207 * created new repository GT2004_WM
00208 *
00209 * Revision 1.3  2004/04/08 15:33:06  wachter
00210 * GT04 checkin of Microsoft-Hellounds
00211 *
00212 * Revision 1.2  2004/03/19 11:04:58  nistico
00213 * Some corrections and restructuring
00214 *
00215 * Revision 1.1  2004/01/23 17:07:33  nistico
00216 * Added FastSUSANNoiseReduction.*, a non-linear image noise reduction filter, to ImageProcessorTools
00217 * Added debug visualization of segmented image in ColorTable32KImageProcessor, and experimental support of FastSUSANNoiseReduction
00218 *
00219 *
00220 */

Generated on Thu Sep 23 19:57:29 2004 for GT2004 by doxygen 1.3.6