/* * Convenience function to locate N finder circles with given pattern radius bounds. */ public static List <Point3> LocateFinderCircles(Bitmap img, int minPatternRadius, int maxPatternRadius, int patternCount) { int scaleFactor = GetScaleFactor(minPatternRadius); using (Bitmap downscaledImage = ImageScaling.ScaleDown(img, scaleFactor)) { int[, ,] hough = HoughTransform(downscaledImage, minPatternRadius / scaleFactor, maxPatternRadius / scaleFactor); List <Point3> roughPeaks = LocatePeaks(hough, patternCount, minPatternRadius / scaleFactor).ConvertAll(p => new Point3(p.X * scaleFactor, p.Y * scaleFactor, p.Z * scaleFactor + minPatternRadius)); return(roughPeaks.ConvertAll(peak => TunePeak(img, minPatternRadius, maxPatternRadius, peak))); } }
/* * "Tune" peak location. Given a peak, re-applies Hough transform in some radius * around this peak, and re-determines peak location. * This function also downscales input image, though less severely than * main transform. */ public static Point3 TunePeak(Bitmap img, int minPatternRadius, int maxPatternRadius, Point3 peak) { int scaleFactor = GetScaleFactor(minPatternRadius); int tuneScaleFactor = GetTuneScaleFactor(minPatternRadius); int wSize = scaleFactor * 2 + maxPatternRadius * 2; int wx = peak.X - scaleFactor - maxPatternRadius; int wy = peak.Y - scaleFactor - maxPatternRadius; // clamp window to main image bounds wx = Math.Min(img.Width - wSize, Math.Max(0, wx)); wy = Math.Min(img.Height - wSize, Math.Max(0, wy)); using (Bitmap window = ImageScaling.ScaleDown(img, tuneScaleFactor, new Rectangle(wx, wy, wSize, wSize))) { int[, ,] hough = HoughTransform(window, minPatternRadius / tuneScaleFactor, maxPatternRadius / tuneScaleFactor); Point3 tunedPeak = LocatePeak(hough); return(new Point3( tunedPeak.X * tuneScaleFactor + wx, tunedPeak.Y * tuneScaleFactor + wy, tunedPeak.Z * tuneScaleFactor + minPatternRadius)); } }
private void RunOCR(Bitmap sourceImage, int minPatternRadius, int maxPatternRadius, uint inputValue, NoiseFilter noiseFilter) { this.inputDataLabel.Text = inputValue.ToString(); Bitmap grayImage = ImageUtil.ToGrayscale(sourceImage); this.inputImagePV.Image = grayImage; Bitmap noiseImage = noiseFilter.Apply(sourceImage); if (noiseFilter.GetType() != typeof(EmptyFilter)) { this.noiseImagePV.Image = noiseImage; } int scaleFactor = FinderCircleHoughTransform.GetScaleFactor(minPatternRadius); Console.WriteLine("scaleFactor = " + scaleFactor); Bitmap downscaledImage = ImageScaling.ScaleDown(noiseImage, scaleFactor); int[,,] hough = Util.Timed("hough transform", () => FinderCircleHoughTransform.HoughTransform(downscaledImage, minPatternRadius / scaleFactor, maxPatternRadius / scaleFactor)); Bitmap houghTransformImage = FinderCircleHoughTransform.HoughTransformImage(hough); this.houghImagePV.Image = houghTransformImage; List <Point3> peaks = FinderCircleHoughTransform.LocatePeaks(hough, 2, minPatternRadius / scaleFactor); List <Point3> descaledPeaks = peaks.ConvertAll(p => new Point3(p.X * scaleFactor, p.Y * scaleFactor, p.Z * scaleFactor + minPatternRadius)); foreach (var p in descaledPeaks) { Console.WriteLine("Raw peak at {0}x{1}x{2}", p.X, p.Y, p.Z); } List <Point3> tunedPeaks = Util.Timed("tune peaks", () => descaledPeaks.ConvertAll(peak => FinderCircleHoughTransform.TunePeak(noiseImage, minPatternRadius, maxPatternRadius, peak))); foreach (var p in tunedPeaks) { Console.WriteLine("Tuned peak at {0}x{1}x{2}", p.X, p.Y, p.Z); } Bitmap houghPeaksImage = new Bitmap(houghTransformImage); DrawPeaks(houghPeaksImage, peaks, Color.Red); this.houghPeakImagePV.Image = houghPeaksImage; Bitmap resultPeaksImage = new Bitmap(noiseImage); DrawPeaks(resultPeaksImage, descaledPeaks, Color.Red); DrawPeaks(resultPeaksImage, tunedPeaks, Color.Green); this.peakResultImagePV.Image = resultPeaksImage; FinderPatternPair fpp = new FinderPatternPair(); fpp.p1 = new Point(tunedPeaks[0].X, tunedPeaks[0].Y); fpp.size1 = tunedPeaks[0].Z; fpp.p2 = new Point(tunedPeaks[1].X, tunedPeaks[1].Y); fpp.size2 = tunedPeaks[1].Z; DataMatrixExtraction dme = new DataMatrixExtraction(noiseImage, fpp); Bitmap positioningDebugImage = new Bitmap(noiseImage); dme.DrawPositioningDebug(positioningDebugImage); dataMatrixLocationPV.Image = positioningDebugImage; rotatedDataMatrixPV.Image = dme.rotatedMatrix; recognizedDataMatrixPV.Image = dme.RecognitionDebugImage(); Option <uint> extractedCode = DataMarshaller.UnMarshallInt(dme.extractedData); outputDataLabel.Text = extractedCode.Map(c => c.ToString()).GetOrElse("none"); }