private void btnCorrelation_Click(object sender, EventArgs e) { if (harrisPoints1 == null) { MessageBox.Show("Please click the Harris button first! :-)"); return; } // Step 2: Match feature points using a correlation measure CorrelationMatching matcher = new CorrelationMatching(9, img1, img2); IntPoint[][] matches = matcher.Match(harrisPoints1, harrisPoints2); // Get the two sets of points correlationPoints1 = matches[0]; correlationPoints2 = matches[1]; // Concatenate the two images in a single image (just to show on screen) Concatenate concat = new Concatenate(img1); Bitmap img3 = concat.Apply(img2); // Show the marked correlations in the concatenated image PairsMarker pairs = new PairsMarker( correlationPoints1, // Add image1's width to the X points to show the markings correctly correlationPoints2.Apply(p => new IntPoint(p.X + img1.Width, p.Y))); pictureBox.Image = pairs.Apply(img3); }
//Relies less on neighbor pixels and more on RANSAC protected void fastHarrisRansacBlend(List <Bitmap> imgs) { List <IntPoint[]> harrisPoints = new List <IntPoint[]>(); MatrixH homography; //Calculate all the Harris Points HarrisCornersDetector harris = new HarrisCornersDetector(0.03f, 10000f); for (int i = 0; i < imgs.Count; i++) { harrisPoints.Add(harris.ProcessImage(imgs[i]).ToArray()); } Bitmap final = imgs[0]; for (int i = 1; i < imgs.Count; i++) { IntPoint[] harrisFinal = harris.ProcessImage(final).ToArray(); //Correlate the Harris pts between imgs CorrelationMatching matcher = new CorrelationMatching(5, final, imgs[i]); IntPoint[][] matches = matcher.Match(harrisFinal, harrisPoints[i]); //Create the homography matrix using ransac RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.025, 0.99); homography = ransac.Estimate(matches[0], matches[1]); Blend blend = new Blend(homography, final); blend.Gradient = true; final = blend.Apply(imgs[i]); } showImage(final); }
/* * Matches feature points using a correlation measure. */ private void CorrelationMatchingRecursive() { CorrelationMatching matcher = new CorrelationMatching(9); IntPoint[][] matches = matcher.Match(images[0], images[1], harrisPoints1, harrisPoints2); // Get the two sets of points correlationPoints1 = matches[0]; correlationPoints2 = matches[1]; }
public void MatchTest2() { for (int windowSize = 1; windowSize <= 15; windowSize += 2) { #pragma warning disable 0618 CorrelationMatching target = new CorrelationMatching(windowSize); #pragma warning restore 0618 Bitmap image1 = Accord.Imaging.Image.Clone(Properties.Resources.image1); Bitmap image2 = Accord.Imaging.Image.Clone(Properties.Resources.image1); Assert.AreEqual(16, image1.Height); Assert.AreEqual(16, image2.Height); Assert.AreEqual(16, image1.Width); Assert.AreEqual(16, image2.Width); // will test every possible point in the image // (and also some points outside just to make sure) List <IntPoint> points = new List <IntPoint>(); for (int i = -5; i < 20; i++) { for (int j = -5; j < 20; j++) { points.Add(new IntPoint(i, j)); } } // Assert that no exception if thrown #pragma warning disable 0618 IntPoint[][] actual = target.Match(image1, image2, points.ToArray(), points.ToArray()); #pragma warning restore 0618 Assert.IsNotNull(actual); Assert.AreEqual(2, actual.Length); var p1 = actual[0]; var p2 = actual[1]; Assert.AreEqual(p1.Length, p2.Length); for (int i = 0; i < p1.Length; i++) { // As the images are the same, assert that // each point correlates with itself. Assert.AreEqual(p1[i], p2[i]); // Also assert we have no bogus values Assert.IsTrue(p1[i].X >= 0 && p1[i].X < 16); Assert.IsTrue(p1[i].Y >= 0 && p1[i].Y < 16); } } }
protected void fastHarrisRansacBlendStraight(List <Bitmap> imgs) { List <IntPoint[]> harrisPoints = new List <IntPoint[]>(); MatrixH homography; //Calculate all the Harris Points HarrisCornersDetector harris = new HarrisCornersDetector(0.03f, 10000f); for (int i = 0; i < imgs.Count; i++) { harrisPoints.Add(harris.ProcessImage(imgs[i]).ToArray()); } Bitmap final = imgs[0]; for (int i = 1; i < imgs.Count; i++) { //Convert my frames to grayscale so I can find and adjust the normal vectors AForge.Imaging.Filters.GrayscaleBT709 grayscale = new AForge.Imaging.Filters.GrayscaleBT709(); AForge.Imaging.DocumentSkewChecker skew = new AForge.Imaging.DocumentSkewChecker(); double finalAngle = skew.GetSkewAngle(grayscale.Apply(final)); double imgAngle = skew.GetSkewAngle(grayscale.Apply(imgs[i])); //Less than 5% to account for human error with rotations and wobbles if (Math.Abs(finalAngle - imgAngle) < 5) { AForge.Imaging.Filters.RotateBilinear rotate = new AForge.Imaging.Filters.RotateBilinear(finalAngle - imgAngle); rotate.FillColor = Color.FromArgb(0, 255, 255, 255); imgs[i] = rotate.Apply(imgs[i]); //Update harris harrisPoints[i] = harris.ProcessImage(imgs[i]).ToArray(); } IntPoint[] harrisFinal = harris.ProcessImage(final).ToArray(); //Correlate the Harris pts between imgs CorrelationMatching matcher = new CorrelationMatching(5, final, imgs[i]); IntPoint[][] matches = matcher.Match(harrisFinal, harrisPoints[i]); //Create the homography matrix using ransac RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.025, 0.99); homography = ransac.Estimate(matches[0], matches[1]); Blend blend = new Blend(homography, final); blend.Gradient = true; final = blend.Apply(imgs[i]); } showImage(final); }
/// <summary> /// Maximum cross-correlation feature point matching algorithm. /// </summary> /// <param name="correlationMatching"> Maximum cross-correlation feature point matching algorithm.</param> /// <param name="image1">First image.</param> /// <param name="image2">Second image.</param> /// <param name="points1">Points from the first image.</param> /// <param name="points2">Points from the second image.</param> /// <returns>Matched point-pairs.</returns> public static Point[][] Match(this CorrelationMatching correlationMatching, Image <Gray, byte> image1, Image <Gray, byte> image2, Point[] points1, Point[] points2) { var result = correlationMatching.Match ( image1.ToBitmap(copyAlways: false, failIfCannotCast: true), image2.ToBitmap(copyAlways: false, failIfCannotCast: true), points1, points2 ); return(result); }
/// <summary> /// Maximum cross-correlation feature point matching algorithm. /// </summary> /// <param name="image1">First image.</param> /// <param name="image2">Second image.</param> /// <param name="points1">Points from the first image.</param> /// <param name="points2">Points from the second image.</param> /// <param name="windowSize">The size of the correlation window.</param> /// <param name="maxDistance">The maximum distance to consider points as correlated.</param> /// <returns>Matched point-pairs.</returns> public static Point[][] Match(Gray <byte>[,] image1, Gray <byte>[,] image2, Point[] points1, Point[] points2, int windowSize, int maxDistance) { Point[][] matches = null; using (var uImg1 = image1.Lock()) using (var uImg2 = image2.Lock()) { var correlationMatching = new CorrelationMatching(windowSize, maxDistance, uImg1.AsBitmap(), uImg2.AsBitmap()); matches = correlationMatching.Match(points1.ToPoints(), points2.ToPoints()).ToPoints(); } return(matches); }
public void MatchTest() { int windowSize = 3; #pragma warning disable 0618 CorrelationMatching target = new CorrelationMatching(windowSize); #pragma warning restore 0618 Bitmap image1 = Accord.Imaging.Image.Clone(Properties.Resources.image1); Bitmap image2 = Accord.Imaging.Image.Clone(Properties.Resources.image1); IntPoint[] points1 = { new IntPoint(3, 3), new IntPoint(14, 3), new IntPoint(3, 14), new IntPoint(14, 14), }; IntPoint[] points2 = { new IntPoint(3, 3), new IntPoint(14, 3), new IntPoint(3, 14), new IntPoint(14, 14), }; IntPoint[][] expected = { new IntPoint[] { new IntPoint(3, 3), new IntPoint(14, 3), new IntPoint(3, 14), new IntPoint(14, 14) }, new IntPoint[] { new IntPoint(3, 3), new IntPoint(14, 3), new IntPoint(3, 14), new IntPoint(14, 14) }, }; #pragma warning disable 0618 IntPoint[][] actual = target.Match(image1, image2, points1, points2); #pragma warning restore 0618 Assert.IsTrue(actual.IsEqual(expected)); }
public void MatchTest() { int windowSize = 3; CorrelationMatching target = new CorrelationMatching(windowSize); Bitmap image1 = Properties.Resources.image1; Bitmap image2 = Properties.Resources.image1; IntPoint[] points1 = { new IntPoint(3, 3), new IntPoint(14, 3), new IntPoint(3, 14), new IntPoint(14, 14), }; IntPoint[] points2 = { new IntPoint(3, 3), new IntPoint(14, 3), new IntPoint(3, 14), new IntPoint(14, 14), }; IntPoint[][] expected = { new IntPoint[] { new IntPoint(3, 3), new IntPoint(14, 3), new IntPoint(3, 14), new IntPoint(14, 14) }, new IntPoint[] { new IntPoint(3, 3), new IntPoint(14, 3), new IntPoint(3, 14), new IntPoint(14, 14) }, }; IntPoint[][] actual = target.Match(image1, image2, points1, points2); Assert.IsTrue(actual.IsEqual(expected)); }
protected void drawFastHarrisFeaturesCorrelations(List <Bitmap> imgs) { List <IntPoint[]> harrisPoints = new List <IntPoint[]>(); MatrixH homography; //Calculate all the Harris Points HarrisCornersDetector harris = new HarrisCornersDetector(0.03f, 10000f); foreach (Bitmap img in imgs) { harrisPoints.Add(harris.ProcessImage(img).ToArray()); } //Map them and draw them! Bitmap harrisImg = imgs[0]; for (int i = 0; i < imgs.Count - 1; i++) { //Correlate the Harris pts between imgs CorrelationMatching matcher = new CorrelationMatching(5, imgs[i], imgs[i + 1]); IntPoint[][] matches = matcher.Match(harrisPoints[i], harrisPoints[i + 1]); //Create the homography matrix using ransac RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.025, 0.99); homography = ransac.Estimate(matches[0], matches[1]); Concatenate concat = new Concatenate(harrisImg); Bitmap img = concat.Apply(imgs[i + 1]); Color color = Color.White; if (i % 3 == 1) { color = Color.OrangeRed; } if (i % 3 == 2) { color = Color.Blue; } PairsMarker pairs = new PairsMarker(matches[0].Apply(p => new IntPoint(p.X + harrisImg.Width - imgs[0].Width, p.Y)), matches[1].Apply(p => new IntPoint(p.X + harrisImg.Width, p.Y)), color); harrisImg = pairs.Apply(img); } showImage(harrisImg); }
/// <summary> /// </summary> /// <param name="sender"> /// </param> /// <param name="e"> /// </param> private void BtnCorrelation_OnClick(object sender, RoutedEventArgs e) { // Step 2: Match feature points using a correlation measure var matcher = new CorrelationMatching(9, this.img1, this.img2); var matches = matcher.Match(this.harrisPoints1, this.harrisPoints2); // Get the two sets of points this.correlationPoints1 = matches[0]; this.correlationPoints2 = matches[1]; // Concatenate the two images in a single image (just to show on screen) var concat = new Concatenate(this.img1); var img3 = concat.Apply(this.img2); // Show the marked correlations in the concatenated image var pairs = new PairsMarker(this.correlationPoints1, // Add image1's width to the X points to show the markings correctly this.correlationPoints2.Apply(p => new IntPoint(p.X + this.img1.Width, p.Y))); this.PictureBox.Source = (ImageSource)pairs.Apply(img3); }
// Correlation Matching private void Correlator() { // Step 2: Match feature points using a correlation measure CorrelationMatching matcher = new CorrelationMatching(9); IntPoint[][] matches = matcher.Match(_img1, _img2, harrisPoints1, harrisPoints2); // Get the two sets of points correlationPoints1 = matches[0]; correlationPoints2 = matches[1]; // Concatenate the two images in a single image (just to show on screen) Concatenate concat = new Concatenate(_img1); Bitmap img3 = concat.Apply(_img2); // Show the marked correlations in the concatenated image PairsMarker pairs = new PairsMarker( correlationPoints1, // Add image1's width to the X points // to show the markings correctly correlationPoints2.Apply(p => new IntPoint(p.X + _img1.Width, p.Y))); _processImage2 = pairs.Apply(img3); }
public static Geometry AutoAlign(Bitmap needle, Bitmap haystack, double retryThreshold = 1, int retryLimit = 10) { IntPoint[] harrisPoints1; IntPoint[] harrisPoints2; IntPoint[] correlationPoints1; IntPoint[] correlationPoints2; MatrixH homography; var mi1 = new MagickImage(needle); mi1.Equalize(); needle = mi1.ToBitmap(); var mi2 = new MagickImage(haystack); mi2.Equalize(); haystack = mi2.ToBitmap(); HarrisCornersDetector harris = new HarrisCornersDetector(0.04f, 20000f); harrisPoints1 = harris.ProcessImage(needle).ToArray(); harrisPoints2 = harris.ProcessImage(haystack).ToArray(); CorrelationMatching matcher = new CorrelationMatching(9, needle, haystack); IntPoint[][] matches = matcher.Match(harrisPoints1, harrisPoints2); correlationPoints1 = matches[0]; correlationPoints2 = matches[1]; RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.001, 0.999); homography = ransac.Estimate(correlationPoints1, correlationPoints2); IntPoint[] inliers1 = correlationPoints1.Get(ransac.Inliers); IntPoint[] inliers2 = correlationPoints2.Get(ransac.Inliers); Concatenate concat = new Concatenate(needle); Bitmap img3 = concat.Apply(haystack); PairsMarker pairs = new PairsMarker( inliers1, inliers2.Apply(p => new IntPoint(p.X + needle.Width, p.Y))); var Image = pairs.Apply(img3); Image.Save(@"C:\AutoAlignDebug.png"); var pointCount = inliers1.Length; int[] xList1 = new int[pointCount]; int[] yList1 = new int[pointCount]; int[] xList2 = new int[pointCount]; int[] yList2 = new int[pointCount]; for (int n = 0; n < pointCount; n++) { xList1[n] = inliers1[n].X; yList1[n] = inliers1[n].Y; xList2[n] = inliers2[n].X; yList2[n] = inliers2[n].Y; } var f = new double[8] { xList1.Min(), yList1.Min(), xList1.Max(), yList1.Max(), xList2.Min(), yList2.Min(), xList2.Max(), yList2.Max() }; double distFromX1 = f[0] / needle.Width; double distFromX2 = f[2] / needle.Width; double leftRatio = f[0] / (f[2] - f[0]); double rightRatio = (needle.Width - f[2]) / (f[2] - f[0]); double distFromY1 = f[1] / needle.Height; double distFromY2 = f[3] / needle.Height; double topRatio = f[1] / (f[3] - f[1]); double bottomRatio = (needle.Height - f[3]) / (f[3] - f[1]); double leftDist = (f[6] - f[4]) * leftRatio; double rightDist = (f[6] - f[4]) * rightRatio; double topDist = (f[7] - f[5]) * topRatio; double bottomDist = (f[7] - f[5]) * bottomRatio; double x = f[4] - leftDist; double y = f[5] - topDist; double width = leftDist + (f[6] - f[4]) + rightDist; double height = topDist + (f[7] - f[5]) + bottomDist; mi1.Resize(new MagickGeometry((int)Math.Round(width), (int)Math.Round(height)) { IgnoreAspectRatio = true }); var mg = new MagickGeometry((int)Math.Round(x), (int)Math.Round(y), (int)Math.Round(width), (int)Math.Round(height)) { IgnoreAspectRatio = true }; mi2.Extent(mg, Gravity.Northwest, MagickColor.FromRgba(0, 0, 0, 0)); double delta = mi1.Compare(mi2, ErrorMetric.NormalizedCrossCorrelation); Geometry outGeo = new Geometry(x, y, width, height); if (delta < retryThreshold && retryLimit > 0) { retryLimit--; outGeo = AutoAlign(needle, haystack, delta, retryLimit); } return(outGeo); }