1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/****************************************************************************/
/* */
/* IMG* Image Processing Tools Library */
/* Program: imgEdgeSynth.c */
/* Author: Simon A.J. Winder */
/* Date: Thu Oct 20 20:45:37 1994 */
/* Copyright (C) 1994 Simon A.J. Winder */
/* */
/****************************************************************************/
#include "tools.h"
#define STACKSIZE 1000
#define PRGNAME "EdgeSynth"
#define ERROR(e) imgError(e,PRGNAME)
#define push(p,q) {stack[sp].x=(p);stack[sp++].y=(q);}
#define pull() ((sp>0)?(&(stack[--sp])):NULL)
#define stack_full (sp>=STACKSIZE)
/* Stack of x,y coordinates */
static it_point stack[STACKSIZE];
static int sp;
int main(int argc,char **argv)
{
it_image *i1,*i2,*i3;
int width,height,x,y,xx,yy,i,j;
double low_thresh,high_thresh;
it_float *flt_ptr;
it_point *p;
IFHELP
{
fprintf(stderr,"img%s - Canny two level edge synth operator\n",
PRGNAME);
fprintf(stderr,"img%s [low_thresh high_thresh]\n",
PRGNAME);
fprintf(stderr," stdin: Float\n");
fprintf(stderr," stdout: pbm\n");
exit(0);
}
imgStart(PRGNAME);
low_thresh=high_thresh=0.0;
if(argc>4)
ERROR("invalid arguments");
if(argc>1)
low_thresh=atof(argv[1]);
if(argc>2)
high_thresh=atof(argv[2]);
do {
/* Load the edge image */
i2=i_read_image_file(stdin,IT_FLOAT,IM_CONTIG);
if(i2==NULL)
ERROR("can't import image file");
width=i2->width;
height=i2->height;
if(argc==1)
{
low_thresh=i2->max_value*0.1;
high_thresh=i2->max_value*0.35;
}
i1=i_create_image(width,height,IT_BIT,IM_CONTIG);
if(i1==NULL)
ERROR("out of memory");
/* Make image to hold high threshold map */
i3=i_create_image(width,height,IT_BIT,IM_CONTIG);
if(i3==NULL)
ERROR("out of memory");
/* Make low and high thresholded bit images */
for(y=0;y<height;y++)
{
flt_ptr=im_float_row(i2,y);
for(x=0;x<width;x++,flt_ptr++)
{
if(*flt_ptr>low_thresh)
im_put_bit_value(i1,x,y,1);
if(*flt_ptr>=high_thresh)
im_put_bit_value(i3,x,y,1);
}
}
i_destroy_image(i2);
/* Create output bit image */
i2=i_create_image(width,height,IT_BIT,IM_CONTIG);
if(i2==NULL)
ERROR("out of memory");
/* Go through image writing out all lower threshold lines */
/* that are present to some extent in the high threshold image */
for(y=0;y<height;y++)
for(x=0;x<width;x++)
{
/* Use high threshold image for a seed */
if(im_get_bit_value(i3,x,y))
{
/* Stack starting point and clear from low thresh image */
push(x,y);
im_put_bit_value(i1,x,y,0);
/* Trace the line from x,y */
while((p=pull())!=NULL)
{
/* Write the point to the output image and delete */
/* from the high threshold image */
xx=p->x;
yy=p->y;
im_put_bit_value(i2,xx,yy,1);
im_put_bit_value(i3,xx,yy,0);
/* Stack and delete points we want to go to next */
for(i=yy-1;i<yy+2;i++)
for(j=xx-1;j<xx+2;j++)
if(i>0 && i<height && j>0 && j<width)
if(im_get_bit_value(i1,j,i))
{
if(stack_full)
ERROR("pixel stack overflowed");
push(j,i);
im_put_bit_value(i1,j,i,0);
}
}
}
}
i_destroy_image(i1);
i_destroy_image(i3);
i_write_image_file(stdout,i2,IF_BINARY);
i_destroy_image(i2);
} while(!feof(stdin));
imgFinish(PRGNAME);
return(0);
}
/* Version 1.0 (Oct 1994) */
/* Version 1.1 (Nov 1994) */
|