I50 Answer ― Median Filter


#include <stdlib.h>
#include <stdio.h>
#include "basicImage.c"

int selectionSort( int arr[], int size )
{
  int pass, j;
  int min, minj;

  /* Each pass finds the correct value to put in arr[pass] */
  for ( pass=0; pass<size-1; pass++ )
  {
    /* find the smallest remaining element in */
    /* arr[pass]... arr[size-1] */
    minj = pass;
    min  = arr[minj];
    for ( j=pass+1; j<size; j++ )
    {
      if ( arr[j] < min )
      {
        min = arr[j];
        minj = j;
      }
    }

    /* swap the smallest remaining element */
    /* with the element in arr[pass] */
    arr[minj] = arr[pass];
    arr[pass] = min;
  }
}

void pickMedian( image img, image smooth )
{
  int pix[9];
  int j, r, ri, c, ci, min, best;
  unsigned char value ;

  /* Copy edge pixels from input image to output image */
  for ( r=0; r<img.nrows; r++ )
  {
    value = getPixel( img, r, 0 ) ;
    setPixel( smooth, r, 0, value );
    value = getPixel( img, r, img.ncols-1 ) ;
    setPixel( smooth, r, img.ncols-1 , value );
  }

  for ( c=0; c<img.ncols; c++ )
  {
    value = getPixel( img, 0, c ) ;
    setPixel( smooth, 0, c, value );
    value = getPixel( img, img.nrows-1, c ) ;
    setPixel( smooth, img.nrows-1, c, value );
  }

  /* Look at each neighborhood */
  for ( r=1; r<img.nrows-1; r++ )
    for ( c=1; c<img.ncols-1; c++ )
    {
      /* Fill in the array with neighborhood values */
      j = 0;
      for ( ri= -1; ri <= 1; ri++ )
        for ( ci= -1; ci <= 1; ci++ )
          pix[j++]  = getPixel( img, r+ri, c+ci );

      /* Sort the array */
      selectionSort( pix, 9 );

      /* Output the median value */
      setPixel( smooth, r, c, pix[5] );
    }
}

int main ( int argc, char* argv[] )
{
  image img, smimg;
  
  if ( argc != 3 )
  {
    printf( "medianFilter oldImage smoothImage\n" );
    system( "pause" );
    exit( EXIT_FAILURE );
  }
  
  /* read in the image */
  readPGMimage( &img, argv[1] );

  /* create a blank image */
  newImage( &smimg, img.nrows, img.ncols );

  /* fill in values for the new image */
  pickMedian( img, smimg );
  
  /* write the image to disk and free memory */
  writePGMimage( smimg, argv[2] );
  freeImage( &img );
  freeImage( &smimg );
}


Comments: