
       /***********************************************
       *
       *       Functions: This file contains
       *          homogeneity
       *          difference_edge
       *          contrast_edge
       *
       *       Purpose:
       *          These functions implement several
       *          types of advanced edge detection.
       *
       *       External Calls:
       *          wtiff.c - does_not_exist
       *                    round_off_image_size
       *                    create_allocate_tiff_file
       *                    write_array_into_tiff_image
       *          tiff.c - read_tiff_header
       *          rtiff.c - read_tiff_image
       *          numcvrt.c - get_integer
       *          edge.c - fix_edges
       *
       *       Modifications:
       *          26 March 1991 - created
       *
       *************************************************/



#include "d:\cips\cips.h"



short e_mask[3][3] = {
       {-9,  0, -9},
       { 0, 36,  0},
       {-9,  0, -9} };

short contrast[3][3] = {
   {  1,  1,  1},
   {  1,  1,  1},
   {  1,  1,  1}};


   /**************************************************
   *
   *   homogeneity(...
   *
   *   This function performs edge detection by looking
   *   for the absence of an edge.  The center of a
   *   3x3 area is replaced by the absolute value of
   *   the max difference between the center point
   *   and its 8 neighbors.
   *
   ***************************************************/


homogeneity(in_name, out_name, the_image, out_image,
             il, ie, ll, le, threshold, high)

   char   in_name[], out_name[];
   int    high, il, ie, ll, le, threshold;
   short  the_image[ROWS][COLS], out_image[ROWS][COLS];
{
   int a, b, absdiff, absmax, diff, i, j,
       length, max, max_diff, new_hi, new_low, width;

   struct tiff_header_struct image_header;

   if(does_not_exist(out_name)){
      printf("\n\nHOMO> output file does not exist %s",
             out_name);
      read_tiff_header(in_name, &image_header);
      round_off_image_size(&image_header,
                           &length, &width);
      image_header.image_length = length*ROWS;
      image_header.image_width  = width*COLS;
      create_allocate_tiff_file(out_name, &image_header,
                                out_image);
   }  /* ends if does_not_exist */

   read_tiff_header(in_name, &image_header);

   new_hi  = 250;
   new_low = 16;
   if(image_header.bits_per_pixel == 4){
       new_hi  = 10;
       new_low = 3;
   }

   max = 255;
   if(image_header.bits_per_pixel == 4)
      max = 16;
   read_tiff_image(in_name, the_image, il, ie, ll, le);

   for(i=0; i<ROWS; i++)
      if( (i%10) == 0) printf("%3d", i);
      for(j=0; j<COLS; j++)
         out_image[i][j] = 0;

   for(i=1; i<ROWS-1; i++){
      for(j=1; j<COLS-1; j++){

          max_diff = 0;
          for(a=-1; a<=1; a++){
             for(b=-1; b<=1; b++){

                <%-2>diff = the_image[i][j] - the_image[i+a][j+b];
<%0>                absdiff = abs(diff);
                if(absdiff > max_diff) max_diff = absdiff;

             }  /* ends loop over b */
          }  /* ends loop over a */

          out_image[i][j] = max_diff;
      }  /* ends loop over j */
   }  /* ends loop over i */


     /* if desired, threshold the output image */

   if(threshold == 1){
       for(i=0; i<ROWS; i++){
          for(j=0; j<COLS; j++){
             if(out_image[i][j] > high){
                  out_image[i][j] = new_hi;
             }
             else{
                  out_image[i][j] = new_low;
             }
          }
       }
   }  /* ends if threshold == 1 */

   fix_edges(out_image, 1);

   write_array_into_tiff_image(out_name, out_image,
                               il, ie, ll, le);

} /* ends homogeneity */

   /**************************************************
   *
   *   difference_edge(...
   *
   *   This function performs edge detection by looking
   *   at the differences in the pixels that surround
   *   the center point of a 3x3 area.  It replaces the
   *   center point with the absolute value of the
   *   max difference of:
   *      upper left - lower right
   *      upper right - lower left
   *      left - right
   *      top - bottom
   *
   ***************************************************/

difference_edge(in_name, out_name, the_image, out_image,
                il, ie, ll, le, threshold, high)
   char   in_name[], out_name[];
   int    high, il, ie, ll, le, threshold;
   short  the_image[ROWS][COLS], out_image[ROWS][COLS];
{
   int a, b, absdiff, absmax, diff, i, j,
       length, max, max_diff, new_hi, new_low, width;

   struct tiff_header_struct image_header;


   if(does_not_exist(out_name)){
      printf("\n\nDIFF> output file does not exist %s",
             out_name);
      read_tiff_header(in_name, &image_header);

      round_off_image_size(&image_header,
                           &length, &width);
      image_header.image_length = length*ROWS;
      image_header.image_width  = width*COLS;
      create_allocate_tiff_file(out_name, &image_header,
                                out_image);
   }  /* ends if does_not_exist */

   read_tiff_header(in_name, &image_header);

   new_hi  = 250;
   new_low = 16;
   if(image_header.bits_per_pixel == 4){
       new_hi  = 10;
       new_low = 3;
   }

   max = 255;
   if(image_header.bits_per_pixel == 4)
      max = 16;

   read_tiff_image(in_name, the_image, il, ie, ll, le);

   for(i=0; i<ROWS; i++)
      for(j=0; j<COLS; j++)
         out_image[i][j] = 0;

   for(i=1; i<ROWS-1; i++){
      if( (i%10) == 0) printf("%3d", i);
      for(j=1; j<COLS-1; j++){

          max_diff = 0;
          absdiff = abs(the_image[i-1][j-1] -
                         the_image[i+1][j+1]);
          if(absdiff > max_diff) max_diff = absdiff;

          absdiff = abs(the_image[i-1][j+1] -
                         the_image[i+1][j-1]);
          if(absdiff > max_diff) max_diff = absdiff;

          absdiff = abs(the_image[i][j-1] -
                         the_image[i][j+1]);
          if(absdiff > max_diff) max_diff = absdiff;

          absdiff = abs(the_image[i-1][j] -
                         the_image[i+1][j]);
          if(absdiff > max_diff) max_diff = absdiff;


          out_image[i][j] = max_diff;

      }  /* ends loop over j */
   }  /* ends loop over i */

     /* if desired, threshold the output image */
   if(threshold == 1){
       for(i=0; i<ROWS; i++){
          for(j=0; j<COLS; j++){

             if(out_image[i][j] > high){
                  out_image[i][j] = new_hi;
             }
             else{
                  out_image[i][j] = new_low;
             }
          }
       }
   }  /* ends if threshold == 1 */



   fix_edges(out_image, 1);
   write_array_into_tiff_image(out_name, out_image,
                               il, ie, ll, le);


} /* ends difference_edge */



   /**************************************************
   *
   *   contrast_edge(...
   *
   *   The edge detector uses the basic quick edge
   *   detector mask and then divides the result
   *   by a contrast smooth mask.  This implements
   *   Johnson's contrast based edge detector.
   *
   ***************************************************/

contrast_edge(in_name, out_name, the_image, out_image,
                il, ie, ll, le, threshold, high)
   char   in_name[], out_name[];
   int    high, il, ie, ll, le, threshold;
   short  the_image[ROWS][COLS], out_image[ROWS][COLS];
{
   int ad, d;
   int a, b, absdiff, absmax, diff, i, j,
       length, max, new_hi, new_low, sum_d, sum_n, width;

   struct tiff_header_struct image_header;


   if(does_not_exist(out_name)){
      printf("\n\nCONTRAST> output file does not exist %s",
             out_name);
      read_tiff_header(in_name, &image_header);
      round_off_image_size(&image_header,
                           &length, &width);
      image_header.image_length = length*ROWS;
      image_header.image_width  = width*COLS;

      create_allocate_tiff_file(out_name, &image_header,
                                out_image);
   }  /* ends if does_not_exist */
   read_tiff_header(in_name, &image_header);

   new_hi  = 250;
   new_low = 16;
   if(image_header.bits_per_pixel == 4){
       new_hi  = 10;
       new_low = 3;
   }

   max = 255;
   if(image_header.bits_per_pixel == 4)
      max = 16;

   read_tiff_image(in_name, the_image, il, ie, ll, le);

   for(i=0; i<ROWS; i++)
      for(j=0; j<COLS; j++)
         out_image[i][j] = 0;

   for(i=1; i<ROWS-1; i++){
      if( (i%10) == 0) printf("%3d", i);
      for(j=1; j<COLS-1; j++){

         sum_n = 0;
         sum_d = 0;

         for(a=-1; a<2; a++){
            for(b=-1; b<2; b++){
               sum_n = sum_n + the_image[i+a][j+b] *
                       e_mask[a+1][b+1];
               sum_d = sum_d + the_image[i+a][j+b] *
                       contrast[a+1][b+1];
            }
         }

         d = sum_d / 9;
         if(d == 0)
            d = 1;

         out_image[i][j] = sum_n/d;

         if(out_image[i][j] > max) out_image[i][j] = max;
         if(out_image[i][j] < 0) out_image[i][j] = 0;


      }  /* ends loop over j */
   }  /* ends loop over i */



     /* if desired, threshold the output image */
   if(threshold == 1){
       for(i=0; i<ROWS; i++){
          for(j=0; j<COLS; j++){
             if(out_image[i][j] > high){
                  out_image[i][j] = new_hi;
             }

             else{
                  out_image[i][j] = new_low;
             }
          }
       }
   }  /* ends if threshold == 1 */


   fix_edges(out_image, 1);
   write_array_into_tiff_image(out_name, out_image,
                               il, ie, ll, le);

} /* ends contrast_edge */

/* End of File */ 

