void canny(unsigned char *readImage, unsigned char **writeImage, float gauSigma, float edgeT, float backT, char *composedFilename) { float *radiansImg; short int *gsmoothImage, *deltaX, *deltaY, *magnitude; unsigned char *nms; // FILE *fp; (*writeImage) = (unsigned char *) calloc(HEIGHT*WIDTH, sizeof (unsigned char)); if (VERBOSE) printf("Gaussian smoothing ...\n"); gaussianSmooth(readImage, &gsmoothImage, gauSigma); if (VERBOSE) printf("Computing the X and Y first derivaties.\n"); derrXY(gsmoothImage, &deltaX, &deltaY); radianDir(deltaX, deltaY, &radiansImg, -1, -1); if (VERBOSE) printf("Computing the magnitude of the gradient.\n"); magXY(deltaX, deltaY, &magnitude); if (VERBOSE) printf("Doing the non-maximal suppression.\n"); nms = (unsigned char *) calloc(HEIGHT*WIDTH, sizeof (unsigned char)); nonMaxSup(magnitude, deltaX, deltaY, nms); if (VERBOSE) printf("Doing hysteresis thresholding.\n"); applyHysteresis(magnitude, nms, edgeT, backT, *writeImage); free(gsmoothImage); free(deltaX); free(deltaY); free(magnitude); free(nms); }
bool ImageEdgeDetectionBase<T, U>::detectEdges(float iSigma, /* Standard deviation of the gaussian kernel. */ float iTlow, /* Fraction of the high threshold in hysteresis. */ float iThigh, PGCore::Image<T> *iInImage, PGCore::Image<U> *oEdgeImage //must be allocated outside ) { if (!iInImage || !oEdgeImage) return false; //iOutImage = iInImage; //char composedfname[128]; /* Name of the output "direction" image */ T *image = (T *)iInImage->GetBuffer(); /* The input image */ U *edge = (U *)oEdgeImage->GetBuffer(); /* The output edge image */ //int rows , cols; /* The dimensions of the image. */ //float sigma, /* Standard deviation of the gaussian kernel. */ // tlow, /* Fraction of the high threshold in hysteresis. */ // thigh; /* High hysteresis threshold control. The actual threshold is the (100 * thigh) percentage point in the histogram of the magnitude of the gradient image that passes non-maximal suppression. */ /**************************************************************************** * Get the command line arguments. ****************************************************************************/ //infilename = argv[1]; //sigma = iSigma;//atof(argv[2]); //tlow = iTlow;//atof(argv[3]); //thigh = iThigh;//atof(argv[4]); long rows, cols; iInImage->GetDimensions(rows, cols); //rows = (int)lrows; //cols = (int)lcols; /**************************************************************************** * Perform the edge detection. All of the work takes place here. ****************************************************************************/ //void canny(unsigned char *image, int rows, int cols, float sigma, // float tlow, float thigh, unsigned char **edge, char *fname) //{ //FILE *fpdir=NULL; /* File to write the gradient image to. */ //U *nms; /* Points that are local maximal magnitude. */ T *smoothedim; /* The image after gaussian smoothing. */ T *delta_x, /* The first devivative image, x-direction. */ *delta_y, /* The first derivative image, y-direction. */ *magnitude; /* The magnitude of the gadient image. */ //int r, c, pos; //float *dir_radians=NULL; /* Gradient direction image. */ #ifdef _DEBUG PGAlgs::DumpImageAsPGM(*iInImage, std::string("C:\\Tmp\\Dump\\OriginalImage.pgm")); #endif /**************************************************************************** * Perform gaussian smoothing on the image using the input standard * deviation. ****************************************************************************/ //if(0) printf("Smoothing the image using a gaussian kernel.\n"); //gaussian_smooth(image, rows, cols, sigma, &smoothedim); PGCore::Image<T> smoothedImage(rows, cols); PGCore::GaussianKernel<T, T> gausskernel(iSigma, 3); gausskernel.Convolve(*iInImage, smoothedImage); smoothedim = (T *)smoothedImage.GetBuffer(); #ifdef _DEBUG PGAlgs::DumpImageAsPGM(smoothedImage, std::string("C:\\Tmp\\Dump\\SmoothImage.pgm")); #endif /**************************************************************************** * Compute the first derivative in the x and y directions. ****************************************************************************/ //if(0) printf("Computing the X and Y first derivatives.\n"); //derrivative_x_y(smoothedim, rows, cols, &delta_x, &delta_y); PGCore::DerivativeOfGaussianKernel<T, T> derivOfGaussian(iSigma); PGCore::DiffOfGaussianKernel<T, T> dogFilter(iSigma+0.1f, iSigma); PGCore::Image<T> oImageDerivG(rows, cols), oImageDerivGX(rows, cols), oImageDerivGY(rows, cols); // X gradient if (1) { //gausskernel.Convolve1D_Y(smoothedImage, oImageDerivG); //derivOfGaussian.Convolve1D_X(oImageDerivG, oImageDerivGX); dogFilter.Convolve1D_X(smoothedImage, oImageDerivGX); delta_x = (T *)oImageDerivGX.GetBuffer(); #ifdef _DEBUG PGAlgs::DumpImageAsPGM(oImageDerivGX, std::string("C:\\Tmp\\Dump\\GradientX.pgm")); #endif } // Y gradient if (1) { //gausskernel.Convolve1D_X(smoothedImage, oImageDerivG); //derivOfGaussian.Convolve1D_Y(oImageDerivG, oImageDerivGY); dogFilter.Convolve1D_Y(smoothedImage, oImageDerivGY); delta_y = (T *)oImageDerivGY.GetBuffer(); #ifdef _DEBUG PGAlgs::DumpImageAsPGM(oImageDerivGY, std::string("C:\\Tmp\\Dump\\GradientY.pgm")); #endif } /**************************************************************************** * Compute the magnitude of the gradient. ****************************************************************************/ //if(0) printf("Computing the magnitude of the gradient.\n"); //magnitude_x_y(delta_x, delta_y, rows, cols, &magnitude); PGCore::Image<T> gradientMagntudeImage(rows, cols); magnitude = (T *)gradientMagntudeImage.GetBuffer(); { long imgIter = 0; while (imgIter< rows*cols) { double inValX = *(delta_x+imgIter); double inValY = *(delta_y+imgIter); //double inVal = fabs(inValX) + fabs(inValY);//inValX>inValY ? inValX : inValY; double inVal = sqrt((inValX)*(inValX) + (inValY)*(inValY));//inValX>inValY ? inValX : inValY; T outVal = (T)((inVal + 0.5f)); *(magnitude+imgIter) = outVal; imgIter++; } } #ifdef _DEBUG PGAlgs::DumpImageAsPGM(gradientMagntudeImage, std::string("C:\\Tmp\\Dump\\GradientMagnitude.pgm")); #endif /**************************************************************************** * Perform non-maximal suppression. ****************************************************************************/ PGCore::Image<U> nonMaxSuppressedImage(rows, cols); U* nms = (U *)nonMaxSuppressedImage.GetBuffer(); if(!nms) { return false; } bool rv = nonMaximumSuppression(magnitude, delta_x, delta_y, rows, cols, nms); if (!rv) return false; #ifdef _DEBUG PGAlgs::DumpImageAsPGM(nonMaxSuppressedImage, std::string("C:\\Tmp\\Dump\\NonMaxSuppressed.pgm")); #endif /**************************************************************************** * Use hysteresis to mark the edge pixels. ****************************************************************************/ //if(0) printf("Doing hysteresis thresholding.\n"); /* if((*edge=(unsigned char *)calloc(rows*cols,sizeof(unsigned char))) ==NULL){ fprintf(stderr, "Error allocating the edge image.\n"); exit(1); }*/ //error in here somewhere rv = applyHysteresis(magnitude, nms, rows, cols, iTlow, iThigh, edge); if (!rv) { return false; } #ifdef _DEBUG PGAlgs::DumpImageAsPGM(*oEdgeImage, std::string("C:\\Tmp\\Dump\\Edges.pgm")); #endif /**************************************************************************** * Free all of the memory that we allocated except for the edge image that * is still being used to store out result. ****************************************************************************/ //free(smoothedim); //free(delta_x); //free(delta_y); //free(magnitude); //free(nms); return rv; }