Sign in to follow this  
Followers 0
AnthonyScoffler

Fuzzy Edge Detector

2 posts in this topic

Overview
This is based on my previous edge detector, which went from top left to bottom right and checked each pixel to see if it contrasted with another pixel by some degree in the chosen channels. The pixel has a magnitude and angle, but the angle is randomized instead of being set as it was with my last edge detector. This effect now also has a quality setting to determine the number of passes it makes per-pixel. As a result, it hits all angles in a 'fuzzy' way, and may require multiple passes to get smooth edges.

 
6lb0Ps9.png

Rx1JUhX.png

JNZU7LV.png
 
Purpose and Applications
This is used to make outlines that reduce the data needed to analyze an image, deducing areas of interest, and enabling the use of many interesting edge-based effects. I used it to make sharp or stylized outlines as needed. You can also get the edge data alone as white-on-black, then select the edge pixels and do as you wish with it. For programmers, it's easy to add an effect.  
 

Options 
Sampling range: the magnitude for the vector (the other component is the angle) that determines how thick edges are.
 
Quality: The number of passes to make.
 
Background color: This selects how the background appears. It may be black, transparent (replacing the image), or transparent (on top of the image). The foreground is black unless the background is black, in which case the foreground is white for visibility. You can always invert the colors later.
Intensity threshold: All thresholds are values that describe how 'different' pixels have to be to be detected as edges. This one deals with intensity.
 
Red, green, blue, and alpha thresholds: These deal with the rgba channels. See above.
 
Remarks
Located in the Stylize folder. Using blurs before edge detection might improve accuracy.
 
Source


#region UICode

double Amount1 = 1; // [-10,10] Sampling range

int Amount2 = 3; // [1,10] Quality

byte Amount3 = 0; // Background Color|Black|Transparent, no image|Transparent, with image

double Amount4 = 0.1; // [0,1] Intensity threshold

double Amount5 = 255; // [0,255] Red threshold

double Amount6 = 255; // [0,255] Green threshold

double Amount7 = 255; // [0,255] Blue threshold

double Amount8 = 255; // [0,255] Alpha threshold

#endregion
void Render(Surface dst, Surface src, Rectangle rect)

{ 

    //Creates variables to store the colors.

    ColorBgra CurrentPixel, Col1, Col2;

    CurrentPixel = ColorBgra.White;

    Random rng = new Random();

   

    //Stores a list of all edges detected

    List<int> edgePixelsX = new List<int>();

    List<int> edgePixelsY = new List<int>();

   

    //The for loops iterate through all pixels.

    for (float y = rect.Top; y < rect.Bottom; y++)

    {

        //Cancels by user request.

        if (IsCancelRequested)

        {

            return;

        }

        for (float x = rect.Left; x < rect.Right; x++)

        {

            //The number of samplings taken.       

            for (int i = 0; i < Amount2; i++)

            {

                //Sets the value of the current pixel to be transparent or black.

                //The pixel color will later become white if an edge is detected.

                CurrentPixel = src[(int)x,(int)y];

                   

                double magX = Math.Cos(rng.NextDouble() * 2 * Math.PI) * Amount1;

                double magY = Math.Sin(rng.NextDouble() * 2 * Math.PI) * Amount1;

               

                //Gets the intensities of the pixels.

                Col1 = src.GetBilinearSampleClamped(x, y);

                Col2 = src.GetBilinearSampleClamped(x + (float)magX, y + (float)magY);

               

                if (Amount4 < 1)

                {               

                    //The intensity threshold has been reached.

                    if (Math.Abs(Col1.GetIntensity()- Col2.GetIntensity()) > Amount4)

                    {

                        edgePixelsX.Add((int)x);

                        edgePixelsY.Add((int)y);

                    }

                }

                //If red is being calculated.

                if (Amount5 < 255)

                {

                    //The redness threshold has been reached.

                    if (Math.Abs(Col1.R - Col2.R) > Amount5)

                    {

                        edgePixelsX.Add((int)x);

                        edgePixelsY.Add((int)y);

                    }

                }

                //If green is being calculated.

                if (Amount6 < 255)

                {

                    //The green-ness threshold has been reached.

                    if (Math.Abs(Col1.G - Col2.G) > Amount6)

                    {

                        edgePixelsX.Add((int)x);

                        edgePixelsY.Add((int)y);

                    }

                }

                //If blue is being calculated.

                if (Amount7 < 255)

                {

                    //The blueness threshold has been reached.

                    if (Math.Abs(Col1.B - Col2. > Amount7)

                    {

                        edgePixelsX.Add((int)x);

                        edgePixelsY.Add((int)y);

                    }

                }

                //If alpha is being calculated.

                if (Amount8 < 255)

                {

                    //The alpha threshold has been reached.

                    if (Math.Abs(Col1.A - Col2.A) > Amount8)

                    {

                        edgePixelsX.Add((int)x);

                        edgePixelsY.Add((int)y);

                    }

                }

           

                //Applies all changes to the destination surface.

                if (Amount3 == 0) //black

                {

                    dst[(int)x, (int)y] = ColorBgra.Black;

                }

                else if (Amount3 == 1) //transparent, no image

                {

                    dst[(int)x, (int)y] = ColorBgra.Transparent;

                }

                else if (Amount3 == 2) //transparent, with image

                {

                    dst[(int)x, (int)y] = CurrentPixel;

                }

            }

        }

    }

   

    //Iterates through each edge pixel and makes it white.

    for (int i = 0; i < edgePixelsX.Count; i++)

    {

        //Uses white pixels for black backgrounds.

        if (Amount3 == 0)

        {

            dst[edgePixelsX[i], edgePixelsY[i]] = ColorBgra.White;

        }

        //Uses black pixels for other backgrounds.

        else

        {

            dst[edgePixelsX[i], edgePixelsY[i]] = ColorBgra.Black;

        }

    }

}


Fuzzy Edge Detect.zip

Edited by AnthonyScoffler
2

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0