// neighborhood_example.01.c
// Averaging using neighborhoods and the neighborhood reduction
//   function sum().

// We will average the image at each point over a localized set
//   of 9 points, i.e. the point in question and it\'s eight
//   neighboring points.

// We will calculate the average by:
//    1) Creating a summation image, which will have a value equal
//       to the sum of values of the points in the neighborhood.
//    2) Divide the resultant image by the size of the neighborhood.

// Note: This approach has the failing that average calculated at the
//    boundary of the image maybe too small.  This is because this
//    method does not take into account that not every point has a
//    full neighborhood.


#include "IntDI.h"
#include "UcharDI.h"
#include "Nbh.h"


int main() {

    // Read in the image from the standard input stream: cin
    IA_Image<IA_Point<int>,int>
        in_image = read_int_PGM( cin );

    // Declare the intermediate and final result images
    IA_Image<IA_Point<int>,int>
        sum_image,
        avg_image;

    // Define the point set of the 9 points centered at <0,0>
    IA_Set<IA_Point<int> >
        nbhd_ps = IA_boxy_pset( IA_Point<int>(-1,-1),
                                IA_Point<int>( 1, 1) );

    // Now create the neighborhood based on the point set just defined.
    IA_Neighborhood<IA_Point<int>,IA_Point<int> >
        nbhd( 2,          // The dimension of the pointset
              nbhd_ps );  // This is similar to a template\'s image

    // Now we will create the summation image
    sum_image = sum( in_image,
                     nbhd,
                     in_image.domain()  // Resultant image domain
                     );


    // Finally calculate the image by simple division
    avg_image = sum_image/( nbhd_ps.card() );


    // Write the result to the standard output stream
    avg_image.write_PGM( cout );

    return 0;
}
