#include <stdlib.h> #include <stdio.h> #include "basicImage.c" /* Puzzle43.c -- Smooth 3x3 with Edge Handling | | This is the easy solution that uses lots of statements | for all the special cases of edges and corners. | */ #include#include #include "../basicImage.c" void smoothImage( image img, image smooth ) { int r, c, sum; unsigned char value ; /* Upper Left corner */ r=0; c=0; sum = getPixel( img, r , c ); sum += getPixel( img, r , c+1 ); sum += getPixel( img, r+1, c ); sum += getPixel( img, r+1, c+1 ); setPixel( smooth, r, c, sum/4 ); /* Upper Right corner */ r=0; c=img.ncols-1; sum = getPixel( img, r , c-1 ); sum += getPixel( img, r , c ); sum += getPixel( img, r+1, c-1 ); sum += getPixel( img, r+1, c ); setPixel( smooth, r, c, sum/4 ); /* Lower Left corner */ r=img.nrows-1; c=0; sum = getPixel( img, r-1, c ); sum += getPixel( img, r-1, c+1 ); sum += getPixel( img, r , c ); sum += getPixel( img, r , c+1 ); setPixel( smooth, r, c, sum/4 ); /* Lower Right corner */ r=img.nrows-1; c=img.ncols-1; sum = getPixel( img, r-1, c-1 ); sum += getPixel( img, r-1, c ); sum += getPixel( img, r , c-1 ); sum += getPixel( img, r , c ); setPixel( smooth, r, c, sum/4 ); /* Deal with top and bottom edges */ for ( c=1; c<img.ncols-1; c++ ) { r=0; sum = getPixel( img, r , c-1 ); sum += getPixel( img, r , c ); sum += getPixel( img, r , c+1 ); sum += getPixel( img, r+1, c-1 ); sum += getPixel( img, r+1, c ); sum += getPixel( img, r+1, c+1 ); setPixel( smooth, r, c, sum/6 ); r=img.nrows-1; sum = getPixel( img, r-1, c-1 ); sum += getPixel( img, r-1, c ); sum += getPixel( img, r-1, c+1 ); sum += getPixel( img, r , c-1 ); sum += getPixel( img, r , c ); sum += getPixel( img, r , c+1 ); setPixel( smooth, r, c, sum/6 ); } /* Deal with left and right edges */ for ( r=1; r<img.nrows-1; r++ ) { c=0; sum = getPixel( img, r-1, c ); sum += getPixel( img, r-1, c+1 ); sum += getPixel( img, r , c ); sum += getPixel( img, r , c+1 ); sum += getPixel( img, r+1, c ); sum += getPixel( img, r+1, c+1 ); setPixel( smooth, r, c, sum/6 ); c=img.ncols-1; sum = getPixel( img, r-1, c-1 ); sum += getPixel( img, r-1, c ); sum += getPixel( img, r , c-1 ); sum += getPixel( img, r , c ); sum += getPixel( img, r+1, c-1 ); sum += getPixel( img, r+1, c ); setPixel( smooth, r, c, sum/6 ); } /* Fill in the center with neighborhood averages */ for ( r=1; r<img.nrows-1; r++ ) for ( c=1; c<img.ncols-1; c++ ) { sum = getPixel( img, r-1, c-1 ); sum += getPixel( img, r-1, c ); sum += getPixel( img, r-1, c+1 ); sum += getPixel( img, r , c-1 ); sum += getPixel( img, r , c ); sum += getPixel( img, r , c+1 ); sum += getPixel( img, r+1, c-1 ); sum += getPixel( img, r+1, c ); sum += getPixel( img, r+1, c+1 ); setPixel( smooth, r, c, sum/9 ); } } int main ( int argc, char* argv[] ) { image img, smimg; if ( argc != 3 ) { printf( "smoothE 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 */ smoothImage( img, smimg ); /* write the image to disk and free memory */ writePGMimage( smimg, argv[2] ); freeImage( &img ); freeImage( &smimg ); }
Comments: The hard solution might actually be easier. It certainly is shorter:
void smoothImage( image img, image smooth ) { int r, ri, c, ci, sum, count; unsigned char value ; /* Find all neighborhood averages */ for ( r=0; r<img.nrows; r++ ) for ( c=0; c<img.ncols; c++ ) { sum = 0; count = 0; for ( ri= -1; ri<=1; ri++ ) if ( r+ri >=0 && r+ri < img.nrows ) for ( ci= -1; ci<=1; ci++ ) if ( c+ci >=0 && c+ci < img.ncols ) { sum += getPixel( img, r+ri, c+ci ); count++ ; } setPixel( smooth, r, c, sum/count ); } }