public DataMatrixExtraction(Bitmap sourceImage, FinderPatternPair fpp) { this.fpp = fpp; PointF p1 = fpp.p1.X < fpp.p2.X ? fpp.p1.ToF() : fpp.p2.ToF(); PointF p2 = fpp.p1.X < fpp.p2.X ? fpp.p2.ToF() : fpp.p1.ToF(); PointF vect = PointOps.Mult(PointOps.Sub(p2, p1), 0.1f); float unit = (float)PointOps.Distance(vect); PointF normX = PointOps.Normalize(vect); angX = Math.Atan2(normX.Y, normX.X); double angY = angX - Math.PI / 2; PointF normY = new PointF((float)Math.Cos(angY), (float)Math.Sin(angY)); topLeft = PointOps.Add(p1, PointOps.Add(PointOps.Mult(normX, unit), PointOps.Mult(normY, unit))); bottomLeft = PointOps.Add(p1, PointOps.Sub(PointOps.Mult(normX, unit), PointOps.Mult(normY, unit))); topRight = PointOps.Add(p1, PointOps.Add(PointOps.Mult(normX, unit * 9), PointOps.Mult(normY, unit))); bottomRight = PointOps.Add(p1, PointOps.Sub(PointOps.Mult(normX, unit * 9), PointOps.Mult(normY, unit))); rotatedMatrix = new Bitmap((int)Math.Ceiling(unit * 8), (int)Math.Ceiling(unit * 2), PixelFormat.Format32bppArgb); Graphics rotG = Graphics.FromImage(rotatedMatrix); rotG.RotateTransform((float)(-angX * 180 / Math.PI)); float diagonal = (float)PointOps.Distance(p1, p2); rotG.DrawImage( sourceImage, new RectangleF(-diagonal, -diagonal, diagonal * 2, diagonal * 2), new RectangleF(topLeft.X - diagonal, topLeft.Y - diagonal, diagonal * 2, diagonal * 2), GraphicsUnit.Pixel); rotG.Dispose(); int[] cellSum = new int[DataMatrixDrawer.rowCount * DataMatrixDrawer.columnCount]; unsafe { BitmapData bd = rotatedMatrix.LockBits(ImageLockMode.ReadOnly); byte * ptr = (byte *)bd.Scan0.ToPointer(); for (int y = 0; y < rotatedMatrix.Height; y++) { for (int x = 0; x < rotatedMatrix.Width; x++) { int cx = (int)Math.Floor((float)x * DataMatrixDrawer.columnCount / rotatedMatrix.Width); int cy = (int)Math.Floor((float)y * DataMatrixDrawer.rowCount / rotatedMatrix.Height); cellSum[cy * DataMatrixDrawer.columnCount + cx] += *ptr; ptr += 4; } } rotatedMatrix.UnlockBits(bd); } double threshold = ValueClustering.DivThreshold(cellSum); extractedData = new bool[DataMatrixDrawer.rowCount * DataMatrixDrawer.columnCount]; for (int q = 0; q < DataMatrixDrawer.rowCount * DataMatrixDrawer.columnCount; q++) { extractedData[q] = cellSum[q] < threshold; } }
public static FinderPatternPair LocateFinderPatternPair(Bitmap sourceImage, int patternRadius) { int minPatternRadius = (int)Math.Floor((double)patternRadius * 0.9); int maxPatternRadius = (int)Math.Ceiling((double)patternRadius * 1.1); List <Point3> finderPatterns = FinderCircleHoughTransform.LocateFinderCircles( sourceImage, minPatternRadius, maxPatternRadius, 2); FinderPatternPair fp = new FinderPatternPair(); fp.p1 = new Point(finderPatterns[0].X, finderPatterns[0].Y); fp.size1 = finderPatterns[0].Z; fp.p2 = new Point(finderPatterns[1].X, finderPatterns[1].Y); fp.size2 = finderPatterns[1].Z; return(fp); }
public static Option <Tuple <uint, DataMatrixExtraction> > ExtractCodeExt(Bitmap sourceImage, int minPatternRadius, int maxPatternRadius) { List <Point3> finderCircles = FinderCircleHoughTransform.LocateFinderCircles(sourceImage, minPatternRadius, maxPatternRadius, 2); var fpp = new FinderPatternPair(); fpp.p1 = new Point(finderCircles[0].X, finderCircles[0].Y); fpp.size1 = finderCircles[0].Z; fpp.p2 = new Point(finderCircles[1].X, finderCircles[1].Y); fpp.size2 = finderCircles[1].Z; var dme = new DataMatrixExtraction(sourceImage, fpp); Option <uint> extractedCode = DataMarshaller.UnMarshallInt(dme.extractedData); if (extractedCode.NonEmpty()) { return(new Some <Tuple <uint, DataMatrixExtraction> >(new Tuple <uint, DataMatrixExtraction>(extractedCode.Get(), dme))); } else { return(new None <Tuple <uint, DataMatrixExtraction> >()); } }
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"); }