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
Wrap
Text File
|
1992-07-26
|
12KB
|
356 lines
-authors
Greg DONOHOE and Pascal ADAM
-authors_end
-short_prog_description
Perform a tophat transform on image X, using structuring element B.
-short_prog_description_end
-short_lib_description
Perform a tophat transform on image X, using structuring element B.
-short_lib_description_end
-man1_long_description
.I vgmtophat
computes the Top Hat transform 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. The Top Hat of image X by kernel
B is defined as X - Open(X,B).
The effect is to enchance detail and suppress smooth, dark areas.
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
vgmtophat -i image1 -k kernel -o image2
.LP
Computes the opening 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
\fIvgmtophat\fP accepts only \fIBYTE\fP images, and the kernel must
be type \fIINT\fP.
-man1_restrictions_end
-man1_see_also
vmcustom(1), lvmcustom(3)
-man1_see_also_end
-man3_long_description
.I lvgmtophat
computes the Top Hat filter 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. Performing the Top Hat filter of
image X by structering element B is defined as X - Open(X,B).
The effect is to enhance detail while suppressing dark areas.
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
\fIvgmtophat\fP accepts only \fIBYTE\fP images, and the kernel must
be type\fIINT\fP.
-man3_restrictions_end
-man3_see_also
vgmtophat(1)
-man3_see_also_end
-usage_additions
-usage_additions_end
-include_includes
-include_includes_end
-include_additions
-include_additions_end
-include_macros
#define READINPUT(image1,kernel) \
image1 = readimage(vgmtophat->i_file); \
if (image1 == NULL) { \
(void) fprintf(stderr, "vgmtophat: Can not read input image \n"); \
exit(1); /* Quit if bad image */ \
} \
kernel = readimage(vgmtophat->k_file); \
if (kernel == NULL) { \
(void) fprintf(stderr, "vgmtophat: Can not read input kernel\n"); \
exit(1); /* Quit if bad kernel */ \
}
#define CHECKINPUT(program, image1, kernel) \
propertype(program,image1,VFF_TYP_1_BYTE,TRUE); \
proper_num_images(program,image1,1,TRUE); \
proper_num_bands(program,image1,1,TRUE); \
proper_map_enable(program,image1,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 *image1, *kernel, *readimage();
-main_variable_list_end
-main_before_lib_call
if (check_args()) exit(1);
READINPUT (image1, kernel);
CHECKINPUT (program, image1, kernel);
-main_before_lib_call_end
-main_library_call
if(! lvgmtophat(image1, kernel,vgmtophat->s_float,
vgmtophat->normal_logic))
{
(void) fprintf(stderr, "vgmtophat: lvgmtophat Failed\n");
exit(1);
}
-main_library_call_end
-main_after_lib_call
writeimage(vgmtophat->o_file,image1);
-main_after_lib_call_end
-library_includes
#include <limits.h>
-library_includes_end
-library_input
.IP "image" 15
xvimage structure, must be a byte image.
.IP "kernel" 15
xvimage structure, morphological kernel or structuring element.
Should have been created by vmcustom.
.IP "s_float"
scale factor: proportion of smoothed image to subtract
.IP "normal_logical"
normalize output image?
-library_input_end
-library_output
.IP "img2" 15
xvimage structure, opening of img1 by kernel ker.
-library_output_end
-library_def
int
lvgmtophat(image1, kernel, scale, normalize)
struct xvimage *image1, *kernel;
float scale;
int normalize;
-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 */
int *result; /* storage of final result */
char *program = "lvgmtophat";
int i,j,k,ii,jj,iii,jjj;
register int minpix, maxpix, imagepix, kernpix, index;
struct xvimage *img, *createimage();
unsigned char *c1;
int *c2, *c3;
int *c4;
float fmax, fmin; /* max and min for normalization */
float a, b; /* scale factor and offset for normlzn */
/* Check type,... of image */
if (!(propertype(program, image1, VFF_TYP_1_BYTE, FALSE))) {
(void) fprintf (stderr, "\n\n%s: ", program);
(void) fprintf (stderr, "lvgmtophat: image must be of type byte\n");
return (0);
}
if (!(proper_num_images (program, image1, 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, image1, 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 = image1->row_size; /* number of columns */
nr = image1->col_size; /* number of rows */
c1 = (unsigned char *)(image1->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,"lvgmtophat: 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);
}
img = createimage((unsigned long) nr, /* number of rows */
(unsigned long) nc, /* number of columns */
(unsigned long) /* data storage type */
VFF_TYP_4_BYTE,
(unsigned long) 1, /* num_of_images */
(unsigned long) 1, /* num_data_bands */
"created by vgmtophat", /* comment */
(unsigned long) 0, /* map_row_size */
(unsigned long) 0, /* map_col_size */
(unsigned long)
VFF_MS_NONE, /* map_scheme */
(unsigned long)
VFF_MAPTYP_NONE, /* map_storage_type */
(unsigned long)
VFF_LOC_IMPLICIT, /* location_type */
(unsigned long) 0); /* location_dim */
img;
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 on 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 = (int *) malloc( nc * nr *sizeof(unsigned int));
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 */
/* First ERODE the image by the structuring element */
for (i=0;i<nr;i++) {
for (j=0;j<nc;j++) {
minpix = 255;
for (ii=0; ii < kernr; ii++) {
iii = i + ii + starti;
for (jj = 0; jj < kernc; jj++) {
jjj = j + jj + startj;
imagepix = *(c1+iii*nc+jjj);
kernpix = *(c2+ii*kernc+jj);
if (kernpix != 0)
minpix = MIN(minpix, (imagepix - kernpix));
}
}
/*
Remove the clipping for intermediate result
minpix = MAX(minpix, 0);
*/
*(c3 + i*nc + j) = (int)minpix;
}
}
c4 = (int *)(img->imagedata);
fmin = INT_MAX;
fmax = INT_MIN;
/* Now DILATE the image by the structuring element */
/* Use the input image for the result */
for (i=0;i<nr;i++) {
for (j=0;j<nc;j++) {
maxpix = 0;
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 = *(c3+iii*nc+jjj);
kernpix = *(c2+ii*kernc+jj);
if (kernpix >= 0)
maxpix = MAX(maxpix, (imagepix + kernpix));
}
}
}
index = i*nc + j;
imagepix = *(c1 + index) - (int)(scale*(float)maxpix);
imagepix = MAX(imagepix, 0);
fmax = MAX(imagepix, fmax);
fmin = MIN(imagepix, fmin);
*(c4 + index) = (unsigned char)(imagepix);
}
}
/* Copy the integer result to the byte-valued input image. */
/* If the 'normalize' logical variable is set, normalize */
/* the output image; otherwise, just clip it. */
c1 = (unsigned char *)(image1->imagedata);
c4 = (int *)(img->imagedata);
if (normalize) {
a = (float)255/(fmax-fmin);
b = - a*fmin;
for (i=0; i<k; i++) {
imagepix = (int)(a*(float)c4[i] + b);
c1[i] = (unsigned char)imagepix;
}
}
else {
for (i=0; i<k; i++)
c1[i] = (unsigned char ) MIN((c4[i]),255);
}
/* 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