Go to the documentation of this file.00001 #ifndef MEDIAN_FILTER_H
00002 #define MEDIAN_FILTER_H
00003
00004 #include "ImageToImageOperator.h"
00005 #include "PumaException.h"
00006
00007 namespace puma2 {
00008
00024 template <class T>
00025 class MedianFilter : public ImageToImageOperator<T,T> {
00026 public:
00027
00033 MedianFilter(int windowWidth, int windowHeight);
00034
00040 MedianFilter(int windowSize);
00041
00045 virtual ~MedianFilter();
00046
00050 virtual void apply(const T& iImg, T& oImg);
00051
00055 int getWindowWidth() const { return mWindowWidth; }
00056
00060 int getWindowHeight() const { return mWindowHeight; }
00061
00062 private:
00063
00069 void computeHelpers();
00070
00074 int mWindowWidth;
00075
00079 int mWindowHeight;
00080
00084 int mHalfWindowWidth;
00085
00089 int mHalfWindowHeight;
00090
00094 int mNumWindowElements;
00095
00099 typename T::ElementType* mWindowElements;
00100
00104 int mMedianIndex;
00105 };
00106
00107
00108 template <class T>
00109 MedianFilter<T>::MedianFilter(int windowSize) {
00110 if (windowSize < 1 || windowSize % 2 == 0) {
00111 std::string msg("Illegal window size for median filter (has to be odd and positive)");
00112 throw PumaException(PumaException::intolerable, msg);
00113 }
00114
00115 if (T::numberOfChannels() > 1) {
00116
00117 }
00118
00119 mWindowHeight = windowSize;
00120 mWindowWidth = windowSize;
00121 computeHelpers();
00122 }
00123
00124
00125 template <class T>
00126 MedianFilter<T>::MedianFilter(int windowWidth, int windowHeight) {
00127 if (windowWidth < 1 || windowWidth % 2 == 0) {
00128 std::string msg("Illegal window width for median filter (has to be odd and positive)");
00129 throw PumaException(PumaException::intolerable, msg);
00130 }
00131 if (windowHeight < 1 || windowHeight % 2 == 0) {
00132 std::string msg("Illegal window height for median filter (has to be odd and positive)");
00133 throw PumaException(PumaException::intolerable, msg);
00134 }
00135
00136 if (T::numberOfChannels() > 1) {
00137
00138 }
00139
00140 mWindowHeight = windowHeight;
00141 mWindowWidth = windowWidth;
00142 computeHelpers();
00143 }
00144
00145 template <class T>
00146 void MedianFilter<T>::computeHelpers() {
00147 mHalfWindowHeight = (mWindowHeight - 1) / 2;
00148 mHalfWindowWidth = (mWindowWidth - 1) / 2;
00149 mNumWindowElements = mWindowWidth * mWindowHeight;
00150 mWindowElements = new typename T::ElementType[mNumWindowElements];
00151 mMedianIndex = (mNumWindowElements - 1) / 2;
00152 }
00153
00154 template <class T>
00155 MedianFilter<T>::~MedianFilter() {
00156 delete mWindowElements;
00157 };
00158
00159
00160
00161
00162
00163
00164
00165
00166 template <class T>
00167 void MedianFilter<T>::apply(const T& iImg, T& oImg) {
00168
00169 int minX = mHalfWindowWidth;
00170 int maxX = oImg.getWidth() - mHalfWindowWidth - 1;
00171 int minY = mHalfWindowHeight;
00172 int maxY = oImg.getHeight() - mHalfWindowHeight - 1;
00173 int numChannelsM1 = T::numberOfChannels() - 1;
00174
00175 for (int y = minY; y <= maxY; y++) {
00176 for (int x = minX; x <= maxX; x++) {
00177 for (int n = 0; n <= numChannelsM1; n++) {
00178 int listIndex = 0;
00179 for (int wy = -mHalfWindowHeight; wy <= mHalfWindowHeight; wy++) {
00180 for (int wx = -mHalfWindowWidth; wx <= mHalfWindowWidth; wx++) {
00181 mWindowElements[listIndex++] = iImg.sample(x + wx, y + wy, n);
00182 }
00183 }
00184
00185 for (int k = 1; k <= mNumWindowElements - 1; k++) {
00186 for (int l = 0; l < mNumWindowElements - k; l++) {
00187 if (mWindowElements[l] > mWindowElements[l + 1]) {
00188 typename T::ElementType temp = mWindowElements[l];
00189 mWindowElements[l] = mWindowElements[l + 1];
00190 mWindowElements[l + 1] = temp;
00191 }
00192 }
00193 }
00194 oImg.sample(x, y, n) = mWindowElements[mMedianIndex];
00195 }
00196 }
00197 }
00198 }
00199
00200 }
00201
00202 #endif