Пример #1
0
        //МЕТОДЫ, ИСПОЛЬЗУЕМЫЕ ДЛЯ СОЗДАНИЯ ЭТАЛОНОВ
        //----------------------------------------------------------------
        //получить txt файлы для картинок с конкретными символами в папке
        private void CreateEtalonMatrix(object sender, EventArgs e)
        {
            //настроика диалога
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            DialogResult        result = folderBrowserDialog.ShowDialog();

            if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(folderBrowserDialog.SelectedPath))
            {
                string[] files = Directory.GetFiles(folderBrowserDialog.SelectedPath);

                foreach (string file in files)
                {
                    //считываем изображение из файла
                    System.Drawing.Bitmap image = new Bitmap(file);

                    //произведем бинаризацию изображения
                    BinarizedImage binarizedImage = new BinarizedImage(image);

                    //матрица эталонная для символа
                    byte[,] etalonArray = MyTextRecognizer.CreateMatrix_16X16(binarizedImage);

                    string fileName = Path.GetFileName(file);

                    fileName = fileName.Replace(".png", "");

                    MyArraySerializer.SerializeArray(etalonArray, new StreamWriter(txtPath + fileName + ".txt"));
                }
            }
        }
Пример #2
0
        private static Tuple <int, int> GetDividersY(BinarizedImage binarizedImage, Tuple <int, int> xBoundaries)
        {
            byte[,] imageArray = binarizedImage.GetArray();

            int yStart = binarizedImage.GetHeight(), yEnd = -1;

            for (int i = xBoundaries.Item1; i <= xBoundaries.Item2; ++i)
            {
                for (int j = 0; j < binarizedImage.GetHeight(); ++j)
                {
                    if (imageArray[i, j] == 1)
                    {
                        if (yStart > j)
                        {
                            yStart = j;
                        }
                        if (yEnd < j)
                        {
                            yEnd = j;
                        }
                    }
                }
            }

            return(new Tuple <int, int>(yStart - 1, yEnd + 1));
            //return new Tuple<int, int>(0, ImageBitmap.Height - 1);
        }
Пример #3
0
        //выбрать из проводника изображение для распознавания
        private void chooseImageFromExplorer(object sender, EventArgs e)
        {
            //настроика диалога
            openFileDialog.InitialDirectory = "c:\\";
            openFileDialog.Filter           = "png files (*.png)|*.png|All files (*.*)|*.*";
            openFileDialog.FilterIndex      = 2;
            openFileDialog.RestoreDirectory = true;

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                //путь к файлу
                String filePath = openFileDialog.FileName;

                //считываем изображение из файла
                System.Drawing.Bitmap image = new Bitmap(filePath);

                //очистим полотно
                //canvas.Clear(Color.FromArgb(110, 110, 110));
                //отрисуем картинку на полотне
                //canvas.DrawImage(image, new PointF(20, 20));

                //бинаризация изображения
                BinarizedImage binarizedImage = new BinarizedImage(image);

                //отрисуем бинаризованную картинку на полотне
                //canvas.DrawImage(binarizedImageBitmap, new PointF(20, binarizedImageBitmap.Size.Height+40));
                //imageSaver.Save(binarizedImage.GetBitmap(), "binarizedImage.png");

                //моздаем объект - распознаватель
                MyTextRecognizer recognizer = new MyTextRecognizer();

                //разделение изображения на отдельные символы
                List <Symbol> symbols = MyTextRecognizer.GetSymbols(binarizedImage);

                //результат распознавания
                recognitionResultTextbox.Text = "";

                int count = 0;
                foreach (Symbol symbol in symbols)
                {
                    symbol.Print();
                    Console.WriteLine();

                    recognizer.RecognizeSymbol(symbol);

                    recognitionResultTextbox.Text = recognizer.;
                    count += 1;
                }
                //

                //recognitionResultTextbox.Text = MyTextRecognizer.RecognizeSymbol(MyTextRecognizer.CreateMatrix_16X16(binarizedImage));
            }
        }
Пример #4
0
        public BinarizedImage(BinarizedImage image, int xLeft, int xRight, int yTop, int yBottom)
        {
            N = xRight - xLeft + 1;
            M = yBottom - yTop + 1;

            Console.WriteLine("Создается биткарта размерами " + N + " x " + M);

            binarizedImageArray = new byte[N, M];

            for (int i = xLeft; i <= xRight; i++)
            {
                for (int j = yTop; j <= yBottom; j++)
                {
                    binarizedImageArray[i - xLeft, j - yTop] = image.GetArray()[i, j];
                }
            }
        }
Пример #5
0
        //устарело
        //-----------------------------------------------
        //получит список всех символов на изображении
        private static List <int> GetDividersX(BinarizedImage binarizedImage)
        {
            List <int> resultDivivderIndexes = new List <int>();

            byte[,] imageArray = binarizedImage.GetArray();
            int N = binarizedImage.GetWidth();
            int M = binarizedImage.GetHeight();

            //первый разделитель в промежтуке
            bool previousOnlyWhite = false;

            for (int i = 0; i < N; ++i)
            {
                bool currentOnlyWhite = true;

                for (int j = 0; j < M; ++j)
                {
                    currentOnlyWhite &= imageArray[i, j] == 0;
                }
                //переход с белого на чёрный
                if (currentOnlyWhite == false)
                {
                    /*if (i == 0 || i == N - 1) {
                     *  resultDivivderIndexes.Add(i);
                     * }*/
                    if (previousOnlyWhite == true)
                    {
                        resultDivivderIndexes.Add(i - 1);
                    }
                }
                //переход с чёрного на белый
                else
                {
                    //если первый столбец пикселей белый, значит мы не нашли изображение... пропускаем этот столбец
                    if (previousOnlyWhite == false && i != 0)
                    {
                        resultDivivderIndexes.Add(i);
                    }
                }
                previousOnlyWhite = currentOnlyWhite;
            }
            return(resultDivivderIndexes);
        }
Пример #6
0
        //-----------------------------------------------

        //получить список символов на картинке
        public static List <Symbol> GetSymbols(BinarizedImage binarizedImage)
        {
            List <Symbol> symbols = new List <Symbol>();

            List <Rectangle> symbolsBoundaries = GetSymbolsBoundaries(binarizedImage);

            foreach (Rectangle rect in symbolsBoundaries)
            {
                //Console.WriteLine("DividerX: "+dividerX.Item1+", "+dividerX.Item2);
                //Console.WriteLine("DividerY: " + dividerY.Item1 + ", " + dividerY.Item2);

                BinarizedImage image = new BinarizedImage(binarizedImage, rect.Left, rect.Right - 1, rect.Top, rect.Bottom);

                Symbol symbol = new Symbol(rect.Left, rect.Top, rect.Width, rect.Height, CreateMatrix_16X16(image));

                symbols.Add(symbol);
            }

            return(symbols);
        }
Пример #7
0
        //получить границы символов на изображении с множеством символов
        private static List <Rectangle> GetSymbolsBoundaries(BinarizedImage binarizedImage)
        {
            List <Rectangle> symbolsBoundaries = new List <Rectangle>();

            byte[,] imageArray = binarizedImage.GetArray();
            int N = binarizedImage.GetWidth();
            int M = binarizedImage.GetHeight();

            //первый разделитель в промежтуке
            bool previousOnlyWhite = false;

            int Left = -1, Right = -1, Top = -1, Bottom = -1, Counter = 0;

            for (int i = 0; i < N; ++i)
            {
                bool currentOnlyWhite = true;

                for (int j = 0; j < M; ++j)
                {
                    currentOnlyWhite &= imageArray[i, j] == 0;
                }
                //переход с белого на чёрный
                if (currentOnlyWhite == false)
                {
                    /*if (i == 0 || i == N - 1) {
                     *  resultDivivderIndexes.Add(i);
                     * }*/
                    if (previousOnlyWhite == true)
                    {
                        Counter += 1;
                        Left     = i - 1;
                    }
                }
                //переход с чёрного на белый
                else
                {
                    //если первый столбец пикселей белый, значит мы не нашли изображение... пропускаем этот столбец
                    if (previousOnlyWhite == false && i != 0)
                    {
                        Counter += 1;
                        Right    = i;
                    }
                }
                previousOnlyWhite = currentOnlyWhite;

                if (Counter == 2)
                {
                    Top    = binarizedImage.GetHeight();
                    Bottom = -1;

                    for (int k = Left; k <= Right; ++k)
                    {
                        for (int l = 0; l < binarizedImage.GetHeight(); ++l)
                        {
                            if (imageArray[k, l] == 1)
                            {
                                if (Top > l)
                                {
                                    Top = l;
                                }
                                if (Bottom < l)
                                {
                                    Bottom = l;
                                }
                            }
                        }
                    }

                    Counter = 0;

                    Console.WriteLine("l: " + Left + ", \tr: " + Right + ", \tt: " + Top + ", \tb: " + Bottom);

                    symbolsBoundaries.Add(new Rectangle(Left, Top - 1, Right - Left + 1, Bottom - Top + 2));
                }
            }

            return(symbolsBoundaries);
        }
Пример #8
0
        //создать матрицу 16*16 для картинки с конкретным символом
        public static byte[,] CreateMatrix_16X16(BinarizedImage binarizedImage)
        {
            int N = binarizedImage.GetWidth();
            int M = binarizedImage.GetHeight();

            byte[,] binarizedImageArray = binarizedImage.GetArray();


            //==========================================================
            //НАХОЖДЕНИЕ ГРАНИЦ СИМВОЛА

            //----------------------------------------------------------
            //поиск верхней границы символа

            int yTop = -1;

            //цикл по вертикали(y)
            for (int j = 0; j < M; j++)
            {
                //цикл по горизонтали(x)
                for (int i = 0; i < N; i++)
                {
                    //встретился черный пиксель - верхняя граница найдена
                    if (binarizedImageArray[i, j] == 1)
                    {
                        yTop = j;
                        break;
                    }
                }
                if (yTop == j)
                {
                    break;
                }
            }
            //----------------------------------------------------------

            //----------------------------------------------------------
            //поиск нижней границы символа

            int yBottom = -1;

            //цикл по вертикали(y)
            for (int j = M - 1; j >= 0; j--)
            {
                //цикл по горизонтали(x)
                for (int i = 0; i < N; i++)
                {
                    //встретился черный пиксель - нижняя граница найдена
                    if (binarizedImageArray[i, j] == 1)
                    {
                        yBottom = j + 1;
                        break;
                    }
                }
                if (yBottom == j + 1)
                {
                    break;
                }
            }
            //----------------------------------------------------------

            //----------------------------------------------------------
            //поиск левой границы символа

            int xLeft = -1;

            //цикл по горизонтали(x)
            for (int i = 0; i < N; i++)
            {
                //цикл по вертикали(y)
                for (int j = 0; j < M; j++)
                {
                    //встретился черный пиксель - левая граница найдена
                    if (binarizedImageArray[i, j] == 1)
                    {
                        xLeft = i;
                        break;
                    }
                }
                if (xLeft == i)
                {
                    break;
                }
            }
            //----------------------------------------------------------

            //----------------------------------------------------------
            //поиск правой границы символа

            int xRight = -1;

            //цикл по горизонтали(x)
            for (int i = N - 1; i >= 0; i--)
            {
                //цикл по вертикали(y)
                for (int j = 0; j < M; j++)
                {
                    //встретился черный пиксель - правая граница найдена
                    if (binarizedImageArray[i, j] == 1)
                    {
                        xRight = i + 1;
                        break;
                    }
                }
                if (xRight == i + 1)
                {
                    break;
                }
            }
            //----------------------------------------------------------


            //==========================================================

            //границы символа не найденв => ничего не нарисовано
            if (((yBottom - yTop) * (xRight - xLeft)) == 0)
            {
                Console.WriteLine("EtalonCreator: image has no symbol to bound it");
                return(null);
            }

            //==========================================================
            // получаем процент заполнения как отношение кол-ва значимых пикселей к общему
            // кол-ву пикселей в границах образа
            // Percent будет необходим при анализе каждой ячейки в разбитом на 16х16 образе

            //количество черных пикселей на изображении
            int nSymbol = 0;

            for (int j = yTop; j <= yBottom; j++)
            {
                for (int i = xLeft; i <= xRight; i++)
                {
                    if (binarizedImageArray[i, j] == 1)
                    {
                        nSymbol += 1;
                    }
                }
            }

            double percent = (double)nSymbol / ((yBottom - yTop) * (xRight - xLeft));

            // коэф-т влияет на формирование матрицы 16х16
            // > 1 - учитывается меньше значимых пикселей
            // < 1 - учитывается больше значимых пикселей
            percent *= 0.99;
            //==========================================================
            //==========================================================
            // разбиваем прямоугольник образа на 16 равных частей путем деления сторон на 2
            // и получаем относительные координаты каждой ячейки

            //ширина прямоугольника вокруг изображения
            int symbolWidth = xRight - xLeft;

            int[,] XY = new int[17, 2];
            XY[0, 0]  = 0;
            XY[16, 0] = symbolWidth;
            XY[8, 0]  = XY[16, 0] / 2;
            XY[4, 0]  = XY[8, 0] / 2;
            XY[2, 0]  = XY[4, 0] / 2;
            XY[1, 0]  = XY[2, 0] / 2;
            XY[3, 0]  = (XY[4, 0] + XY[2, 0]) / 2;
            XY[6, 0]  = (XY[8, 0] + XY[4, 0]) / 2;
            XY[5, 0]  = (XY[6, 0] + XY[4, 0]) / 2;
            XY[7, 0]  = (XY[8, 0] + XY[6, 0]) / 2;
            XY[12, 0] = (XY[16, 0] + XY[8, 0]) / 2;
            XY[10, 0] = (XY[12, 0] + XY[8, 0]) / 2;
            XY[14, 0] = (XY[16, 0] + XY[12, 0]) / 2;
            XY[9, 0]  = (XY[10, 0] + XY[8, 0]) / 2;
            XY[11, 0] = (XY[12, 0] + XY[10, 0]) / 2;
            XY[13, 0] = (XY[14, 0] + XY[12, 0]) / 2;
            XY[15, 0] = (XY[16, 0] + XY[14, 0]) / 2;

            //высота образа
            int symbolHeight = yBottom - yTop;

            XY[0, 1]  = 0;
            XY[16, 1] = symbolHeight;
            XY[8, 1]  = XY[16, 1] / 2;
            XY[4, 1]  = XY[8, 1] / 2;
            XY[2, 1]  = XY[4, 1] / 2;
            XY[1, 1]  = XY[2, 1] / 2;
            XY[3, 1]  = (XY[4, 1] + XY[2, 1]) / 2;
            XY[6, 1]  = (XY[8, 1] + XY[4, 1]) / 2;
            XY[5, 1]  = (XY[6, 1] + XY[4, 1]) / 2;
            XY[7, 1]  = (XY[8, 1] + XY[6, 1]) / 2;
            XY[12, 1] = (XY[16, 1] + XY[8, 1]) / 2;
            XY[10, 1] = (XY[12, 1] + XY[8, 1]) / 2;
            XY[14, 1] = (XY[16, 1] + XY[12, 1]) / 2;
            XY[9, 1]  = (XY[10, 1] + XY[8, 1]) / 2;
            XY[11, 1] = (XY[12, 1] + XY[10, 1]) / 2;
            XY[13, 1] = (XY[14, 1] + XY[12, 1]) / 2;
            XY[15, 1] = (XY[16, 1] + XY[14, 1]) / 2;
            //==========================================================

            //==========================================================
            // анализируем каждую полученную ячейку в разбитом прямоугольнике образа
            // и создаем приведенную матрицу 16x16

            // результат - приведенная матрица 16х16
            byte[,] result = new byte[16, 16];

            // пробегаемся по ячейкам уже
            // в абсолютных координатах
            // считаем кол-во значимых пикселей (=0 -> черный цвет)
            for (int kj = 0; kj < 16; kj++)
            {
                for (int ki = 0; ki < 16; ki++)
                {
                    nSymbol = 0;
                    for (int j = yTop + XY[kj, 1]; j <= yTop + XY[kj + 1, 1]; j++)
                    {
                        for (int i = xLeft + XY[ki, 0]; i <= xLeft + XY[ki + 1, 0]; i++)
                        {
                            if (binarizedImageArray[i, j] == 1)
                            {
                                nSymbol += 1;
                            }
                        }
                    }

                    // если отношение кол-ва знач. пикселей к общему кол-ву в ящейке > характерного процента заполнения то = 1 иначе = 0
                    if (nSymbol / Math.Max(1, ((XY[ki + 1, 0] - XY[ki, 0]) * (XY[kj + 1, 1] - XY[kj, 1]))) > percent)
                    {
                        result[kj, ki] = 1;
                    }
                    else
                    {
                        result[kj, ki] = 0;
                    }
                }
            }
            //==========================================================

            return(result);
        }