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
/
vgmerode
/
vgmerode.prog
< prev
Wrap
Text File
|
1992-07-28
|
9KB
|
281 lines
-authors
Pascal ADAM and Greg DONOHOE
-authors_end
-short_prog_description
Erode a greyscale image X, by a structuring element B.
-short_prog_description_end
-short_lib_description
Erode a greyscale image X, by a structuring element B.
-short_lib_description_end
-man1_long_description
.I vgmerode
computes the Erosion of an greyscale image by a structuring element.
.sp 2
This algorithms is taken from Digital Image Processing by R.C. Gonzalez and
R.E. Woods, Addison-Wesley, 1992. It replaces each pixel X(p,q) of image X
by MIN{ (X(x-p,y-q) - B(x,y))} for all (x,y) belonging to
B. The result is clipped to the range [0-255]. Valid values of B(x,y)
are in the range [0 - 255]. Pixels in B that are not part of the domain
of B should be negative. For this reason, the structuring element
is of type 'int'.
-man1_long_description_end
-man1_examples
vgmerode -i image1 -k kernel -o image2
.LP
Computes the erosion of an image X (intput -i) by a structuring
element B (input -k) and stores the result in the output image ( -o).
-man1_examples_end
-man1_restrictions
\fIvgmerode\fP accepts only \fIBYTE\fP images, and the kernel must
be type \fIINT\fP.
-man1_restrictions_end
-man1_see_also
lvgmerode(3)
-man1_see_also_end
-man3_long_description
.I lvgmerode
computes the Erosion of an greyscale image by a structuring element.
.sp 2
This algorithms is taken from Digital Image Processing by R.C. Gonzalez and
R.E. Woods, Addison-Wesley, 1992. It replaces each pixel X(p,q) of image X
by MAX{ (X(x-p,y-q) - B(x,y))} for all (x,y) belonging to
B. The result is clipped to the range [0-255]. Valid values of B(x,y)
are in the range [0 - 255]. Pixels in B that are not part of the domain
of B should be negative. For this reason, the structuring element
is of type 'int'.
-man3_long_description_end
-man3_restrictions
.LP
\fIvgmerode\fP accepts only \fIBYTE\fP images, and the kernel must
be type\fIINT\fP.
-man3_restrictions_end
-man3_see_also
vgmerode(1)
-man3_see_also_end
-usage_additions
-usage_additions_end
-include_includes
-include_includes_end
-include_additions
-include_additions_end
-include_macros
#define READINPUT(image,kernel) \
image = readimage(vgmerode->i_file); \
if (image == NULL) { \
(void) fprintf(stderr, "vgmerode: Can not read input image \n"); \
exit(1); /* Quit if bad image */ \
} \
kernel = readimage(vgmerode->k_file); \
if (kernel == NULL) { \
(void) fprintf(stderr, "vgmerode: Can not read input kernel\n"); \
exit(1); /* Quit if bad kernel */ \
}
#define CHECKINPUT(program, image,kernel) \
propertype(program,image,VFF_TYP_1_BYTE,TRUE); \
proper_num_images(program,image,1,TRUE); \
proper_num_bands(program,image,1,TRUE); \
proper_map_enable(program,image,VFF_MAP_OPTIONAL,TRUE); \
propertype(program,kernel,VFF_TYP_4_BYTE,TRUE) ; \
proper_num_images(program,kernel,1,TRUE); \
proper_num_bands(program,kernel,1,TRUE); \
proper_map_enable(program,kernel,VFF_MAP_OPTIONAL,TRUE); \
-include_macros_end
-main_variable_list
struct xvimage *image, *kernel,*readimage();
-main_variable_list_end
-main_before_lib_call
if (check_args()) exit(1);
READINPUT (image, kernel);
CHECKINPUT (program, image, kernel);
-main_before_lib_call_end
-main_library_call
if(! lvgmerode(image,kernel))
{
(void) fprintf(stderr, "vgmerode: lvgmerode Failed\n");
exit(1);
}
-main_library_call_end
-main_after_lib_call
writeimage(vgmerode->o_file,image);
-main_after_lib_call_end
-library_includes
-library_includes_end
-library_input
.IP "img" 15
xvimage structure, must be a byte image.
.IP "ker" 15
xvimage structure, morphological kernel or structuring element.
Should have been created by vmcustom.
-library_input_end
-library_output
.IP "img2" 15
xvimage structure, erosion of img1 by kernel ker.
-library_output_end
-library_def
int
lvgmerode(image,kernel)
struct xvimage *image, *kernel;
-library_def_end
-library_code
{
int belong, /* TRAN(IMG2;i,j) belongs to IMG1 ? */
nc, /* number of columns of image */
nr, /* " " rows " " */
starti, /* x upper left corner position of kernel */
startj, /* y " " " " " " */
kernc, /* number of columns of kernel */
kernr; /* number of rows of kernel */
unsigned char *result; /* storage of final result */
char *program = "lvgmerode";
int i,j,k,ii,jj,iii,jjj;
register int minpix, imagepix, kernpix;
unsigned char *c1, *c3;
int *c2;
/* Check type,... of image */
if (!(propertype(program, image, VFF_TYP_1_BYTE, FALSE))) {
(void) fprintf (stderr, "\n\n%s: ", program);
(void) fprintf (stderr, "lvgmerode: image must be of type int\n");
return (0);
}
if (!(proper_num_images (program, image, 1, FALSE))) {
(void) fprintf (stderr, "\n\n%s: ", program);
(void) fprintf (stderr, "Can only work on files with one image\n\n");
return (0);
}
if (!(proper_num_bands (program, image, 1, FALSE))) {
(void) fprintf (stderr,"\n\n%s: ", program);
(void) fprintf (stderr,"Can only work on images with 1 data band\n\n");
return (0);
}
nc = image->row_size; /* number of columns */
nr = image->col_size; /* number of rows */
c1 = (unsigned char *)(image->imagedata); /* pointer on image's pixels */
/* Check type,... of image */
if (!(propertype(program, kernel, VFF_TYP_4_BYTE, FALSE))) {
(void) fprintf (stderr,"\n\n%s: ", program);
(void) fprintf (stderr,"lvgmerode: kernel must be of type int/n");
return (0);
}
if (!(proper_num_images (program, kernel, 1, FALSE))) {
(void) fprintf (stderr,"\n\n%s: ", program);
(void) fprintf (stderr,"Can only work on files with one image\n\n");
return (0);
}
if (!(proper_num_bands (program, kernel, 1, FALSE))) {
(void) fprintf (stderr,"\n\n%s: ", program);
(void) fprintf (stderr,"Can only work on images with 1 data band\n\n");
return (0);
}
kernc = kernel->row_size;/* number of columns of the kernel */
kernr = kernel->col_size;/* number of rows of the kernel */
starti = (int)kernel->ispare1; /* position of upper left hand */
startj = (int)kernel->ispare2; /* corner of the kernel (x,y) */
c2 = (int *)(kernel->imagedata); /* pointer to kernel values */
/* Checks if the relative position of the kernel relative to the
** dimension of the image will give a significant result image */
if (starti>nr/2 || startj>nc/2) {
(void) fprintf (stderr, "\n%s: ", program);
(void) fprintf (stderr, "Warning : the size of the kernel\n");
(void) fprintf (stderr, "is too big compared to the image\n");
(void) fprintf (stderr, "size. The visible result may out\n");
(void) fprintf (stderr, "of the result image dimension...\n");
}
/* dynamic memory allocation for temporary result stockage */
result = (unsigned char *) malloc( nc * nr *sizeof(unsigned char));
if (result == NULL) {
(void) fprintf (stderr, "\n%s: ", program);
(void) fprintf (stderr, "Insufficient Space avaliable\n");
return(0);
}
c3 = result; /* pointer on the result image data */
k = nc * nr; /* total number of pixels in the input image */
/* initialisation of the resulting image */
for (j=0;j<k;j++) *(c3 +j)=0;
/* Scans and computes the final value of the result image */
for (i=0;i<nr;i++) {
for (j=0;j<nc;j++) {
/* Compute erosion. Scan image and kernel. For each non-negative */
/* kernel location, find difference between image and kernel. */
/* Replace center pixel with minimum of these difference, clipped */
/* to zero. */
minpix = 255; /* Initialize to max value */
for (ii=0; ii < kernr; ii++) {
iii = i + ii + starti;
if (iii<0 || iii>=nr) continue;
for (jj = 0; jj < kernc; jj++) {
jjj = j + jj + startj;
if (jjj>=0 && jjj<nc) {
imagepix = *(c1+iii*nc+jjj);
kernpix = *(c2+ii*kernc+jj);
if (kernpix >= 0)
minpix = MIN(minpix, (imagepix - kernpix));
}
}
}
if (minpix < 0)
*(c3 + i*nc + j) = (unsigned char)0;
else
*(c3 + i*nc + j) = (unsigned char)minpix;
}
}
c3=result;
c1=(unsigned char *)image->imagedata;
/* transfert result data in image data */
for (i=0;i<k;i++) *(c1++) = *(c3++);
/* free memory location of temporary result storage */
free(result);
return(1);
}
-library_code_end
-library_mods
Has been updated to ghostX on 5/24/90 by Pascal ADAM
-library_mods_end