Esempio n. 1
0
        public static Func<byte, byte, byte, Pixel> Otsu(PNM image)
        {
            double[] histogram = image.GetHistogramLuminosity();
            object compareLock = new object();
            double[] variances = new double[256];
            Parallel.For(0, 256, i =>
            {
                double[] background = histogram.Take(i).ToArray();
                double[] foreground = histogram.Skip(i).ToArray();
                double backgroundWeight = background.Sum();
                double foregroundWeight = 1 - backgroundWeight;
                double backgroundMean = background.Length == 0 ? 0 : background.Select((d, idx) => d * idx).Average();
                double foregroundMean = foreground.Select((d, idx) => d * idx).Average();
                double variance = backgroundWeight * foregroundWeight * Math.Pow(foregroundMean - backgroundMean, 2);
                variances[i] = variance;
            });
            byte threshold = 0;
            double maxVariance = Double.NegativeInfinity;
            for(int i =0; i< 256;i++)
            {
                if (variances[i] > maxVariance)
                {
                    maxVariance = variances[i];
                    threshold = (byte)i;
                }
            }

            return (r, g, b) => Plain(r, g, b, threshold);
        }
Esempio n. 2
0
        public static Func <byte, byte, byte, Pixel> Otsu(PNM image)
        {
            double[] histogram   = image.GetHistogramLuminosity();
            object   compareLock = new object();

            double[] variances = new double[256];
            Parallel.For(0, 256, i =>
            {
                double[] background     = histogram.Take(i).ToArray();
                double[] foreground     = histogram.Skip(i).ToArray();
                double backgroundWeight = background.Sum();
                double foregroundWeight = 1 - backgroundWeight;
                double backgroundMean   = background.Length == 0 ? 0 : background.Select((d, idx) => d * idx).Average();
                double foregroundMean   = foreground.Select((d, idx) => d * idx).Average();
                double variance         = backgroundWeight * foregroundWeight * Math.Pow(foregroundMean - backgroundMean, 2);
                variances[i]            = variance;
            });
            byte   threshold   = 0;
            double maxVariance = Double.NegativeInfinity;

            for (int i = 0; i < 256; i++)
            {
                if (variances[i] > maxVariance)
                {
                    maxVariance = variances[i];
                    threshold   = (byte)i;
                }
            }

            return((r, g, b) => Plain(r, g, b, threshold));
        }
Esempio n. 3
0
        public static Func <byte, byte, byte, Pixel> Triangle(PNM image)
        {
            double[] histogram = image.GetHistogramLuminosity();
            int      minx = 0, maxx = 0;
            double   minValue = Double.PositiveInfinity, maxValue = Double.NegativeInfinity;

            // find min max
            for (int i = 0; i < 256; i++)
            {
                if (histogram[i] >= maxValue)
                {
                    maxValue = histogram[i];
                    maxx     = i;
                }
                if (histogram[i] < minValue)
                {
                    minValue = histogram[i];
                    minx     = i;
                }
            }
            // find line
            double a = -(maxValue - minValue) / (maxx - minx);
            double b = 1;
            double c = (minx * (maxValue - minValue) / (maxx - minx)) - minValue;

            // find the furthest point
            double distance, maxDistance = Double.NegativeInfinity;
            byte   threshold = 0;
            int    from, to;

            if (minx < maxx)
            {
                from = minx + 1;
                to   = maxx;
            }
            else
            {
                to   = minx + 1;
                from = maxx;
            }
            for (int i = from; i < to; i++)
            {
                distance = PointToLineDistance(a, b, c, i, histogram[i]);
                if (distance >= maxDistance)
                {
                    maxDistance = distance;
                    threshold   = (byte)i;
                }
            }
            return((pr, pg, pb) => Plain(pr, pg, pb, threshold));
        }
Esempio n. 4
0
        public static Func<byte, byte, byte, Pixel> Triangle(PNM image)
        {
            double[] histogram = image.GetHistogramLuminosity();
            int minx=0, maxx=0;
            double minValue = Double.PositiveInfinity, maxValue = Double.NegativeInfinity;
            // find min max
            for (int i = 0; i < 256; i++)
            {
                if (histogram[i] >= maxValue)
                {
                    maxValue = histogram[i];
                    maxx = i;
                }
                if (histogram[i] < minValue)
                {
                    minValue = histogram[i];
                    minx = i;
                }
            }
            // find line
            double a = -(maxValue - minValue) / (maxx - minx);
            double b = 1;
            double c = (minx * (maxValue - minValue) / (maxx - minx)) - minValue;

            // find the furthest point
            double distance, maxDistance = Double.NegativeInfinity;
            byte threshold = 0;
            int from, to;
            if (minx < maxx)
            {
                from = minx + 1;
                to = maxx;
            }
            else
            {
                to = minx + 1;
                from = maxx;
            }
            for(int i = from; i< to; i++)
            {
                distance = PointToLineDistance(a,b,c,i,histogram[i]);
                if (distance >= maxDistance)
                {
                    maxDistance = distance;
                    threshold = (byte)i;
                }
            }
            return (pr, pg, pb) => Plain(pr, pg, pb, threshold);
        }
Esempio n. 5
0
        // Kapur's method
        public static Func <byte, byte, byte, Pixel> Entropy(PNM image)
        {
            double[] histogram  = image.GetHistogramLuminosity();
            double   entropySum = Double.NegativeInfinity;
            int      threshold  = 0;

            for (int i = 0; i < 256; i++)
            {
                double[] background = histogram.Take(i + 1).ToArray();
                double[] foreground = histogram.Skip(i + 1).ToArray();
                double   sumB       = background.Sum();
                double   sumF       = foreground.Sum();
                double   entropyB   = -background.Select(p =>
                {
                    if (p == 0)
                    {
                        return(0);
                    }
                    return((p / sumB) * Math.Log(p / sumB, 2));
                })
                                      .Sum();
                double entropyF = -foreground.Select(p =>
                {
                    if (p == 0)
                    {
                        return(0);
                    }
                    return((p / (1 - sumB)) * Math.Log(p / (1 - sumB), 2));
                })
                                  .Sum();
                double sum = entropyB + entropyF;
                if (sum > entropySum)
                {
                    entropySum = sum;
                    threshold  = i;
                }
            }

            return((r, g, b) => Plain(r, g, b, (byte)threshold));
        }
Esempio n. 6
0
        // Kapur's method
        public static Func<byte, byte, byte, Pixel> Entropy(PNM image)
        {
            double[] histogram = image.GetHistogramLuminosity();
            double entropySum = Double.NegativeInfinity;
            int threshold = 0;
            for (int i = 0; i < 256; i++)
            {
                double[]  background = histogram.Take(i + 1).ToArray();
                double[]  foreground = histogram.Skip(i + 1).ToArray();
                double sumB = background.Sum();
                double sumF = foreground.Sum();
                double entropyB = -background.Select(p =>
                    {
                        if(p == 0)
                            return 0;
                        return (p / sumB) * Math.Log(p / sumB, 2);
                    })
                    .Sum();
                double entropyF = -foreground.Select(p => 
                    {
                        if(p == 0)
                            return 0;
                        return (p / (1 - sumB)) * Math.Log(p / (1 - sumB), 2);
                    })
                    .Sum();
                double sum = entropyB + entropyF;
                if (sum > entropySum)
                {
                    entropySum = sum;
                    threshold = i;
                }
            }

            return (r, g, b) => Plain(r, g, b, (byte)threshold);
        }