/********************************************************** * spatialFilter.cpp - perform spatial-domain filtering * * Lowpass: * - average: the average filter * - median: the median filter * - contrah: the contraharmonic filter * - gmean: geometric mean * - amedian: adaptive median * * Highpass: * - prewitt: 1st derivative * - roberts: 1st derivative * - sobel: 1st derivative * - laplacian: 2nd derivative * - zeroCrossing * * Author: Hairong Qi (C) hqi@utk.edu * * Created: 01/24/06 * * Modified: * - 02/12/06: modified laplacian() such that abs(img) is * returned instead of img **********************************************************/ #include "Image.h" #include "Dip.h" #include #include #include using namespace std; /** * Average lowpass filter. * @param inimg The input image. * @param size The size of the neighborhood. * @return The smoothed image using average filter. */ Image average(Image &inimg, int size) { Image outimg, mask; // create the average mask mask.createImage(size, size); mask.initImage(1); mask = mask / (size * size); // apply kernel operation outimg = conv(inimg, mask); return outimg; } /** * Gaussian lowpass filter. Kernel = [1 2 1; 2 4 2; 1 2 1]/16; * @param inimg The input image * @return The smoothed image. */ Image gaussianSmooth(Image &inimg) { Image outimg, mask; // create the two masks and initialize to zero mask.createImage(3,3); mask(0,0) = mask(0,2) = mask(2,0) = mask(2,2) = 1; mask(0,1) = mask(1,0) = mask(1,2) = mask(2,1) = 2; mask(1,1) = 4; mask = mask / 16.0; // apply kernel operation outimg = conv(inimg, mask); return outimg; } /** * Median filter * @param inimg The input image * @param masksize The size (or radius) of the neighborhood * @return Image smoothed by median filter */ Image median(Image &inimg, int masksize) { Image outimg; int nr, nc, nchan, radius1, radius2; int i, j, m, n, l; float *p; nr = inimg.getRow(); nc = inimg.getCol(); nchan = inimg.getChannel(); if (nchan > 1) { cout << "Median: Can only handle gray-scale images.\n"; exit(3); } outimg.createImage(nr, nc); // handle odd and even mask size if ((float)masksize/2.0 > masksize/2) { radius1 = radius2 = masksize/2; } else { radius1 = masksize/2; radius2 = radius1 - 1; } p = (float *) new float [masksize*masksize]; for (i=radius1; i 1) { cout << "amedian: Can only handle gray-scale images.\n"; exit(3); } outimg.createImage(nr, nc); flag = 1; for (i=0; i masksize/2) { radius1 = radius2 = masksize/2; } else { radius1 = masksize/2; radius2 = radius1 - 1; } // calculate neighborhood size nsize = 0; for (m=-radius1; m<=radius2; m++) for (n=-radius1; n<=radius2; n++) if (i+m>=0 && j+n>=0 && i+m=0 && j+n>=0 && i+m0 && zmed-zmax<0) { // the medium is not impulse // stage B if (zxy-zmin>0 && zxy-zmax<0) { // the current pixel is not impulse outimg(i,j) = zxy; flag = 0; } else { outimg(i,j) = zmed; flag = 0; } } else { masksize++; delete p; } } if (flag) outimg(i,j) = zmed; } return outimg; } /** * Contraharmonic mean filter. Well suited for eliminating sap noise. * @param inimg The input image. * @param Q The order of the filter * when Q=0, it becomes arithmetic mean filter * when Q=-1, it becomes harmonic mean filter * when Q is positive, it erases pepper noise * when Q is negative, it erases salt noise. * @param masksize The size of the neighborhood. * @return Restored image. */ Image contrah(Image &inimg, float Q, int masksize) { Image outimg; int i, j, m, n; int nc, nr, nchan; float sumn, sumd; // get the dimension nc = inimg.getCol(); nr = inimg.getRow(); nchan = inimg.getChannel(); if (nchan > 1) { cout << "ContraH: Can only handle gray-scale images.\n"; exit(3); } outimg.createImage(nr, nc); // apply the contraharmonic filter for (i=0; i=0 && i+m=0 && j+n=0 && masksize+m=0 && masksize+n 1) { cout << "gmean: Can only handle gray-scale images.\n"; exit(3); } outimg.createImage(nr, nc); for (i=size/2; i