📄 code_susan.htm
字号:
if ((fd=fopen(filename,"wb")) == NULL)
#else
if ((fd=fopen(filename,"w")) == NULL)
#endif
exit_error("Can't output image%s.\n",filename);
fprintf(fd,"P5\n");
fprintf(fd,"%d %d\n",x_size,y_size);
fprintf(fd,"255\n");
if (fwrite(in,x_size*y_size,1,fd) != 1)
exit_error("Can't write image %s.\n",filename);
fclose(fd);
}
/* }}} */
/* {{{ int_to_uchar(r,in,size) */
int_to_uchar(r,in,size)
uchar *in;
int *r, size;
{
int i,
max_r=r[0],
min_r=r[0];
for (i=0; i<size; i++)
{
if ( r[i] > max_r )
max_r=r[i];
if ( r[i] < min_r )
min_r=r[i];
}
/*printf("min=%d max=%d\n",min_r,max_r);*/
max_r-=min_r;
for (i=0; i<size; i++)
in[i] = (uchar)((int)((int)(r[i]-min_r)*255)/max_r);
}
/* }}} */
/* {{{ setup_brightness_lut(bp,thresh,form) */
void setup_brightness_lut(bp,thresh,form)
uchar **bp;
int thresh, form;
{
int k;
float temp;
*bp=(unsigned char *)malloc(516);
*bp=*bp+258;
for(k=-256;k<257;k++)
{
temp=((float)k)/((float)thresh);
temp=temp*temp;
if (form==6)
temp=temp*temp*temp;
temp=100.0*exp(-temp);
*(*bp+k)= (uchar)temp;
}
}
/* }}} */
/* {{{ susan principle */
/* {{{ susan_principle(in,r,bp,max_no,x_size,y_size) */
susan_principle(in,r,bp,max_no,x_size,y_size)
uchar *in, *bp;
int *r, max_no, x_size, y_size;
{
int i, j, n;
uchar *p,*cp;
memset (r,0,x_size * y_size * sizeof(int));
for (i=3;i<y_size-3;i++)
for (j=3;j<x_size-3;j++)
{
n=100;
p=in + (i-3)*x_size + j - 1;
cp=bp + in[i*x_size+j];
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=x_size-3;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=x_size-5;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=x_size-6;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=2;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=x_size-6;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=x_size-5;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=x_size-3;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
if (n<=max_no)
r[i*x_size+j] = max_no - n;
}
}
/* }}} */
/* {{{ susan_principle_small(in,r,bp,max_no,x_size,y_size) */
susan_principle_small(in,r,bp,max_no,x_size,y_size)
uchar *in, *bp;
int *r, max_no, x_size, y_size;
{
int i, j, n;
uchar *p,*cp;
memset (r,0,x_size * y_size * sizeof(int));
max_no = 730; /* ho hum ;) */
for (i=1;i<y_size-1;i++)
for (j=1;j<x_size-1;j++)
{
n=100;
p=in + (i-1)*x_size + j - 1;
cp=bp + in[i*x_size+j];
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=x_size-2;
n+=*(cp-*p);
p+=2;
n+=*(cp-*p);
p+=x_size-2;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
if (n<=max_no)
r[i*x_size+j] = max_no - n;
}
}
/* }}} */
/* }}} */
/* {{{ smoothing */
/* {{{ median(in,i,j,x_size) */
uchar median(in,i,j,x_size)
uchar *in;
int i, j, x_size;
{
int p[8],k,l,tmp;
p[0]=in[(i-1)*x_size+j-1];
p[1]=in[(i-1)*x_size+j ];
p[2]=in[(i-1)*x_size+j+1];
p[3]=in[(i )*x_size+j-1];
p[4]=in[(i )*x_size+j+1];
p[5]=in[(i+1)*x_size+j-1];
p[6]=in[(i+1)*x_size+j ];
p[7]=in[(i+1)*x_size+j+1];
for(k=0; k<7; k++)
for(l=0; l<(7-k); l++)
if (p[l]>p[l+1])
{
tmp=p[l]; p[l]=p[l+1]; p[l+1]=tmp;
}
return( (p[3]+p[4]) / 2 );
}
/* }}} */
/* {{{ enlarge(in,tmp_image,x_size,y_size,border) */
/* this enlarges "in" so that borders can be dealt with easily */
enlarge(in,tmp_image,x_size,y_size,border)
uchar **in;
uchar *tmp_image;
int *x_size, *y_size, border;
{
int i, j;
for(i=0; i<*y_size; i++) /* copy *in into tmp_image */
memcpy(tmp_image+(i+border)*(*x_size+2*border)+border, *in+i* *x_size, *x_size);
for(i=0; i<border; i++) /* copy top and bottom rows; invert as many as necessary */
{
memcpy(tmp_image+(border-1-i)*(*x_size+2*border)+border,*in+i* *x_size,*x_size);
memcpy(tmp_image+(*y_size+border+i)*(*x_size+2*border)+border,*in+(*y_size-i-1)* *x_size,*x_size);
}
for(i=0; i<border; i++) /* copy left and right columns */
for(j=0; j<*y_size+2*border; j++)
{
tmp_image[j*(*x_size+2*border)+border-1-i]=tmp_image[j*(*x_size+2*border)+border+i];
tmp_image[j*(*x_size+2*border)+ *x_size+border+i]=tmp_image[j*(*x_size+2*border)+ *x_size+border-1-i];
}
*x_size+=2*border; /* alter image size */
*y_size+=2*border;
*in=tmp_image; /* repoint in */
}
/* }}} */
/* {{{ void susan_smoothing(three_by_three,in,dt,x_size,y_size,bp) */
void susan_smoothing(three_by_three,in,dt,x_size,y_size,bp)
int three_by_three, x_size, y_size;
uchar *in, *bp;
float dt;
{
/* {{{ vars */
float temp;
int n_max, increment, mask_size,
i,j,x,y,area,brightness,tmp,centre;
uchar *ip, *dp, *dpt, *cp, *out=in,
*tmp_image;
TOTAL_TYPE total;
/* }}} */
/* {{{ setup larger image and border sizes */
if (three_by_three==0)
mask_size = ((int)(1.5 * dt)) + 1;
else
mask_size = 1;
total=0.1; /* test for total's type */
if ( (dt>15) && (total==0) )
{
printf("Distance_thresh (%f) too big for integer arithmetic.\n",dt);
printf("Either reduce it to <=15 or recompile with variable \"total\"\n");
printf("as a float: see top \"defines\" section.\n");
exit(0);
}
if ( (2*mask_size+1>x_size) || (2*mask_size+1>y_size) )
{
printf("Mask size (1.5*distance_thresh+1=%d) too big for image (%dx%d).\n",mask_size,x_size,y_size);
exit(0);
}
tmp_image = (uchar *) malloc( (x_size+mask_size*2) * (y_size+mask_size*2) );
enlarge(&in,tmp_image,&x_size,&y_size,mask_size);
/* }}} */
if (three_by_three==0)
{ /* large Gaussian masks */
/* {{{ setup distance lut */
n_max = (mask_size*2) + 1;
increment = x_size - n_max;
dp = (unsigned char *)malloc(n_max*n_max);
dpt = dp;
temp = -(dt*dt);
for(i=-mask_size; i<=mask_size; i++)
for(j=-mask_size; j<=mask_size; j++)
{
x = (int) (100.0 * exp( ((float)((i*i)+(j*j))) / temp ));
*dpt++ = (unsigned char)x;
}
/* }}} */
/* {{{ main section */
for (i=mask_size;i<y_size-mask_size;i++)
{
for (j=mask_size;j<x_size-mask_size;j++)
{
area = 0;
total = 0;
dpt = dp;
ip = in + ((i-mask_size)*x_size) + j - mask_size;
centre = in[i*x_size+j];
cp = bp + centre;
for(y=-mask_size; y<=mask_size; y++)
{
for(x=-mask_size; x<=mask_size; x++)
{
brightness = *ip++;
tmp = *dpt++ * *(cp-brightness);
area += tmp;
total += tmp * brightness;
}
ip += increment;
}
tmp = area-10000;
if (tmp==0)
*out++=median(in,i,j,x_size);
else
*out++=((total-(centre*10000))/tmp);
}
}
/* }}} */
}
else
{ /* 3x3 constant mask */
/* {{{ main section */
for (i=1;i<y_size-1;i++)
{
for (j=1;j<x_size-1;j++)
{
area = 0;
total = 0;
ip = in + ((i-1)*x_size) + j - 1;
centre = in[i*x_size+j];
cp = bp + centre;
brightness=*ip++; tmp=*(cp-brightness); area += tmp; total += tmp * brightness;
brightness=*ip++; tmp=*(cp-brightness); area += tmp; total += tmp * brightness;
brightness=*ip; tmp=*(cp-brightness); area += tmp; total += tmp * brightness;
ip += x_size-2;
brightness=*ip++; tmp=*(cp-brightness); area += tmp; total += tmp * brightness;
brightness=*ip++; tmp=*(cp-brightness); area += tmp; total += tmp * brightness;
brightness=*ip; tmp=*(cp-brightness); area += tmp; total += tmp * brightness;
ip += x_size-2;
brightness=*ip++; tmp=*(cp-brightness); area += tmp; total += tmp * brightness;
brightness=*ip++; tmp=*(cp-brightness); area += tmp; total += tmp * brightness;
brightness=*ip; tmp=*(cp-brightness); area += tmp; total += tmp * brightness;
tmp = area-100;
if (tmp==0)
*out++=median(in,i,j,x_size);
else
*out++=(total-(centre*100))/tmp;
}
}
/* }}} */
}
}
/* }}} */
/* }}} */
/* {{{ edges */
/* {{{ edge_draw(in,corner_list,drawing_mode) */
edge_draw(in,mid,x_size,y_size,drawing_mode)
uchar *in, *mid;
int x_size, y_size, drawing_mode;
{
int i;
uchar *inp, *midp;
if (drawing_mode==0)
{
/* mark 3x3 white block around each edge point */
midp=mid;
for (i=0; i<x_size*y_size; i++)
{
if (*midp<8)
{
inp = in + (midp - mid) - x_size - 1;
*inp++=255; *inp++=255; *inp=255; inp+=x_size-2;
*inp++=255; *inp++; *inp=255; inp+=x_size-2;
*inp++=255; *inp++=255; *inp=255;
}
midp++;
}
}
/* now mark 1 black pixel at each edge point */
midp=mid;
for (i=0; i<x_size*y_size; i++)
{
if (*midp<8)
*(in + (midp - mid)) = 0;
midp++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -