Esempio n. 1
0
        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);
        }
Esempio n. 3
0
        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> >());
            }
        }
Esempio n. 4
0
        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");
        }