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 / vgmclose / vgmclose.prog < prev   
Text File  |  1992-07-26  |  10KB  |  295 lines

  1. -authors
  2. Pascal ADAM and Greg DONOHOE
  3. -authors_end
  4.  
  5. -short_prog_description
  6. Close a greyscale image X, by a structuring element B.
  7. -short_prog_description_end
  8.  
  9. -short_lib_description
  10. Close a greyscale image X, by a structuring element B.
  11. -short_lib_description_end
  12.  
  13. -man1_long_description
  14. .I vgmclose  
  15. computes the Closing 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.  It Dilates  X by B,
  19. then Erodes the result by B.
  20. The result is clipped to the range [0-255].  Valid values of B(x,y)
  21. are in the range [0 - 255].  Pixels in B that are not part of the domain
  22. of B should be negative.  For this reason,  the structuring element
  23. is of type 'int'.
  24. -man1_long_description_end
  25.  
  26. -man1_examples
  27. vgmclose -i image1 -k kernel -o image2
  28. .LP
  29. Computes the closeing of an image X (intput -i) by a structuring
  30. element B (input -k) and stores the result in the output image ( -o).
  31. -man1_examples_end
  32.  
  33. -man1_restrictions
  34. \fIvgmclose\fP accepts only \fIBYTE\fP images,  and the kernel must
  35. be type \fIINT\fP.
  36. -man1_restrictions_end
  37.  
  38. -man1_see_also
  39. vmcustom(1), lvmcustom(3)
  40. -man1_see_also_end
  41.  
  42. -man3_long_description
  43. .I lvgmclose
  44. computes the Closing of an greyscale image by a structuring element.
  45. .sp 2
  46. This algorithms is taken from Digital Image Processing by R.C. Gonzalez and
  47. R.E. Woods, Addison-Wesley,  1992.  Closing is defined as a
  48. Dilation followed by an Erosion.
  49. The result is clipped to the range [0-255].  Valid values of B(x,y)
  50. are in the range [0 - 255].  Pixels in B that are not part of the domain
  51. of B should be negative.  For this reason,  the structuring element
  52. is of type 'int'.
  53. -man3_long_description_end
  54.  
  55. -man3_restrictions
  56. .LP
  57. \fIvgmclose\fP accepts only \fIBYTE\fP images,  and the kernel must
  58. be type\fIINT\fP.
  59. -man3_restrictions_end
  60.  
  61. -man3_see_also
  62. vgmclose(1)
  63. -man3_see_also_end
  64.  
  65. -usage_additions
  66. -usage_additions_end
  67.  
  68. -include_includes
  69. -include_includes_end
  70.  
  71. -include_additions
  72. -include_additions_end
  73.  
  74. -include_macros
  75. #define READINPUT(image,kernel) \
  76. image = readimage(vgmclose->i_file);  \
  77. if (image == NULL) {  \
  78.    (void) fprintf(stderr, "vgmclose: Can not read input image \n");  \
  79.    exit(1);  /* Quit if bad image */ \
  80. } \
  81. kernel = readimage(vgmclose->k_file);  \
  82. if (kernel == NULL) {  \
  83.    (void) fprintf(stderr, "vgmclose: Can not read input kernel\n");  \
  84.    exit(1);  /* Quit if bad kernel */ \
  85. }
  86. #define CHECKINPUT(program, image,kernel) \
  87.     propertype(program,image,VFF_TYP_1_BYTE,TRUE); \
  88.     proper_num_images(program,image,1,TRUE);  \
  89.     proper_num_bands(program,image,1,TRUE);  \
  90.     proper_map_enable(program,image,VFF_MAP_OPTIONAL,TRUE); \
  91.     propertype(program,kernel,VFF_TYP_4_BYTE,TRUE) ; \
  92.     proper_num_images(program,kernel,1,TRUE);  \
  93.     proper_num_bands(program,kernel,1,TRUE);  \
  94.     proper_map_enable(program,kernel,VFF_MAP_OPTIONAL,TRUE); \
  95. -include_macros_end
  96.  
  97. -main_variable_list
  98.     struct xvimage *image, *kernel,*readimage();
  99. -main_variable_list_end
  100.  
  101. -main_before_lib_call
  102.     if (check_args()) exit(1);
  103.  
  104.     READINPUT (image, kernel);
  105.     CHECKINPUT (program, image, kernel);
  106.  
  107. -main_before_lib_call_end
  108.  
  109. -main_library_call
  110.     if(! lvgmclose(image,kernel))
  111.     {
  112.         (void) fprintf(stderr, "vgmclose: lvgmclose Failed\n");
  113.         exit(1);
  114.     }
  115. -main_library_call_end
  116.  
  117. -main_after_lib_call
  118.     writeimage(vgmclose->o_file,image);
  119. -main_after_lib_call_end
  120.  
  121. -library_includes
  122. -library_includes_end
  123.  
  124. -library_input
  125. .IP "img" 15
  126. xvimage structure, must be a byte image.
  127. .IP "ker" 15
  128. xvimage structure, morphological kernel or structuring element.
  129. Should have been created by vmcustom.
  130. -library_input_end
  131.  
  132. -library_output
  133. .IP "img2" 15
  134. xvimage structure, closeing of img1 by kernel ker.
  135. -library_output_end
  136.  
  137. -library_def
  138. int
  139. lvgmclose(image,kernel)
  140. struct xvimage *image, *kernel;
  141. -library_def_end
  142.  
  143. -library_code
  144. {
  145.     int belong,    /* TRAN(IMG2;i,j) belongs to IMG1 ? */ 
  146.         nc,        /* number of columns of image */ 
  147.         nr,        /*   "    "  rows    "  "    */
  148.         starti,    /* x upper left corner position of kernel */
  149.         startj,    /* y   "    "    "        "     "   "     */
  150.         kernc,     /* number of columns of kernel */
  151.         kernr;     /* number of rows of kernel */
  152.         unsigned char *result; /* storage of final result */
  153.  
  154.     char   *program = "lvgmclose";
  155.  
  156.     int i,j,k,ii,jj,iii,jjj;
  157.     register int minpix, maxpix, imagepix,  kernpix;
  158.     unsigned char *c1, *c3;
  159.     int *c2;
  160.  
  161.     /* Check type,... of image */
  162.     if (!(propertype(program, image, VFF_TYP_1_BYTE, FALSE))) {
  163.         (void) fprintf (stderr, "\n\n%s:   ", program);
  164.         (void) fprintf (stderr, "lvgmclose: image must be of type byte\n");
  165.         return (0);
  166.     }
  167.     if (!(proper_num_images (program, image, 1, FALSE))) {
  168.         (void) fprintf (stderr, "\n\n%s:   ", program);
  169.         (void) fprintf (stderr, "Can only work on files with one image\n\n");
  170.         return (0);
  171.     }
  172.     if (!(proper_num_bands (program, image, 1, FALSE))) {
  173.         (void) fprintf (stderr,"\n\n%s:   ", program);
  174.         (void) fprintf (stderr,"Can only work on images with 1 data band\n\n");
  175.         return (0);
  176.     }
  177.  
  178.     nc = image->row_size; /* number of columns */
  179.     nr = image->col_size; /* number of rows    */
  180.  
  181.     c1 = (unsigned char *)(image->imagedata); /* pointer on image's pixels */
  182.  
  183.     /* Check type,... of image */
  184.     if (!(propertype(program, kernel, VFF_TYP_4_BYTE, FALSE))) {
  185.         (void) fprintf (stderr,"\n\n%s:   ", program);
  186.         (void) fprintf (stderr,"lvgmclose: kernel must be of type int/n");
  187.         return (0);
  188.     }
  189.     if (!(proper_num_images (program, kernel, 1, FALSE))) {
  190.         (void) fprintf (stderr,"\n\n%s:   ", program);
  191.         (void) fprintf (stderr,"Can only work on files with one image\n\n");
  192.         return (0);
  193.     }
  194.     if (!(proper_num_bands (program, kernel, 1, FALSE))) {
  195.         (void) fprintf (stderr,"\n\n%s:   ", program);
  196.         (void) fprintf (stderr,"Can only work on images with 1 data band\n\n");
  197.         return (0);
  198.     }
  199.  
  200.     kernc = kernel->row_size;/* number of columns of the kernel */
  201.     kernr = kernel->col_size;/* number of rows of the kernel    */
  202.  
  203.     starti = (int)kernel->ispare1; /* position of upper left hand */ 
  204.     startj = (int)kernel->ispare2; /* corner of the kernel (x,y)  */
  205.  
  206.     c2 = (int *)(kernel->imagedata); /* pointer on kernel values */
  207.  
  208.     /* Checks if the relative position of the kernel relative to the 
  209.     ** dimension of the image will give a significant result image  */
  210.     if (starti>nr/2 || startj>nc/2) {
  211.         (void) fprintf (stderr, "\n%s:   ", program);
  212.         (void) fprintf (stderr, "Warning : the size of the kernel\n");
  213.         (void) fprintf (stderr, "is too big compared to the image\n");
  214.         (void) fprintf (stderr, "size. The visible result may out\n");
  215.         (void) fprintf (stderr, "of the result image dimension...\n");
  216.         }
  217.    
  218.     
  219.     /* dynamic memory allocation for temporary result stockage */
  220.     result = (unsigned char *) malloc( nc * nr *sizeof(int));
  221.     if (result == NULL) {
  222.         (void) fprintf (stderr, "\n%s:   ", program);
  223.         (void) fprintf (stderr, "Insufficient Space avaliable\n");
  224.         return(0);
  225.     }
  226.  
  227.     c3 = result; /* pointer on the result image data */
  228.  
  229.     k = nc * nr; /* total number of pixels in the input image */
  230.                                 
  231.     /* initialisation of the resulting image  */
  232.     for (j=0;j<k;j++) *(c3 +j)=0;
  233.  
  234.     /* Scans  and computes the final value of the result image */
  235.     
  236.     /* First DILATE the image by the structuring element */
  237.     for (i=0;i<nr;i++) {
  238.       for (j=0;j<nc;j++) {
  239.            maxpix = 0;           
  240.            for (ii=0;  ii < kernr;  ii++) {
  241.                  iii = i + ii + starti;
  242.                  if (iii<0 || iii>=nr) continue;
  243.                  for (jj = 0;  jj < kernc; jj++) {
  244.                        jjj = j + jj + startj;
  245.                        if (jjj>=0 && jjj<nc) {
  246.                           imagepix = *(c1+iii*nc+jjj);
  247.                           kernpix = *(c2+ii*kernc+jj);
  248.                           if (kernpix >= 0)
  249.                              maxpix = MAX(maxpix, (imagepix + kernpix));
  250.                         }
  251.                     }
  252.                }
  253.            maxpix = MIN(maxpix, 255);
  254.            *(c3 + i*nc + j) = (unsigned char)maxpix;
  255.         }
  256.       }
  257.  
  258.     /* Now ERODE the image by the structuring element */
  259.     /*  Use the input image for the result */
  260.     for (i=0;i<nr;i++) {
  261.       for (j=0;j<nc;j++) {
  262.  
  263.            minpix = 255; 
  264.            for (ii=0;  ii < kernr;  ii++) {
  265.                  iii = i + ii + starti;
  266.                  if (iii<0 || iii>=nr) continue;
  267.                  for (jj = 0;  jj < kernc; jj++) {
  268.                        jjj = j + jj + startj;
  269.                        if (jjj>=0 && jjj<nc) {
  270.                           imagepix = *(c3+iii*nc+jjj);
  271.                           kernpix = *(c2+ii*kernc+jj);
  272.                           if (kernpix >= 0)
  273.                              minpix = MIN(minpix, (imagepix - kernpix));
  274.                         }
  275.                     }
  276.                }
  277.            minpix = MAX(minpix, 0);
  278.            *(c1 + i*nc + j) = (unsigned char)minpix;
  279.         
  280.            }
  281.          }
  282.     
  283.     /*  Now the input image containes the closing */
  284.  
  285.     /* free memory location of temporary result storage */ 
  286.     free(result);
  287.     return(1);
  288. }
  289. -library_code_end
  290.  
  291. -library_mods
  292. Has been updated to ghostX on 5/24/90 by Pascal ADAM
  293. -library_mods_end
  294.  
  295.