コード例 #1
0
        private static string getStringFromLevelCodeImage(Image <Bgr, byte> image)
        {
            Image <Gray, byte> ocrReadyImage = ImageLibrary.PrepareImageForOCR(image);

            ocrReadyImage = cropLineOfText(ocrReadyImage, new Size(37, 3));
            List <Mat> characters = segmentCharacters(ocrReadyImage);

            // 11 characters expected in a level code (XXX-XXX-XXX)
            if (characters.Count == 11)
            {
                // Remove the dashes
                characters.RemoveAt(7);
                characters.RemoveAt(3);

                string levelCode = doOCROnCharacterImages(characters, "0123456789ABCDEFGHJKLMNPQRSTUVWXY");

                // format code
                levelCode = $"{levelCode.Substring(0, 3)}-{levelCode.Substring(3, 3)}-{levelCode.Substring(6, 3)}";

                return(levelCode);
            }
            else
            {
                // fallback to original OCR if segmentation has unexpected number of characters
                log.Debug($"segmentChacters - level code - detected {characters.Count} characters, falling back to original OCR method");
                return(doOCROnLevelCodeImage(ocrReadyImage));
            }
        }
コード例 #2
0
 private static string getStringFromImage(Image <Bgr, byte> image)
 {
     using (Image <Gray, byte> ocrReadyImage = ImageLibrary.PrepareImageForOCR(image))
     {
         return(doOCROnImage(ocrReadyImage));
     }
 }
コード例 #3
0
ファイル: OCRLibrary.cs プロジェクト: Vukkk/MarioMaker2OCR
        /// <summary>
        /// Read clear time from frame
        /// </summary>
        /// <param name="frame"></param>
        /// <param name="commentsEnabled">If true, then use a different screen region to scan for time</param>
        /// <returns></returns>
        internal static string GetClearTimeFromFrame(Image <Bgr, byte> frame, bool commentsEnabled)
        {
            // Update boundry sizes relative to the current resolution
            int idx = commentsEnabled ? 1 : 0;

            clearTimeBoundry = ImageLibrary.ChangeSize(clearTimeBoundry720[idx], resolution720, frame.Size);

            // Set ROI
            frame.ROI = clearTimeBoundry;

            // Prepare Image for OCR
            Image <Gray, byte> ocrReadyImage = ImageLibrary.PrepareImageForOCR(frame);

            // Segment characters
            List <Mat> characters = segmentCharacters(ocrReadyImage);

            frame.ROI = Rectangle.Empty;

            // expect time to be 9 characters, quote reads as 2 chars (ex: 01'34''789)
            if (characters.Count == 10)
            {
                // Different Time Formats
                // 12:34,567 | 12:34.567 | 12'34"567

                // Remove punctuation - can identify by height
                // Make relative to max character size incase we ever resize images.
                int maxCharHeight = characters.Max(p => p.Height);
                int minimumHeight = (int)Math.Floor(maxCharHeight * .60);
                characters.RemoveAll(p => p.Height < minimumHeight);

                // Do OCR
                string clearTime = doOCROnCharacterImages(characters, "0123456789");

                // format clear time
                try
                {
                    if (clearTime.Length >= 7)
                    {
                        clearTime = $"{clearTime.Substring(0, 2)}'{clearTime.Substring(2, 2)}\"{clearTime.Substring(4, 3)}";
                    }
                }
                catch (ArgumentOutOfRangeException ex)
                {
                    log.Error($"ArgumentOutOfRangeException formatting clear time: {clearTime}");
                    clearTime = "";
                }
                return(clearTime);
            }
            else
            {
                log.Debug($"segmentChacters for time - {characters.Count} characters detected, expected 10, falling back to original OCR method");
                return(doOCROnImage(ocrReadyImage));
            }
        }
コード例 #4
0
ファイル: OCRLibrary.cs プロジェクト: Vukkk/MarioMaker2OCR
        private static string getStringFromLevelCodeImage(Image <Bgr, byte> image)
        {
            Image <Gray, byte> ocrReadyImage = null;
            Image <Gray, byte> croppedImage  = null;

            try
            {
                ocrReadyImage = ImageLibrary.PrepareImageForOCR(image);
                croppedImage  = cropLineOfText(ocrReadyImage, new Size(37, 3));
                List <Mat> characters = segmentCharacters(croppedImage);

                // 11 characters expected in a level code (XXX-XXX-XXX)
                if (characters.Count == 11)
                {
                    // Remove the dashes
                    characters.RemoveAt(7);
                    characters.RemoveAt(3);

                    string levelCode = doOCROnCharacterImages(characters, "0123456789ABCDEFGHJKLMNPQRSTUVWXY");

                    // format code
                    levelCode = $"{levelCode.Substring(0, 3)}-{levelCode.Substring(3, 3)}-{levelCode.Substring(6, 3)}";

                    return(levelCode);
                }
                else
                {
                    // before falling back to line based OCR, take one more shot at saving this code with segmenting characters.
                    // This is an extremely crude method which will split character images in half if they are much wider than
                    // median char width. This is needed for adjacent "TT" characters in a level code.
                    if (characters.Count < 11 && characters.Count > 7)
                    {
                        log.Debug($"getStringFromLevelCodeImage - level code - detected {characters.Count} characters, manually splitting larger characters");

                        // Remove dashes - can identify by height
                        int maxCharHeight = characters.Max(p => p.Height);
                        int minimumHeight = (int)Math.Floor(maxCharHeight * .60);
                        characters.RemoveAll(p => p.Height < minimumHeight);

                        double medianCharacterWidth = characters.OrderBy(p => p.Width).Skip(characters.Count / 2).Take(1).FirstOrDefault().Width;

                        for (int i = 0; i < characters.Count; i++)
                        {
                            var character = characters[i];

                            double perc = medianCharacterWidth / character.Width;

                            // Current letter is significantly larger than median width
                            if (perc < .65)
                            {
                                Rectangle leftRect  = new Rectangle(0, 0, character.Width / 2, character.Height);
                                Rectangle rightRect = new Rectangle(character.Width / 2, 0, character.Width / 2, character.Height);

                                // Left character
                                Mat leftCharacter = new Mat(character, leftRect);
                                // Right character
                                characters[i] = new Mat(character, rightRect);

                                // Insert left character into array
                                characters.Insert(i, leftCharacter);
                            }

                            // If there are 9 characters then we are done
                            if (characters.Count == 9)
                            {
                                break;
                            }
                        }

                        string levelCode = doOCROnCharacterImages(characters, "0123456789ABCDEFGHJKLMNPQRSTUVWXY");
                        levelCode = $"{levelCode.Substring(0, 3)}-{levelCode.Substring(3, 3)}-{levelCode.Substring(6, 3)}";
                        return(levelCode);
                    }

                    // fallback to original OCR if segmentation has unexpected number of characters
                    log.Debug($"segmentChacters - level code - detected {characters.Count} characters, falling back to original OCR method");
                    return(doOCROnLevelCodeImage(ocrReadyImage));
                }
            }
            catch (Exception ex)
            {
                log.Error("Exception in getStringFromLevelCodeImage - " + ex.Message);
                return("");
            }
            finally
            {
                ocrReadyImage?.Dispose();
                croppedImage?.Dispose();
            }
        }
コード例 #5
0
ファイル: Form1.cs プロジェクト: underscore-zi/MarioMaker2OCR
        private static string getStringFromLevelCodeImage(Image <Bgr, byte> image)
        {
            Image <Gray, byte> ocrReadyImage = ImageLibrary.PrepareImageForOCR(image);

            return(OCRLibrary.GetStringFromLevelCodeImage(ocrReadyImage));
        }