/* Compute the interpolated value of the gradient magnitude */
if ( (g > (xx*g1 + (yy-xx)*g2)) &&
(g > (xx*g3 + (yy-xx)*g4)) )
{
if (g*MAG_SCALE <= 255)
mag->data[i][j] = (unsigned char)(g*MAG_SCALE);
else
mag->data[i][j] = 255;
ori->data[i][j] = atan2 (yc, xc) * ORI_SCALE;
} else
{
mag->data[i][j] = 0;
ori->data[i][j] = 0;
}
}
}
}
void estimate_thresh (IMAGE mag, int *hi, int *low)
{
int i,j,k, hist[256], count;
/* Build a histogram of the magnitude image. */
for (k=0; k<256; k++) hist[k] = 0;
for (i=WIDTH; i<mag->info->nr-WIDTH; i++)
for (j=WIDTH; j<mag->info->nc-WIDTH; j++)
hist[mag->data[i][j]]++;
/* The high threshold should be > 80 or 90% of the pixels
j = (int)(ratio*mag->info->nr*mag->info->nc);
*/
j = mag->info->nr;
if (j<mag->info->nc) j = mag->info->nc;
j = (int)(0.9*j);
k = 255;
count = hist[255];
while (count < j)
{
k--;
if (k<0) break;
count += hist[k];
}
*hi = k;
/* Convolution of source image with a Gaussian in X and Y directions */
seperable_convolution (im, gau, width, smx, smy);
/* Now convolve smoothed data with a derivative */
printf ("Convolution with the derivative of a Gaussian...\n");
dx = f2d (im->info->nr, im->info->nc);
dxy_seperable_convolution (smx, im->info->nr, im->info->nc,
dgau, width, dx, 1);
free(smx[0]); free(smx);
/* Create an image of the norm of dx,dy */
for (i=0; i<im->info->nr; i++)
for (j=0; j<im->info->nc; j++)
{
z = norm (dx[i][j], dy[i][j]);
mag->data[i][j] = (unsigned char)(z*MAG_SCALE);
}
/* Non-maximum suppression - edge pixels should be a local max */
if (sigma == 0) return 0.0;
xx = (float)exp((double) ((-x*x)/(2*sigma*sigma)));
return xx;
}
float meanGauss (float x, float sigma)
{
float z;
z = (gauss(x,sigma)+gauss(x+0.5,sigma)+gauss(x-0.5,sigma))/3.0;
z = z/(PI*2.0*sigma*sigma);
return z;
}
/* First derivative of Gaussian */
float dGauss (float x, float sigma)
{
return -x/(sigma*sigma) * gauss(x, sigma);
}
/* HYSTERESIS thersholding of edge pixels. Starting at pixels with a
value greater than the HIGH threshold, trace a connected sequence
of pixels that have a value greater than the LOW threhsold. */
void hysteresis (int high, int low, IMAGE im, IMAGE mag, IMAGE oriim)
{
int i,j,k;
printf ("Beginning hysteresis thresholding...\n");
for (i=0; i<im->info->nr; i++)
for (j=0; j<im->info->nc; j++)
im->data[i][j] = 0;
if (high<low)
{
estimate_thresh (mag, &high, &low);
printf ("Hysteresis thresholds (from image): HI %d LOW %D\n",
high, low);
}
/* For each edge with a magnitude above the high threshold, begin
tracing edge pixels that are above the low threshold. */
for (i=0; i<im->info->nr; i++)
for (j=0; j<im->info->nc; j++)
if (mag->data[i][j] >= high)
trace (i, j, low, im, mag, oriim);
/* Make the edge black (to be the same as the other methods) */
for (i=0; i<im->info->nr; i++)
for (j=0; j<im->info->nc; j++)
if (im->data[i][j] == 0) im->data[i][j] = 255;
else im->data[i][j] = 0;
}