home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / m / morpho.zip / morpho / src / vgmtophat / vgmtophat.prog < prev   
Text File  |  1992-07-26  |  12KB  |  356 lines

  1. -authors
  2. Greg DONOHOE and Pascal ADAM
  3. -authors_end
  4.  
  5. -short_prog_description
  6. Perform a tophat transform on image X,  using structuring element B.
  7. -short_prog_description_end
  8.  
  9. -short_lib_description
  10. Perform a tophat transform on image X,  using structuring element B.
  11. -short_lib_description_end
  12.  
  13. -man1_long_description
  14. .I vgmtophat  
  15. computes the Top Hat transform of an greyscale image by a structuring element.
  16. .sp 2
  17. This algorithms is taken from Digital Image Processing by R.C. Gonzalez and
  18. R.E. Woods, Addison-Wesley,  1992.  The Top Hat of image X by kernel
  19. B is defined as X - Open(X,B).
  20. The effect is to enchance detail and suppress smooth,  dark areas.
  21. The result is clipped to the range [0-255].  Valid values of B(x,y)
  22. are in the range [0 - 255].  Pixels in B that are not part of the domain
  23. of B should be negative.  For this reason,  the structuring element
  24. is of type 'int'.
  25. -man1_long_description_end
  26.  
  27. -man1_examples
  28. vgmtophat -i image1 -k kernel -o image2
  29. .LP
  30. Computes the opening of an image X (intput -i) by a structuring
  31. element B (input -k) and stores the result in the output image ( -o).
  32. -man1_examples_end
  33.  
  34. -man1_restrictions
  35. \fIvgmtophat\fP accepts only \fIBYTE\fP images,  and the kernel must
  36. be type \fIINT\fP.
  37. -man1_restrictions_end
  38.  
  39. -man1_see_also
  40. vmcustom(1), lvmcustom(3)
  41. -man1_see_also_end
  42.  
  43. -man3_long_description
  44. .I lvgmtophat
  45. computes the Top Hat filter of an greyscale image by a structuring element.
  46. .sp 2
  47. This algorithms is taken from Digital Image Processing by R.C. Gonzalez and
  48. R.E. Woods, Addison-Wesley,  1992.  Performing the Top Hat filter of
  49. image X by structering element B is defined as X - Open(X,B).
  50. The effect is to enhance detail while suppressing dark areas.
  51. The result is clipped to the range [0-255].  Valid values of B(x,y)
  52. are in the range [0 - 255].  Pixels in B that are not part of the domain
  53. of B should be negative.  For this reason,  the structuring element
  54. is of type 'int'.
  55. -man3_long_description_end
  56.  
  57. -man3_restrictions
  58. .LP
  59. \fIvgmtophat\fP accepts only \fIBYTE\fP images,  and the kernel must
  60. be type\fIINT\fP.
  61. -man3_restrictions_end
  62.  
  63. -man3_see_also
  64. vgmtophat(1)
  65. -man3_see_also_end
  66.  
  67. -usage_additions
  68. -usage_additions_end
  69.  
  70. -include_includes
  71. -include_includes_end
  72.  
  73. -include_additions
  74. -include_additions_end
  75.  
  76. -include_macros
  77. #define READINPUT(image1,kernel) \
  78. image1 = readimage(vgmtophat->i_file);  \
  79. if (image1 == NULL) {  \
  80.    (void) fprintf(stderr, "vgmtophat: Can not read input image \n");  \
  81.    exit(1);  /* Quit if bad image */ \
  82. } \
  83. kernel = readimage(vgmtophat->k_file);  \
  84. if (kernel == NULL) {  \
  85.    (void) fprintf(stderr, "vgmtophat: Can not read input kernel\n");  \
  86.    exit(1);  /* Quit if bad kernel */ \
  87. }
  88. #define CHECKINPUT(program, image1, kernel) \
  89.     propertype(program,image1,VFF_TYP_1_BYTE,TRUE); \
  90.     proper_num_images(program,image1,1,TRUE);  \
  91.     proper_num_bands(program,image1,1,TRUE);  \
  92.     proper_map_enable(program,image1,VFF_MAP_OPTIONAL,TRUE); \
  93.     propertype(program,kernel,VFF_TYP_4_BYTE,TRUE) ; \
  94.     proper_num_images(program,kernel,1,TRUE);  \
  95.     proper_num_bands(program,kernel,1,TRUE);  \
  96.     proper_map_enable(program,kernel,VFF_MAP_OPTIONAL,TRUE); \
  97. -include_macros_end
  98.  
  99. -main_variable_list
  100.     struct xvimage *image1, *kernel, *readimage();
  101. -main_variable_list_end
  102.  
  103. -main_before_lib_call
  104.     if (check_args()) exit(1);
  105.  
  106.     READINPUT (image1, kernel);
  107.     CHECKINPUT (program, image1, kernel);
  108.  
  109. -main_before_lib_call_end
  110.  
  111. -main_library_call
  112.     if(! lvgmtophat(image1,  kernel,vgmtophat->s_float,
  113.           vgmtophat->normal_logic))
  114.     {
  115.         (void) fprintf(stderr, "vgmtophat: lvgmtophat Failed\n");
  116.         exit(1);
  117.     }
  118. -main_library_call_end
  119.  
  120. -main_after_lib_call
  121.     writeimage(vgmtophat->o_file,image1);
  122. -main_after_lib_call_end
  123.  
  124. -library_includes
  125. #include <limits.h>
  126. -library_includes_end
  127.  
  128. -library_input
  129. .IP "image" 15
  130. xvimage structure, must be a byte image.
  131. .IP "kernel" 15
  132. xvimage structure, morphological kernel or structuring element.
  133. Should have been created by vmcustom.
  134. .IP "s_float"
  135. scale factor:  proportion of smoothed image to subtract
  136. .IP "normal_logical"
  137. normalize output image?
  138. -library_input_end
  139.  
  140. -library_output
  141. .IP "img2" 15
  142. xvimage structure, opening of img1 by kernel ker.
  143. -library_output_end
  144.  
  145. -library_def
  146. int
  147. lvgmtophat(image1,  kernel, scale, normalize)
  148. struct xvimage *image1,  *kernel;
  149. float scale;
  150. int normalize;
  151. -library_def_end
  152.  
  153. -library_code
  154. {
  155.     int belong,    /* TRAN(IMG2;i,j) belongs to IMG1 ? */ 
  156.         nc,        /* number of columns of image */ 
  157.         nr,        /*   "    "  rows    "  "    */
  158.         starti,    /* x upper left corner position of kernel */
  159.         startj,    /* y   "    "    "        "     "   "     */
  160.         kernc,     /* number of columns of kernel */
  161.         kernr;     /* number of rows of kernel */
  162.         int *result; /* storage of final result */
  163.  
  164.     char   *program = "lvgmtophat";
  165.  
  166.     int i,j,k,ii,jj,iii,jjj;
  167.     register int minpix, maxpix, imagepix,  kernpix, index;
  168.     struct xvimage *img, *createimage();
  169.     unsigned char *c1;
  170.     int *c2, *c3;
  171.     int *c4;
  172.     float fmax, fmin;   /* max and min for normalization */
  173.     float a, b;         /* scale factor and offset for normlzn */
  174.  
  175.     /* Check type,... of image */
  176.     if (!(propertype(program, image1, VFF_TYP_1_BYTE, FALSE))) {
  177.         (void) fprintf (stderr, "\n\n%s:   ", program);
  178.         (void) fprintf (stderr, "lvgmtophat: image must be of type byte\n");
  179.         return (0);
  180.     }
  181.     if (!(proper_num_images (program, image1, 1, FALSE))) {
  182.         (void) fprintf (stderr, "\n\n%s:   ", program);
  183.         (void) fprintf (stderr, "Can only work on files with one image\n\n");
  184.         return (0);
  185.     }
  186.     if (!(proper_num_bands (program, image1, 1, FALSE))) {
  187.         (void) fprintf (stderr,"\n\n%s:   ", program);
  188.         (void) fprintf (stderr,"Can only work on images with 1 data band\n\n");
  189.         return (0);
  190.     }
  191.  
  192.     nc = image1->row_size; /* number of columns */
  193.     nr = image1->col_size; /* number of rows    */
  194.  
  195.     c1 = (unsigned char *)(image1->imagedata); /* pointer on image's pixels */
  196.  
  197.     /* Check type,... of image */
  198.     if (!(propertype(program, kernel, VFF_TYP_4_BYTE, FALSE))) {
  199.         (void) fprintf (stderr,"\n\n%s:   ", program);
  200.         (void) fprintf (stderr,"lvgmtophat: kernel must be of type int\n");
  201.         return (0);
  202.     }
  203.     if (!(proper_num_images (program, kernel, 1, FALSE))) {
  204.         (void) fprintf (stderr,"\n\n%s:   ", program);
  205.         (void) fprintf (stderr,"Can only work on files with one image\n\n");
  206.         return (0);
  207.     }
  208.     if (!(proper_num_bands (program, kernel, 1, FALSE))) {
  209.         (void) fprintf (stderr,"\n\n%s:   ", program);
  210.         (void) fprintf (stderr,"Can only work on images with 1 data band\n\n");
  211.         return (0);
  212.     }
  213.  
  214.  img   =   createimage((unsigned long) nr,  /* number of rows */
  215.                      (unsigned long) nc,   /* number of columns */
  216.                      (unsigned long)       /* data storage type */
  217.                      VFF_TYP_4_BYTE,
  218.                      (unsigned long) 1,      /* num_of_images */
  219.                      (unsigned long) 1,      /* num_data_bands */
  220.                      "created by vgmtophat",    /* comment */
  221.                      (unsigned long) 0,      /* map_row_size */
  222.                      (unsigned long) 0,      /* map_col_size */
  223.                      (unsigned long)
  224.                      VFF_MS_NONE,            /* map_scheme */
  225.                      (unsigned long)
  226.                      VFF_MAPTYP_NONE,        /* map_storage_type */
  227.                      (unsigned long)
  228.                      VFF_LOC_IMPLICIT,       /* location_type */
  229.                      (unsigned long) 0);     /* location_dim */
  230.  
  231.  
  232.     img;
  233.  
  234.     kernc = kernel->row_size;/* number of columns of the kernel */
  235.     kernr = kernel->col_size;/* number of rows of the kernel    */
  236.  
  237.     starti = (int)kernel->ispare1; /* position of upper left hand */ 
  238.     startj = (int)kernel->ispare2; /* corner of the kernel (x,y)  */
  239.  
  240.     c2 = (int *)(kernel->imagedata); /* pointer on kernel values */
  241.  
  242.     /* Checks if the relative position of the kernel relative to the 
  243.     ** dimension of the image will give a significant result image  */
  244.     if (starti>nr/2 || startj>nc/2) {
  245.         (void) fprintf (stderr, "\n%s:   ", program);
  246.         (void) fprintf (stderr, "Warning : the size of the kernel\n");
  247.         (void) fprintf (stderr, "is too big compared to the image\n");
  248.         (void) fprintf (stderr, "size. The visible result may out\n");
  249.         (void) fprintf (stderr, "of the result image dimension...\n");
  250.         }
  251.    
  252.     
  253.     /* dynamic memory allocation for temporary result stockage */
  254.     result = (int *) malloc( nc * nr *sizeof(unsigned int));
  255.     if (result == NULL) {
  256.         (void) fprintf (stderr, "\n%s:   ", program);
  257.         (void) fprintf (stderr, "Insufficient Space avaliable\n");
  258.         return(0);
  259.     }
  260.  
  261.     c3 = result; /* pointer on the result image data */
  262.  
  263.     k = nc * nr; /* total number of pixels in the input image */
  264.                                 
  265.     /* initialisation of the resulting image  */
  266.     for (j=0;j<k;j++) *(c3 +j)=0;
  267.  
  268.     /* Scans  and computes the final value of the result image */
  269.     
  270.     /* First ERODE the image by the structuring element */
  271.     for (i=0;i<nr;i++) {
  272.       for (j=0;j<nc;j++) {
  273.  
  274.            minpix = 255; 
  275.            for (ii=0;  ii < kernr;  ii++) {
  276.                  iii = i + ii + starti;
  277.                  for (jj = 0;  jj < kernc; jj++) {
  278.                        jjj = j + jj + startj;
  279.                        imagepix = *(c1+iii*nc+jjj);
  280.                        kernpix = *(c2+ii*kernc+jj);
  281.                        if (kernpix != 0)
  282.                           minpix = MIN(minpix, (imagepix - kernpix));
  283.                     }
  284.                }
  285. /*
  286.            Remove the clipping for intermediate result
  287.            minpix = MAX(minpix, 0);
  288. */
  289.            *(c3 + i*nc + j) = (int)minpix;
  290.         
  291.            }
  292.          }
  293.     
  294.      c4 = (int *)(img->imagedata);
  295.      fmin = INT_MAX;
  296.      fmax = INT_MIN;
  297.  
  298.     /* Now DILATE the image by the structuring element */
  299.     /*  Use the input image for the result */
  300.     for (i=0;i<nr;i++) {
  301.       for (j=0;j<nc;j++) {
  302.            maxpix = 0;           
  303.            for (ii=0;  ii < kernr;  ii++) {
  304.                  iii = i + ii + starti;
  305.                  if (iii<0 || iii>=nr) continue;
  306.                  for (jj = 0;  jj < kernc; jj++) {
  307.                        jjj = j + jj + startj;
  308.                        if (jjj >=0 && jjj<nc) {
  309.                           imagepix = *(c3+iii*nc+jjj);
  310.                           kernpix = *(c2+ii*kernc+jj);
  311.                           if (kernpix >= 0)
  312.                           maxpix = MAX(maxpix, (imagepix + kernpix));
  313.                        }
  314.                     }
  315.                }
  316.            index = i*nc + j;
  317.            imagepix = *(c1 + index) - (int)(scale*(float)maxpix);
  318.            imagepix = MAX(imagepix, 0);
  319.            fmax = MAX(imagepix, fmax);
  320.            fmin = MIN(imagepix, fmin);
  321.            *(c4 + index) = (unsigned char)(imagepix);
  322.         }
  323.       }
  324.  
  325.  
  326.     /*  Copy the integer result to the byte-valued input image.  */
  327.     /*  If the 'normalize' logical variable is set,  normalize   */
  328.     /*  the output image;  otherwise,  just clip it.             */
  329.  
  330.     c1 = (unsigned char *)(image1->imagedata);
  331.     c4 = (int *)(img->imagedata);
  332.  
  333.     if (normalize) {
  334.           a = (float)255/(fmax-fmin);
  335.           b = - a*fmin;
  336.           for (i=0; i<k; i++) {
  337.                 imagepix = (int)(a*(float)c4[i] + b);
  338.                 c1[i] = (unsigned char)imagepix;
  339.              }
  340.        }
  341.     else {
  342.           for (i=0; i<k; i++)
  343.              c1[i] = (unsigned char ) MIN((c4[i]),255);
  344.        }
  345.  
  346.     /* free memory location of temporary result storage */ 
  347.     free(result);
  348.     return(1);
  349. }
  350. -library_code_end
  351.  
  352. -library_mods
  353. Has been updated to ghostX on 5/24/90 by Pascal ADAM
  354. -library_mods_end
  355.  
  356.