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 */