Exemple #1
0
        public static ArgusColor GetDominantColor(this Surface surface, ArgusColor minValue, ArgusColor maxValue, byte maxDeviation = 10, int maxIterations = 100, Rectangle[] rois = null, Effect callingEffect = null)
        {
            Pair <ArgusColor, ArgusColor> meanAndDev = surface.GetMeanAndStdDeviation(minValue, maxValue, rois, callingEffect);
            ArgusColor dev   = meanAndDev.Second;
            ArgusColor mean  = meanAndDev.First;
            int        count = 1;

            while (!(callingEffect?.IsCancelRequested ?? false) && count < maxIterations && (dev.R > maxDeviation || dev.G > maxDeviation || dev.B > maxDeviation || dev.A > maxDeviation))
            {
                minValue.R = (byte)Math.Max(0, mean.R - dev.R);
                minValue.G = (byte)Math.Max(0, mean.G - dev.G);
                minValue.B = (byte)Math.Max(0, mean.B - dev.B);
                minValue.A = (byte)Math.Max(0, mean.A - dev.A);

                maxValue.R = (byte)Math.Min(255, mean.R + dev.R);
                maxValue.G = (byte)Math.Min(255, mean.G + dev.G);
                maxValue.B = (byte)Math.Min(255, mean.B + dev.B);
                maxValue.A = (byte)Math.Min(255, mean.A + dev.A);

                meanAndDev = surface.GetMeanAndStdDeviation(minValue, maxValue, rois, callingEffect);
                mean       = meanAndDev.First;
                dev        = meanAndDev.Second;
                count++;
            }
            return(mean);
        }
Exemple #2
0
        /// <summary>
        /// Implements: https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Computing_shifted_data
        /// </summary>
        /// <param name="surface"></param>
        /// <param name="rects"></param>
        /// <param name="stdDeviation"></param>
        /// <returns>The mean color.</returns>
        public static Pair <ArgusColor, ArgusColor> GetMeanAndStdDeviation(this Surface surface, ArgusColor minValue, ArgusColor maxValue, Rectangle[] rois = null, Effect callingEffect = null)
        {
            rois = rois ?? new Rectangle[] { surface.Bounds };
            object    _lock  = new object();
            double    r_tot  = 0;
            double    g_tot  = 0;
            double    b_tot  = 0;
            double    a_tot  = 0;
            double    r2_tot = 0;
            double    g2_tot = 0;
            double    b2_tot = 0;
            double    a2_tot = 0;
            long      n_tot  = 0;
            ColorBgra K      = surface[rois[0].Left, rois[0].Top];

            Parallel.For(0, rois.Length, (i, loopStateI) =>
            {
                if (callingEffect?.IsCancelRequested ?? false)
                {
                    loopStateI.Stop();
                    return;
                }
                Rectangle rect = rois[i];
                Parallel.For(rect.Top, rect.Bottom, (y, loopStateY) =>
                {
                    if (callingEffect?.IsCancelRequested ?? false)
                    {
                        loopStateY.Stop();
                        return;
                    }
                    double r  = 0;
                    double g  = 0;
                    double b  = 0;
                    double a  = 0;
                    double r2 = 0;
                    double g2 = 0;
                    double b2 = 0;
                    double a2 = 0;
                    long n    = 0;
                    for (int x = rect.Left; x < rect.Right; x++)
                    {
                        ColorBgra c = surface[x, y];
                        if (c.R < minValue.R || c.R > maxValue.R)
                        {
                            continue;
                        }

                        if (c.G < minValue.G || c.G > maxValue.G)
                        {
                            continue;
                        }

                        if (c.B < minValue.B || c.B > maxValue.B)
                        {
                            continue;
                        }

                        if (c.A < minValue.A || c.A > maxValue.A)
                        {
                            continue;
                        }

                        int v = c.R - K.R;
                        r    += v;
                        r2   += v * v;

                        v   = c.G - K.G;
                        g  += v;
                        g2 += v * v;

                        v   = c.B - K.B;
                        b  += v;
                        b2 += v * v;

                        v   = c.A - K.A;
                        a  += v;
                        a2 += v * v;

                        n++;
                    }
                    lock (_lock)
                    {
                        r_tot  += r;
                        r2_tot += r2;
                        g_tot  += g;
                        g2_tot += g2;
                        b_tot  += b;
                        b2_tot += b2;
                        a_tot  += a;
                        a2_tot += a2;
                        n_tot  += n;
                    }
                });
            });

            n_tot = Math.Max(1, n_tot);
            var mean = new ArgusColor
            {
                R = (byte)Math.Round(r_tot / n_tot + K.R),
                G = (byte)Math.Round(g_tot / n_tot + K.G),
                B = (byte)Math.Round(b_tot / n_tot + K.B),
                A = (byte)Math.Round(a_tot / n_tot + K.A)
            };

            double devR = Math.Round(Math.Sqrt((r2_tot - (r_tot * r_tot / n_tot)) / n_tot));
            double devG = Math.Round(Math.Sqrt((g2_tot - (g_tot * g_tot / n_tot)) / n_tot));
            double devB = Math.Round(Math.Sqrt((b2_tot - (b_tot * b_tot / n_tot)) / n_tot));
            double devA = Math.Round(Math.Sqrt((a2_tot - (a_tot * a_tot / n_tot)) / n_tot));
            var    dev  = new ArgusColor((byte)devR, (byte)devG, (byte)devB, (byte)devA);

            return(new Pair <ArgusColor, ArgusColor>(mean, dev));
        }
Exemple #3
0
 public static async Task <ArgusColor> GetDominantColorAsync(this Surface surface, ArgusColor minValue, ArgusColor maxValue, byte maxDeviation = 10, int maxIterations = 100, Rectangle[] rois = null, Effect callingEffect = null)
 {
     return(await Task.Run(() => { return surface.GetDominantColor(minValue, maxValue, maxDeviation, maxIterations, rois, callingEffect); }));
 }
Exemple #4
0
 public static async Task <Pair <ArgusColor, ArgusColor> > GetMeanAndStdDeviationAsync(this Surface surface, ArgusColor minValue, ArgusColor maxValue, Rectangle[] rois = null, Effect callingEffect = null)
 {
     return(await Task.Run(() => { return surface.GetMeanAndStdDeviation(minValue, maxValue, rois, callingEffect); }));
 }