コード例 #1
0
        public void RunOCR(Bitmap inputImage)
        {
            inputImagePV.Image = inputImage;
            Bitmap removeBorderImage = BorderRemoval.RemoveBorder(inputImage);

            removeBorderPV.Image = removeBorderImage;
            Bitmap removeNoiseImage = NoiseCleaner.RemoveNoiseWithBorder(removeBorderImage);

            noiseRemovalPV.Image = removeNoiseImage;
            Bitmap croppedImage = WhitespaceCropper.CropWhitespace(removeNoiseImage);

            croppedPV.Image = croppedImage;
            if (EmptyImageDetector.IsImageEmpty(croppedImage))
            {
                recognizedGradeLabel.Text       = "0";
                recognitionConfidenceLabel.Text = "empty";
            }
            else
            {
                Bitmap digestImage = DigestExtractor.ExtractDigestImage(croppedImage);
                digestPV.Image = digestImage;

                GradeDigest       digest            = GradeDigest.FromImage(digestImage);
                RecognitionResult recognitionResult = GradeOCR.Program.RecognizeGrade(digest);

                recognizedGradeLabel.Text       = recognitionResult.Grade.ToString();
                recognitionConfidenceLabel.Text = recognitionResult.Confident ? "sure" : "unsure";
            }
        }
コード例 #2
0
        public static GradeDigest FromImage(Bitmap src)
        {
            if (src.Width != digestSize || src.Height != digestSize)
            {
                throw new Exception(String.Format(
                                        "Wrong digest image dimension: required {0}x{1}, got {2}x{3}",
                                        digestSize, digestSize, src.Width, src.Height));
            }
            GradeDigest gd = new GradeDigest();

            bool[] bitData = new bool[digestSize * digestSize];
            unsafe {
                BitmapData bd  = src.LockBits(new Rectangle(0, 0, src.Width, src.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                byte *     ptr = (byte *)bd.Scan0.ToPointer();

                for (int q = 0; q < src.Width * src.Height; q++)
                {
                    bitData[q] = *ptr == 0;
                    ptr       += 4;
                }

                src.UnlockBits(bd);
            }
            gd.data = PackBits(bitData);

            return(gd);
        }
コード例 #3
0
ファイル: DigestDifference.cs プロジェクト: Rogach/GradeOCR
        public static Bitmap GenerateDifferenceImage(GradeDigest gd1, GradeDigest gd2)
        {
            Bitmap res = new Bitmap(GradeDigest.digestSize, GradeDigest.digestSize, PixelFormat.Format32bppArgb);

            unsafe {
                BitmapData bd  = res.LockBits(new Rectangle(0, 0, res.Width, res.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                uint *     ptr = (uint *)bd.Scan0.ToPointer();

                for (int q = 0; q < gd1.data.Length * 64; q++)
                {
                    bool b1 = (gd1.data[q / 64] & ((ulong)1 << (q % 64))) != 0;
                    bool b2 = (gd2.data[q / 64] & ((ulong)1 << (q % 64))) != 0;
                    if (b1 && b2)
                    {
                        *(ptr++) = 0xff00ff00;
                    }
                    else if (b1 && !b2)
                    {
                        *(ptr++) = 0xffff0000;
                    }
                    else if (!b1 && b2)
                    {
                        *(ptr++) = 0xff0000ff;
                    }
                    else
                    {
                        *(ptr++) = 0xffffffff;
                    }
                }

                res.UnlockBits(bd);
            }

            return(res);
        }
コード例 #4
0
ファイル: Program.cs プロジェクト: Rogach/GradeOCR
        public static RecognitionResult RecognizeGrade(GradeDigest digest)
        {
            List <int> gradeCodes = new List <int> {
                2, 3, 4, 5
            };

            double[] output = new double[4];
            gradeRecognitionNetwork.NetOUT(NNUtils.ToNetworkInput(GradeDigest.UnpackBits(digest.data)), out output);
            return(new RecognitionResult(
                       grade: gradeCodes[NNUtils.Answer(output)],
                       confident: NNUtils.AnswerConfidence(output) < recognitionConfidenceThreshold
                       ));
        }
コード例 #5
0
ファイル: Program.cs プロジェクト: Rogach/GradeOCR
        public static Option <GradeDigest> GetGradeDigest(Bitmap img)
        {
            Bitmap croppedImage =
                WhitespaceCropper.CropWhitespace(
                    NoiseCleaner.RemoveNoiseWithBorder(
                        BorderRemoval.RemoveBorder(img)));

            if (EmptyImageDetector.IsImageEmpty(croppedImage))
            {
                return(new None <GradeDigest>());
            }
            else
            {
                return(new Some <GradeDigest>(
                           GradeDigest.FromImage(
                               DigestExtractor.ExtractDigestImage(croppedImage))));
            }
        }
コード例 #6
0
ファイル: GradeDigestSet.cs プロジェクト: Rogach/GradeOCR
        public static GradeDigestSet Read(Stream inStream)
        {
            List <GradeDigest> digests = new List <GradeDigest>();

            uint digestCount = ByteUtils.ReadUInt(inStream);

            for (int q = 0; q < digestCount; q++)
            {
                GradeDigest gd = new GradeDigest();
                gd.grade = ByteUtils.SafeReadByte(inStream);
                for (int w = 0; w < gd.data.Length; w++)
                {
                    gd.data[w] = ByteUtils.ReadULong(inStream);
                }
                digests.Add(gd);
            }

            return(new GradeDigestSet(digests));
        }
コード例 #7
0
ファイル: GradeDigestSet.cs プロジェクト: Rogach/GradeOCR
        public double MatchDigests(GradeDigest gd1, GradeDigest gd2)
        {
            int union        = 0;
            int intersection = 0;

            for (int q = 0; q < gd1.data.Length; q++)
            {
                intersection += ByteUtils.CountBits(gd1.data[q] & gd2.data[q]);
                union        += ByteUtils.CountBits(gd1.data[q] | gd2.data[q]);
            }
            if (union == 0)
            {
                return(0);
            }
            else
            {
                return((double)intersection / (double)union);
            }
        }
コード例 #8
0
ファイル: GradeDigestSet.cs プロジェクト: Rogach/GradeOCR
        public RecognitionResult FindBestMatch(GradeDigest digest)
        {
            double      maxMatch   = 0;
            int         bestIndex  = 0;
            GradeDigest bestDigest = digestList[0];

            for (int q = 0; q < digestList.Count; q++)
            {
                var    gd    = digestList[q];
                double match = MatchDigests(digest, gd);
                if (maxMatch < match && match < 0.9999)
                {
                    maxMatch   = match;
                    bestDigest = gd;
                    bestIndex  = q;
                }
            }
            throw new NotImplementedException();
        }