home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_10_10 / 1010074a < prev    next >
Text File  |  1992-08-11  |  11KB  |  443 lines

  1.        /***********************************************
  2.        *
  3.        *       file d:\cips\filter.c
  4.        *
  5.        *       Functions: This file contains
  6.        *          filter_image
  7.        *          median_filter
  8.        *          setup_fitlers
  9.        *          get_filter_options
  10.        *          median_of
  11.        *          sort_elements
  12.        *          swap
  13.        *
  14.        *       Purpose:
  15.        *          These functions implement several
  16.        *          types of basic spatial frequency filters.
  17.        *
  18.        *       External Calls:
  19.        *          wtiff.c - does_not_exist
  20.        *                    round_off_image_size
  21.        *                    create_allocate_tiff_file
  22.        *                    write_array_into_tiff_image
  23.        *          tiff.c - read_tiff_header
  24.        *          rtiff.c - read_tiff_image
  25.        *          numcvrt.c - get_integer
  26.        *
  27.        *
  28.        *       Modifications:
  29.        *          15 February 1992 - created
  30.        *
  31.        *************************************************/
  32.  
  33. #include "d:\cips\cips.h"
  34. #include <malloc.h>
  35.  
  36.  
  37.      /*******************************************
  38.      *
  39.      *   Define the filter masks.
  40.      *
  41.      *******************************************/
  42.  
  43. short lpf_filter_6[3][3] =
  44.    { {0, 1, 0},
  45.      {1, 2, 1},
  46.      {0, 1, 0}};
  47.  
  48. short lpf_filter_9[3][3] =
  49.    { {1, 1, 1},
  50.      {1, 1, 1},
  51.      {1, 1, 1}};
  52.  
  53. short lpf_filter_10[3][3] =
  54.    { {1, 1, 1},
  55.      {1, 2, 1},
  56.      {1, 1, 1}};
  57.  
  58. short lpf_filter_16[3][3] =
  59.  
  60.    { {1, 2, 1},
  61.      {2, 4, 2},
  62.      {1, 2, 1}};
  63.  
  64. short hpf_filter_1[3][3] =
  65.    { { 0, -1,  0},
  66.      {-1,  5, -1},
  67.      { 0, -1,  0}};
  68.  
  69. short hpf_filter_2[3][3] =
  70.    { {-1, -1, -1},
  71.      {-1,  9, -1},
  72.      {-1, -1, -1}};
  73.  
  74. short hpf_filter_3[3][3] =
  75.    { { 1, -2,  1},
  76.      {-2,  5, -2},
  77.      { 1, -2,  1}};
  78.  
  79.  
  80.      /*******************************************
  81.      *
  82.      *   filter_image(...
  83.      *
  84.      *   This function filters an image by using
  85.      *   a single 3x3 mask.
  86.      *
  87.      *******************************************/
  88.  
  89.  
  90. filter_image(in_name, out_name, the_image, out_image,
  91.              il, ie, ll, le, filter, type)
  92.    char   in_name[], out_name[];
  93.    int    il, ie, ll, le, type;
  94.    short  filter[3][3],
  95.           the_image[ROWS][COLS],
  96.           out_image[ROWS][COLS];
  97.  
  98. {
  99.    int    a, b, d, i, j, k,
  100.           length, max, sum, width;
  101.    struct tiff_header_struct image_header;
  102.  
  103.  
  104.    if(does_not_exist(out_name)){
  105.       printf("\n\n output file does not exist %s",
  106.             out_name);
  107.       read_tiff_header(in_name, &image_header);
  108.       round_off_image_size(&image_header,
  109.                            &length, &width);
  110.       image_header.image_length = length*ROWS;
  111.       image_header.image_width  = width*COLS;
  112.       create_allocate_tiff_file(out_name, &image_header,
  113.                                 out_image);
  114.    }  /* ends if does_not_exist */
  115.  
  116.    read_tiff_header(in_name, &image_header);
  117.  
  118.    d = type;
  119.    if(type == 2 || type == 3) d = 1;
  120.  
  121.    max = 255;
  122.    if(image_header.bits_per_pixel == 4)
  123.       max = 16;
  124.  
  125.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  126.  
  127.          /* Do convolution over image array */
  128.    printf("\n");
  129.    for(i=1; i<ROWS-1; i++){
  130.       if( (i%10) == 0) printf("%d ", i);
  131.       for(j=1; j<COLS-1; j++){
  132.          sum = 0;
  133.          for(a=-1; a<2; a++){
  134.             for(b=-1; b<2; b++){
  135.                sum = sum +
  136.                      the_image[i+a][j+b] *
  137.                      filter[a+1][b+1];
  138.             }
  139.          }
  140.          sum               = sum/d;
  141.          if(sum < 0)   sum = 0;
  142.          if(sum > max) sum = max;
  143.          out_image[i][j]   = sum;
  144.  
  145.       }  /* ends loop over j */
  146.    }  /* ends loop over i */
  147.  
  148.    fix_edges(out_image, 1);
  149.  
  150.    write_array_into_tiff_image(out_name, out_image,
  151.                                il, ie, ll, le);
  152.  
  153. }  /* ends filter_image */
  154.  
  155.  
  156.  
  157.      /*******************************************
  158.      *
  159.      *   median_filter(..
  160.      *
  161.      *   This function performs a median filter
  162.      *   on an image using a size (3x3, 5x5, etc.)
  163.      *   specified in the call.
  164.      *
  165.      *******************************************/
  166.  
  167.  
  168. median_filter(in_name, out_name, the_image, out_image,
  169.               il, ie, ll, le, size)
  170.    char   in_name[], out_name[];
  171.    int    il, ie, ll, le, size;
  172.    short  the_image[ROWS][COLS],
  173.           out_image[ROWS][COLS];
  174.  
  175. {
  176.    int    a, b, count, i, j, k,
  177.  
  178.           length, sd2, sd2p1, ss, width;
  179.    short  *elements;
  180.    struct tiff_header_struct image_header;
  181.  
  182.    sd2   = size/2;
  183.    sd2p1 = sd2 + 1;
  184.  
  185.       /**********************************************
  186.       *
  187.       *   Allocate the elements array large enough
  188.       *   to hold size*size shorts. 
  189.       *
  190.       **********************************************/
  191.  
  192.    ss       = size*size;
  193.    elements = (short *) malloc(ss * sizeof(short));
  194.  
  195.    if(does_not_exist(out_name)){
  196.       printf("\n\n output file does not exist %s",
  197.             out_name);
  198.       read_tiff_header(in_name, &image_header);
  199.       round_off_image_size(&image_header,
  200.                            &length, &width);
  201.       image_header.image_length = length*ROWS;
  202.       image_header.image_width  = width*COLS;
  203.       create_allocate_tiff_file(out_name, &image_header,
  204.                                 out_image);
  205.    }  /* ends if does_not_exist */
  206.  
  207.    read_tiff_image(in_name, the_image, il, ie, ll, le);
  208.  
  209.       /***************************
  210.       *
  211.       *   Loop over image array
  212.       *
  213.       ****************************/
  214.  
  215.    printf("\n");
  216.    for(i=sd2; i<ROWS-sd2; i++){
  217.       if( (i%10) == 0) printf("%d ", i);
  218.       for(j=sd2; j<COLS-sd2; j++){
  219.          count = 0;
  220.          for(a=-sd2; a<sd2p1; a++){
  221.             for(b=-sd2; b<sd2p1; b++){
  222.                elements[count] = the_image[i+a][j+b];
  223.                count++;
  224.             }
  225.          }
  226.          out_image[i][j] = median_of(elements, &ss);
  227.       }  /* ends loop over j */
  228.    }  /* ends loop over i */
  229.  
  230.    fix_edges(out_image, sd2);
  231.  
  232.    write_array_into_tiff_image(out_name, out_image,
  233.                                il, ie, ll, le);
  234.  
  235. }  /* ends median_filter */
  236.  
  237.  
  238.    /***********************************************
  239.     *
  240.     *    median_of(...
  241.     *
  242.     *    This function finds and returns the
  243.     *    median value of the elements array.
  244.     *
  245.     *    As a side result, it also sorts the
  246.     *    elements array.
  247.     *
  248.     ***********************************************/
  249.  
  250. median_of(elements, count)
  251.    int   *count;
  252.    short elements[];
  253. {
  254.    short median;
  255.  
  256.    sort_elements(elements, count);
  257.    median = elements[*count/2];
  258.    return(median);
  259. }  /* ends median_of */
  260.  
  261.  
  262.    /***********************************************
  263.     *
  264.     *    sort_elements(...
  265.     *
  266.     *    This function performs a simple bubble
  267.     *    sort on the elements from the median
  268.     *    filter.
  269.     *
  270.     ***********************************************/
  271.  
  272. sort_elements(elements, count)
  273.    int   *count;
  274.    short elements[];
  275. {
  276.    int i, j;
  277.    j = *count;
  278.    while(j-- > 1){
  279.       for(i=0; i<j; i++){
  280.          if(elements[i] > elements[i+1])
  281.             swap(&elements[i], &elements[i+1]);
  282.       }
  283.    }
  284. }  /* ends sort_elements */
  285.  
  286.  
  287.    /***********************************************
  288.     *
  289.     *    swap(...
  290.     *
  291.     *    This function swaps two shorts.
  292.     *
  293.     ***********************************************/
  294.  
  295. swap(a, b)
  296.  
  297.    short *a, *b;
  298. {
  299.    short temp;
  300.    temp  = *a;
  301.    *a    = *b;
  302.    *b    = temp;
  303. }  /* ends swap */
  304.  
  305.  
  306.     /*******************************************************
  307.     *
  308.     *    setup_filters(...
  309.     *
  310.     *    This function copies the filter mask values defined
  311.     *    at the top of this file into the filter array.
  312.     *
  313.  
  314.     *****************************************************/
  315.  
  316.  
  317. setup_filters(filter_type, low_high, filter)
  318.    char   low_high[];
  319.    int    filter_type;
  320.    short  filter[3][3];
  321. {
  322.    int i, j;
  323.  
  324.    if(low_high[0] == 'l'  || low_high[0] =='L'){
  325.       if(filter_type == 6){
  326.          for(i=0; i<3; i++){
  327.            for(j=0; j<3; j++){
  328.              filter[i][j] = lpf_filter_6[i][j];
  329.            }
  330.          }
  331.       }  /* ends if filter_type == 6 */
  332.  
  333.       if(filter_type == 9){
  334.          for(i=0; i<3; i++){
  335.            for(j=0; j<3; j++){
  336.              filter[i][j] = lpf_filter_9[i][j];
  337.            }
  338.          }
  339.       }  /* ends if filter_type == 9 */
  340.  
  341.       if(filter_type == 10){
  342.          for(i=0; i<3; i++){
  343.            for(j=0; j<3; j++){
  344.              filter[i][j] = lpf_filter_10[i][j];
  345.            }
  346.          }
  347.       }  /* ends if filter_type == 10 */
  348.  
  349.  
  350.       if(filter_type == 16){
  351.          for(i=0; i<3; i++){
  352.            for(j=0; j<3; j++){
  353.              filter[i][j] = lpf_filter_16[i][j];
  354.            }
  355.          }
  356.       }  /* ends if filter_type == 16 */
  357.  
  358.    }  /* ends low pass filter */
  359.  
  360.    if(low_high[0] == 'h'  || low_high[0] =='H'){
  361.       if(filter_type == 1){
  362.          for(i=0; i<3; i++){
  363.            for(j=0; j<3; j++){
  364.              filter[i][j] = hpf_filter_1[i][j];
  365.            }
  366.          }
  367.       }  /* ends if filter_type == 1 */
  368.  
  369.       if(filter_type == 2){
  370.          for(i=0; i<3; i++){
  371.            for(j=0; j<3; j++){
  372.              filter[i][j] = hpf_filter_2[i][j];
  373.            }
  374.          }
  375.       }  /* ends if filter_type == 2 */
  376.  
  377.       if(filter_type == 3){
  378.          for(i=0; i<3; i++){
  379.            for(j=0; j<3; j++){
  380.              filter[i][j] = hpf_filter_3[i][j];
  381.            }
  382.          }
  383.       }  /* ends if filter_type == 3 */
  384.    }  /* ends high pass filter */
  385.  
  386. }  /* ends setup_filters */
  387.  
  388.  
  389.    /***********************************************
  390.     *
  391.     *    get_filter_options(...
  392.     *
  393.     *    This function queries the user for the
  394.     *    parameters needed to perform filtering.
  395.     *
  396.     ***********************************************/
  397.  
  398.  
  399. get_filter_options(filter_type, low_high)
  400.     char low_high[];
  401.     int  *filter_type;
  402. {
  403.     int not_finished, response;
  404.     not_finished = 1;
  405.     while(not_finished){
  406.  
  407.       printf("\nThe filter options are:\n");
  408.       printf("\n\t1.  Type of filter is %d",
  409.             *filter_type);
  410.       printf("\n\t      (recall 6, 9, 10,
  411.             16 for low pass)");
  412.       printf("\n\t      (recall 1, 2, 3 for high pass)");
  413.       printf("\n\t2.  Low or High Pass filter is %s",
  414.              low_high);
  415.       printf("\n\t      l=low pass h=high pass "
  416.              "m=median filter ");
  417.       printf("\n\nEnter choice (0 = no change) _\b");
  418.  
  419.  
  420.  
  421.       get_integer(&response);
  422.  
  423.       if(response == 0){
  424.         not_finished = 0;
  425.       }
  426.  
  427.       if(response == 1){
  428.         printf("\n\nEnter type of filter");
  429.         printf("\n  _\b");
  430.         get_integer(filter_type);
  431.       }
  432.  
  433.       if(response == 2){
  434.         printf("\n\nEnter l=low pass h=high pass "
  435.                  "m=median filter");
  436.         printf("\n  _\b");
  437.         read_string(low_high);
  438.       }
  439.     }  /* ends while not_finished */
  440.  
  441. }  /* ends get_filter_options */
  442.  
  443.