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"; } }
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); }
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); }
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 )); }
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)))); } }
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)); }
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); } }
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(); }