ARKBreedingStats.ArkOCR.readImage C# (CSharp) Method

readImage() private method

private readImage ( int resolution, Bitmap source, bool onlyMaximalMatches, bool onlyNumbers, bool writingInWhite = true ) : string
resolution int
source System.Drawing.Bitmap
onlyMaximalMatches bool
onlyNumbers bool
writingInWhite bool
return string
        private string readImage(int resolution, Bitmap source, bool onlyMaximalMatches, bool onlyNumbers, bool writingInWhite = true)
        {
            string result = "";
            Bitmap[,] theAlphabet = alphabet;

            if (onlyNumbers)
                theAlphabet = reducedAlphabet;

            Bitmap cleanedImage = removePixelsUnderThreshold(GetGreyScale(source, !writingInWhite), whiteThreshold);
            AddBitmapToDebug(cleanedImage);
            //source.Save("D:\\temp\\debug.png"); // TODO comment out
            //cleanedImage.Save("D:\\temp\\debug_cleaned.png");// TODO comment out

            for (int x = 0; x < cleanedImage.Width; x++)
            {
                bool foundLetter = false;
                int letterStart = 0;
                int letterEnd = 0;

                // look for the start pixel of the letter
                while (!(foundLetter == true || x >= cleanedImage.Width))
                {
                    foundLetter = HasWhiteInVerticalLine(cleanedImage, x);
                    x++;
                }

                if (foundLetter)
                {
                    letterStart = x - 1;
                    // look for the end of the letter
                    do
                    {
                        x++;
                    } while (HasWhiteInVerticalLine(cleanedImage, x) && x < cleanedImage.Width - 1);
                    letterEnd = x;
                }
                if (letterEnd > cleanedImage.Width)
                    letterEnd = cleanedImage.Width;

                if (letterStart != letterEnd)
                {
                    // found a letter, see if a match can be found
                    Rectangle letterR = letterRect(cleanedImage, letterStart, letterEnd);
                    if (letterR.Width > 0 && letterR.Height > 0)
                    {
                        Bitmap testImage = SubImage(cleanedImage, letterR.Left, letterR.Top, letterR.Width, letterR.Height);
                        //testImage.Save("D:\\temp\\debug_letterfound.png");// TODO comment out
                        Dictionary<int, float> matches = new Dictionary<int, float>();
                        float bestMatch = 0;
                        for (int l = 0; l < theAlphabet.GetLength(1); l++)
                        {
                            float match = 0;
                            if (theAlphabet[resolution, l] != null)
                                match = (float)(PercentageMatch(theAlphabet[resolution, l], testImage) * charWeighting[l]);
                            else
                                continue;

                            if (match > 0.5)
                            {
                                matches[l] = match;
                                if (bestMatch < match)
                                    bestMatch = match;
                            }
                        }

                        if (matches.Count == 0)
                            continue;

                        Dictionary<int, float> goodMatches = new Dictionary<int, float>();

                        if (matches.Count == 1)
                            goodMatches = matches;
                        else
                        {
                            foreach (KeyValuePair<int, float> kv in matches)
                                if (kv.Value > 0.95 * bestMatch)
                                    goodMatches[kv.Key] = kv.Value; // discard matches that are not at least 95% as good as the best match
                        }

                        //// debugging / TODO
                        //// save recognized image and two best matches with percentage
                        //Bitmap debugImg = new Bitmap(200, 50);
                        //using (Graphics g = Graphics.FromImage(debugImg))
                        //{
                        //    g.FillRectangle(Brushes.DarkCyan, 0, 0, debugImg.Width, debugImg.Height);
                        //    g.DrawImage(testImage, 1, 1, testImage.Width, testImage.Height);
                        //    int i = testImage.Width + 25;
                        //    Font font = new Font("Arial", 8);

                        //    foreach (int l in goodMatches.Keys)
                        //    {
                        //        g.DrawImage(theAlphabet[resolution, l], i, 1, theAlphabet[resolution, l].Width, theAlphabet[resolution, l].Height);
                        //        g.DrawString(Math.Round(goodMatches[l] * 100).ToString(), font, (bestMatch == goodMatches[l] ? Brushes.DarkGreen : Brushes.DarkRed), i, 35);
                        //        i += theAlphabet[resolution, l].Width + 15;
                        //    }
                        //    debugImg.Save("D:\\temp\\debug_letter" + DateTime.Now.ToString("HHmmss\\-fffffff\\-") + x + ".png");
                        //}
                        //// end debugging

                        if (goodMatches.Count == 1)
                            result += (char)(goodMatches.Keys.ToArray()[0]);
                        else
                        {
                            if (onlyMaximalMatches)
                            {
                                foreach (int l in goodMatches.Keys)
                                {
                                    if (goodMatches[l] == bestMatch)
                                    {
                                        result += (char)l;
                                        break; // if there are multiple best matches take only the first
                                    }
                                }
                            }
                            else
                            {
                                result += "[";
                                foreach (int l in goodMatches.Keys)
                                    result += (char)l + goodMatches[l].ToString("{0.00}") + " ";
                                result += "]";
                            }
                        }
                    }
                }
            }

            // replace half letters.
            result = result.Replace((char)15 + "n", "n");
            result = result.Replace((char)16 + "lK", "K");

            return result;
        }