Пример #1
0
        private Point[] GetLocation(ValueTuple <List <double>, List <double> > mx)
        {
            var points = new List <Point>();
            var matrix = mx.Item2;

            foreach (var(cornerX, cornerY) in GetSampleCorners())
            {
                var(pointX, pointY) = Ransac.Transform(matrix, cornerX, cornerY);
                points.Add(new Point((int)Math.Round(pointX), (int)Math.Round(pointY)));
            }

            return(points.ToArray());
        }
Пример #2
0
        public static Bitmap Transform(Bitmap pictureA, Bitmap pictureB, List <double> matrixA, List <double> matrixB)
        {
            int minX = 0,
                maxX = pictureA.Width,
                minY = 0,
                maxY = pictureA.Height;

            var points = new List <(double, double)>
            {
                Ransac.Transform(matrixB, 0, 0),
                Ransac.Transform(matrixB, pictureB.Width, 0),
                Ransac.Transform(matrixB, 0, pictureB.Height),
                Ransac.Transform(matrixB, pictureB.Width, pictureB.Height)
            };

            minX = (int)Math.Min(minX, points.Min(x => x.Item1));
            minY = (int)Math.Min(minY, points.Min(x => x.Item2));
            maxX = (int)Math.Max(maxX, points.Max(x => x.Item1));
            maxY = (int)Math.Max(maxY, points.Max(x => x.Item2));

            int width = maxX - minX,
                height = maxY - minY;
            int dx = -minX, dy = -minY;

            var bitmap = new Bitmap(width, height);
            var g      = Graphics.FromImage(bitmap);

            g.DrawImage(pictureA, dx, dy, pictureA.Width, pictureA.Height);

            for (var x = 0; x < bitmap.Width; x++)
            {
                for (var y = 0; y < bitmap.Height; y++)
                {
                    var(nx, ny) = Ransac.Transform(matrixA, x - dx, y - dy);

                    if (nx < 0 || ny < 0 || nx >= pictureB.Width || ny >= pictureB.Height)
                    {
                        continue;
                    }
                    bitmap.SetPixel(x, y, pictureB.GetPixel((int)nx, (int)ny));
                }
            }

            return(bitmap);
        }
    }
Пример #3
0
        public List <Point[]> Find()
        {
            CoordinateStep = Math.Min(image.Width, image.Height) / 5;
            // CoordinateStep = (int)(1.1 * Math.Min(image.Width, image.Height) / (Math.Max(image.Width, image.Height) / Math.Max(sample.Width, sample.Height)));

            var cellsX = (int)Math.Ceiling(image.Width * 1D / CoordinateStep);
            var cellsY = (int)Math.Ceiling(image.Height * 1D / CoordinateStep);

            VotesImage = IOHelper.MatToImage(image);
            for (var i = 1; i < cellsX; i++)
            {
                var x = CoordinateStep * i;
                DrawHelper.DrawLine(VotesImage, x, 0, x, image.Height - 1);
            }

            for (var i = 1; i < cellsY; i++)
            {
                var y = CoordinateStep * i;
                DrawHelper.DrawLine(VotesImage, 0, y, image.Width - 1, y);
            }

            var descriptorsSample    = BlobsFinder.FindBlobs(sample, 500);
            var descriptorsFullImage = BlobsFinder.FindBlobs(image, 500);
            var matches = DescriptorMatcher.Nndr(descriptorsFullImage, descriptorsSample);

            ReverseMatches = matches.Select(x => new Match(x.Item2, x.Item1)).ToList();

            var sampleCenterX = sample.Width / 2.0;
            var sampleCenterY = sample.Height / 2.0;

            votes  = new double[cellsX, cellsY, AngleCells, CellsScale];
            voters = new List <Match> [cellsX, cellsY, AngleCells, CellsScale];

            foreach (var match in matches)
            {
                var samplePoint = match.Item2.Point;
                var imagePoint  = match.Item1.Point;

                var scale = imagePoint.Radius / samplePoint.Radius;
                var angle = match.Item2.Angle - match.Item1.Angle;

                var vectorX = scale * (sampleCenterX - samplePoint.getX());
                var vectorY = scale * (sampleCenterY - samplePoint.getY());

                var centerX = imagePoint.getX() + vectorX * Math.Cos(angle) - vectorY * Math.Sin(angle);
                var centerY = imagePoint.getY() + vectorX * Math.Sin(angle) + vectorY * Math.Cos(angle);

                Vote(match, centerX, centerY, scale, angle);
                DrawHelper.DrawLine(VotesImage,
                                    imagePoint.getX(), imagePoint.getY(),
                                    (int)Math.Round(centerX), (int)Math.Round(centerY));
            }

            for (var x = 0; x < cellsX; x++)
            {
                for (var y = 0; y < cellsY; y++)
                {
                    for (var a = 0; a < AngleCells; a++)
                    {
                        for (var s = 0; s < CellsScale; s++)
                        {
                            if (IsVotesLocalMaximum(x, y, a, s) && voters[x, y, a, s].Count > VotersThreshold)
                            {
                                //  DrawHelper.DrawPolygon(VotesImage, GetPreliminary(x, y, a, s), true);
                                objects.Add(GetLocation(Ransac.CalculateTransform(voters[x, y, a, s])));
                            }
                        }
                    }
                }
            }

            return(objects);
        }