private CvImage DrawCannyEdges(Bitmap sobel_x, Bitmap sobel_y)
        {
            CvImage image = new CvImage();

            int[,] edge_direction = new int[sobel_x.Width, sobel_x.Height];
            int[,] edge_mag       = new int[sobel_x.Width, sobel_x.Height];
            int[,] non_max        = new int[sobel_x.Width, sobel_x.Height];
            int kernWid    = GAUSSIAN_FILTER.MATRIX.GetLength(1);
            int kernHei    = GAUSSIAN_FILTER.MATRIX.GetLength(0);
            int kernOffset = (kernWid - 1) / 2;

            for (int wid_ic = kernOffset; wid_ic < sobel_x.Width - kernOffset; wid_ic++)
            {
                for (int hei_ic = kernOffset; hei_ic < sobel_x.Height - kernOffset; hei_ic++)
                {
                    var pixel_y       = sobel_y.GetPixel(wid_ic, hei_ic);
                    var pixel_x       = sobel_x.GetPixel(wid_ic, hei_ic);
                    var mag_y         = PixelMath.pixelMag(pixel_y);
                    var mag_x         = PixelMath.pixelMag(pixel_y);
                    var edge_strength = mag_y + mag_x;

                    edge_mag[wid_ic, hei_ic] = (int)edge_strength;
                    non_max[wid_ic, hei_ic]  = (int)edge_strength;
                }
            }

            for (int wid_ic = kernWid; wid_ic < sobel_x.Width - kernWid; wid_ic++)
            {
                for (int hei_ic = kernHei; hei_ic < sobel_x.Height - kernHei; hei_ic++)
                {
                    var    pixel_y     = sobel_y.GetPixel(wid_ic, hei_ic);
                    var    pixel_x     = sobel_x.GetPixel(wid_ic, hei_ic);
                    var    mag_y       = PixelMath.pixelMag(pixel_y);
                    var    mag_x       = PixelMath.pixelMag(pixel_y);
                    var    current_mag = edge_mag[wid_ic, hei_ic];
                    double theta       = current_mag != 0 ? Math.Atan2(mag_y, mag_x) : 90;

                    //CHO_ACTIVE: clean this up
                    //near horizontal
                    if ((theta > -22.5 && theta <= 22.5) ||
                        (theta > 157.5) ||
                        (theta < -157.5))
                    {
                        if ((current_mag < edge_mag[wid_ic, hei_ic + 1]) ||
                            (current_mag < edge_mag[wid_ic, hei_ic - 1]))
                        {
                            non_max[wid_ic, hei_ic] = 0;
                        }
                    }
                    // +45 degree
                    else if ((theta > 22.5 && theta <= 67.5) ||
                             (theta <= -67.5 && theta > -22.5))
                    {
                        if ((current_mag < edge_mag[wid_ic + 1, hei_ic + 1]) ||
                            (current_mag < edge_mag[wid_ic - 1, hei_ic - 1]))
                        {
                            non_max[wid_ic, hei_ic] = 0;
                        }
                    }
                    //vertical
                    else if ((theta > 67.5 && theta <= 112.5) ||
                             (theta <= -67.5 && theta > -112.5))
                    {
                        if ((current_mag < edge_mag[wid_ic + 1, hei_ic]) ||
                            (current_mag < edge_mag[wid_ic - 1, hei_ic]))
                        {
                            non_max[wid_ic, hei_ic] = 0;
                        }
                    }
                    // +135 degree
                    else
                    {
                        if ((current_mag < edge_mag[wid_ic + 1, hei_ic - 1]) ||
                            (current_mag < edge_mag[wid_ic - 1, hei_ic + 1]))
                        {
                            non_max[wid_ic, hei_ic] = 0;
                        }
                    }

                    edge_direction[wid_ic, hei_ic] = (int)theta;
                }
            }

            image.bitmap = TraceCannyEdge(non_max);

            return(image);
        }