public BinaryRecognition() { this.charCache = BinaryChar.GetBinaryChars().ToArray(); }
private double scoreGlyph(CachedBitmap img, BinaryChar glyph, int xPen) { int nextColumn = img.CacheNextFilledColumn.ElementAtOrDefault(xPen + 2); int nextEmptyColumn = img.CacheNextEmptyColumn.ElementAtOrDefault(xPen + glyph.Bitmap.Width); int endColumn = img.CacheNextFilledColumn.ElementAtOrDefault(xPen + glyph.Bitmap.Width + 4); int prevColumn = img.CachePrevFilledColumn.ElementAtOrDefault(xPen + glyph.Bitmap.Width + 1); if (nextColumn == -1 || prevColumn == -1) { return(-9999d); } if (nextColumn - xPen < 2 || (endColumn == -1 && prevColumn - xPen < 2)) { return(-9999d); } if (nextEmptyColumn == -1 || nextEmptyColumn - xPen > 80) { return(-9999d); } int estimatedWidthDiff = Math.Abs((nextEmptyColumn - xPen) - glyph.Bitmap.Width); double estimatedWidthBonus = 1d / (estimatedWidthDiff + 1d); double wrongColumns = 0d; for (int x = xPen; x < (xPen + glyph.Bitmap.Width); x++) { wrongColumns += Math.Abs(img.CacheColumnFilling.ElementAtOrDefault(x) - glyph.Bitmap.CacheColumnFilling.ElementAtOrDefault(x - xPen)); } if (glyph.Bitmap.Width < 5) { wrongColumns = 0d; } else { wrongColumns /= glyph.Bitmap.Width; } double nonMatchingPixels = 0d; double glyphDistanceSum = 0d; double glyphDistanceMax = 0d; double glyphPixelNum = 0d; double targetDistanceSum = 0d; double targetDistanceNum = 0d; double targetDistanceMax = 0d; double targetPixelNum = 0d; for (int y = 0; y < img.Height; y++) { for (int x = 0; x < glyph.Bitmap.Width; x++) { if (glyph.Bitmap.CacheNearestBinaryPixel[y].ElementAtOrDefault(x) == 0) { glyphPixelNum++; double distance = img.CacheNearestBinaryPixel[y].ElementAtOrDefault(x + xPen); glyphDistanceSum += distance; glyphDistanceMax = Math.Max(glyphDistanceMax, distance); } if (img.CacheNearestBinaryPixel[y].ElementAtOrDefault(x + xPen) == 0) { targetPixelNum++; double distance = glyph.Bitmap.CacheNearestBinaryPixel[y][x]; targetDistanceSum += distance; targetDistanceNum++; targetDistanceMax = Math.Max(targetDistanceMax, distance); } if ((img.CacheNearestBinaryPixel[y].ElementAtOrDefault(x + xPen) <= 1) ^ (glyph.Bitmap.CacheNearestBinaryPixel[y].ElementAtOrDefault(x) <= 1)) { nonMatchingPixels++; } } } List <double> scoreParts = new List <double>() { -Math.Pow(glyphDistanceMax <= 1 ? 0d : glyphDistanceMax, 1.5d) * 5, -glyphDistanceSum / (glyphPixelNum * 0.1d), -glyphDistanceSum * 0.05d, -Math.Pow(targetDistanceMax <= 1 ? 0d : targetDistanceMax, 1.5d) * 10d, -(targetDistanceSum / targetDistanceNum) * 25d, -targetDistanceSum * 0.1d, -nonMatchingPixels * 0.05d, +(glyph.Bitmap.Width < 8 ? -5d + (glyph.Bitmap.Width * 0.5d) : 20 + (glyph.Bitmap.Width - 8) * 0.5), +estimatedWidthBonus * 19d, (glyph.Bitmap.Width < 8 && estimatedWidthBonus < 0.5) ? -10 : 0, (glyph.Bitmap.Width <8 && estimatedWidthBonus> 0.5) ? 10 : 0, glyphPixelNum * 0.075, }; double score = 0f; foreach (double scorePart in scoreParts) { if (!Double.IsNaN(scorePart)) { score += scorePart; } else { } } return(score); }