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()); }
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); } }
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); }