Exemplo n.º 1
0
        private Tuple <List <int>, List <int> > NeedleSearchArea(IMagickImage image, Gravity gravity)
        {
            var verticalMargin   = image.Height / 4;
            var horizontalMargin = image.Height / 3;

            switch (gravity)
            {
            case Gravity.South:
                return(Tuple.Create(
                           LinqExtensions.FromTo(image.Height - verticalMargin, image.Height).AsEnumerable().Reverse().ToList(),
                           LinqExtensions.FromTo(horizontalMargin, image.Width - horizontalMargin).OrderFromCenter().ToList()
                           ));

            case Gravity.North:
                return(Tuple.Create(
                           LinqExtensions.FromTo(0, verticalMargin).ToList(),
                           LinqExtensions.FromTo(horizontalMargin, image.Width - horizontalMargin).OrderFromCenter().ToList()
                           ));

            case Gravity.East:
                return(Tuple.Create(
                           LinqExtensions.FromTo(verticalMargin, image.Height - verticalMargin).OrderFromCenter().ToList(),
                           LinqExtensions.FromTo(image.Width - horizontalMargin, image.Width).AsEnumerable().Reverse().ToList()
                           ));

            case Gravity.West:
                return(Tuple.Create(
                           LinqExtensions.FromTo(verticalMargin, image.Height - verticalMargin).OrderFromCenter().ToList(),
                           LinqExtensions.FromTo(0, horizontalMargin).ToList()
                           ));

            default:
                throw new ArgumentException($"Unhandled gravity: {gravity}");
            }
        }
Exemplo n.º 2
0
        private List <List <System.Drawing.Color> > ToPixels(IMagickImage image)
        {
            var pixels = image.GetPixels();

            return(LinqExtensions.FromTo(0, image.Height).Select(y => LinqExtensions.FromTo(0, image.Width).Select(x => pixels.GetPixel(x, y).ToColor().ToColor()).ToList()).ToList());
        }
Exemplo n.º 3
0
        private NeedleResult FindHighEntropyStrip(IMagickImage image, Gravity gravity, double NeedleSize, StitchTask task)
        {
            IProgress <double> progress = task;
            var pixels = image.GetPixels();

            var t1 = DateTime.UtcNow;

            IEnumerable <int> rows    = null;
            IEnumerable <int> columns = null;

            Debug.Assert(image.Height > 1 && image.Width > 1, "Assumes non-empty image");
            Debug.Assert(image.Width >= NeedleSize, "Assumes image is at least as big as needle size");

            var searchArea = NeedleSearchArea(image, gravity);

            rows    = searchArea.Item1;
            columns = searchArea.Item2;

            var minY = rows.Min();
            var maxY = rows.Max();

            var minX            = columns.Min();
            var maxX            = columns.Max();
            var imageDimensions = Tuple.Create(image.Width, image.Height);

            List <List <Pixel> > pixelGrid      = LinqExtensions.FromTo(minY, maxY).Select(y => LinqExtensions.FromTo(minX, maxX).Select(x => pixels.GetPixel(x, y)).ToList()).ToList();
            List <List <float> > brightnessGrid = pixelGrid.Select(xs => xs.Select(p => p.ToColor().ToColor().GetBrightness()).ToList()).ToList();

            var gridWidth  = maxX - minX;
            var gridHeight = maxY - minY;

            var   bestNeedleStddev = 0.0;
            Point bestNeedle       = default(Point);

            double totalCycles  = rows.Count() * columns.Count();
            double currentCycle = 0;

            Console.WriteLine(brightnessGrid);
            foreach (var y in rows)
            {
                foreach (var x in columns)
                {
                    progress.Report(currentCycle / totalCycles);
                    currentCycle++;
                    if (y - minY + NeedleSize >= gridHeight)
                    {
                        continue;
                    }

                    if (x - minX + NeedleSize >= gridWidth)
                    {
                        continue;
                    }

                    var    count      = 0;
                    var    mean       = 0.0;
                    var    m2         = 0.0;
                    double blackCount = 0.0;
                    for (var x2 = x - minX; x2 < x - minX + NeedleSize; x2++)
                    {
                        for (var y2 = y - minY; y2 < y - minY + NeedleSize; y2++)
                        {
                            var b = brightnessGrid[y2][x2];
                            var p = pixelGrid[y2][x2].ToColor();

                            if (b < 0.08)
                            {
                                blackCount++;
                            }

                            count++;
                            var delta = b - mean;
                            mean = mean + delta / count;
                            var delta2 = b - mean;
                            m2 = m2 + delta * delta2;
                        }
                    }
                    var variance = m2 / (count - 1);
                    var stddev   = variance;

                    //Console.WriteLine("{0}, {1}, {2}", blackCount, NeedleSize * NeedleSize, blackCount / (NeedleSize * NeedleSize));
                    if (stddev > bestNeedleStddev && blackCount / (NeedleSize * NeedleSize) < 0.5)
                    {
                        bestNeedleStddev = stddev;
                        bestNeedle       = new Point(x, y);
                    }
                }
            }

            return(new NeedleResult()
            {
                Point = bestNeedle, Entropy = bestNeedleStddev
            });
        }