Exemple #1
0
 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;
}