예제 #1
0
        public BarcodeCorrection(OmrPageOutput page, OmrBarcodeField barcode)
        {
            this.m_page         = page;
            this.m_expectedArea = barcode;
            InitializeComponent();

            // Crop the image
            String tPath = Path.GetTempFileName();

            using (Bitmap bmp = new Bitmap((int)barcode.TopRight.X - (int)barcode.TopLeft.X, (int)barcode.BottomLeft.Y - (int)barcode.TopLeft.Y, PixelFormat.Format24bppRgb))
                using (Graphics g = Graphics.FromImage(bmp))
                    using (Image img = Image.FromFile(this.m_page.AnalyzedImage))
                    {
                        g.DrawImage(img, 0, 0, new Rectangle(new Point((int)barcode.TopLeft.X, (int)barcode.TopLeft.Y), bmp.Size), GraphicsUnit.Pixel);
                        bmp.Save(tPath);
                    }

            // Rotate
            using (Image img = Image.FromFile(tPath))
                using (var rotated = new AForge.Imaging.Filters.RotateBilinear(-90).Apply((Bitmap)img))
                    using (var scaled = new AForge.Imaging.Filters.ResizeBilinear((int)(rotated.Width * 0.75), (int)(rotated.Height * .75)).Apply(rotated))
                    {
                        tPath = Path.GetTempFileName();
                        scaled.Save(tPath);
                        pbBarcode.ImageLocation = tPath;
                    }
        }
예제 #2
0
        /// <summary>
        /// Обработка одного сэмпла
        /// </summary>
        /// <param name="index"></param>
        private int processSample(int r, int c)
        {
            ///  Инвертируем изображение
            AForge.Imaging.Filters.Invert InvertFilter = new AForge.Imaging.Filters.Invert();
            InvertFilter.ApplyInPlace(arrayPics[r, c]);

            ///    Создаём BlobCounter, выдёргиваем самый большой кусок, масштабируем, пересечение и сохраняем
            ///    изображение в эксклюзивном использовании
            AForge.Imaging.BlobCounterBase bc = new AForge.Imaging.BlobCounter();

            bc.FilterBlobs = true;
            bc.MinWidth    = 3;
            bc.MinHeight   = 3;
            // Упорядочиваем по размеру
            bc.ObjectsOrder = AForge.Imaging.ObjectsOrder.Size;
            // Обрабатываем картинку

            bc.ProcessImage(arrayPics[r, c]);

            Rectangle[] rects = bc.GetObjectsRectangles();
            if (rects.Length == 0)
            {
                finalPics[r, c] = AForge.Imaging.UnmanagedImage.FromManagedImage(new Bitmap(100, 100));
                return(0);
            }

            // К сожалению, код с использованием подсчёта blob'ов не работает, поэтому просто высчитываем максимальное покрытие
            // для всех блобов - для нескольких цифр, к примеру, 16, можем получить две области - отдельно для 1, и отдельно для 6.
            // Строим оболочку, включающую все блоки. Решение плохое, требуется доработка
            int lx = arrayPics[r, c].Width;
            int ly = arrayPics[r, c].Height;
            int rx = 0;
            int ry = 0;

            for (int i = 0; i < rects.Length; ++i)
            {
                if (lx > rects[i].X)
                {
                    lx = rects[i].X;
                }
                if (ly > rects[i].Y)
                {
                    ly = rects[i].Y;
                }
                if (rx < rects[i].X + rects[i].Width)
                {
                    rx = rects[i].X + rects[i].Width;
                }
                if (ry < rects[i].Y + rects[i].Height)
                {
                    ry = rects[i].Y + rects[i].Height;
                }
            }

            // Обрезаем края, оставляя только центральные блобчики
            AForge.Imaging.Filters.Crop cropFilter = new AForge.Imaging.Filters.Crop(new Rectangle(lx, ly, rx - lx, ry - ly));
            finalPics[r, c] = cropFilter.Apply(arrayPics[r, c]);

            //  Масштабируем до 100x100
            AForge.Imaging.Filters.ResizeBilinear scaleFilter = new AForge.Imaging.Filters.ResizeBilinear(100, 100);
            finalPics[r, c] = scaleFilter.Apply(finalPics[r, c]);

            //  Ну и распознаём
            currentDeskState[r * 4 + c] = patternMatch(r, c);

            return(0);
        }
예제 #3
0
        public void ProcessImage(Bitmap bitmap, bool justShow)
        {
            //  «Распиливаем» изображение на 16 фрагментов - по отдельной плитке каждый

            //  Минимальная сторона изображения (обычно это высота)
            if (bitmap.Height > bitmap.Width)
            {
                throw new Exception("К такой забавной камере меня жизнь не готовила!");
            }
            int side = bitmap.Height;

            //  Отпиливаем границы, но не более половины изображения
            if (side < 4 * settings.border)
            {
                settings.border = side / 4;
            }
            side -= 2 * settings.border;

            Rectangle cropRect = new Rectangle((bitmap.Width - bitmap.Height) / 2 + settings.border, settings.border, side, side);

            original = new Bitmap(cropRect.Width, cropRect.Height);

            //  Рисуем рамки на оригинале
            Graphics g = Graphics.FromImage(original);

            g.DrawImage(bitmap, new Rectangle(0, 0, original.Width, original.Height), cropRect, GraphicsUnit.Pixel); Pen p = new Pen(Color.Red);

            //  Проверяем значение полей из settings
            if (side < 10 * settings.margin)
            {
                settings.margin = side / 10;
            }

            //  Высчитываем сторону блока для извлечения
            int sz        = side / 4 - 2 * settings.margin;
            int blockSide = side / 4;

            for (int r = 0; r < 4; ++r)
            {
                for (int c = 0; c < 4; ++c)
                {
                    g.DrawRectangle(p, new Rectangle(settings.margin + c * blockSide, settings.margin + r * blockSide, sz, sz));
                }
            }

            //  Рисуем цифры, которые распознались на предыдущем шаге?
            if (justShow)
            {
                DrawNumbersOnOriginalBitmap(g, blockSide);
            }

            //  Конвертируем изображение в градации серого
            AForge.Imaging.Filters.Grayscale grayFilter = new AForge.Imaging.Filters.Grayscale(0.2125, 0.7154, 0.0721);
            processed = grayFilter.Apply(AForge.Imaging.UnmanagedImage.FromManagedImage(original));

            //  Масштабируем изображение до 500x500 - этого достаточно
            AForge.Imaging.Filters.ResizeBilinear scaleFilter = new AForge.Imaging.Filters.ResizeBilinear(500, 500);
            original = scaleFilter.Apply(original);

            //  Если распознавание не планируем – просто выход
            if (justShow)
            {
                return;
            }

            //  Обнуляем state
            for (int i = 0; i < 16; ++i)
            {
                currentDeskState[i] = 0;
            }

            //  Пороговый фильтр применяем. Величина порога берётся из настроек, и меняется на форме
            AForge.Imaging.Filters.BradleyLocalThresholding threshldFilter = new AForge.Imaging.Filters.BradleyLocalThresholding();
            threshldFilter.PixelBrightnessDifferenceLimit = settings.differenceLim;
            threshldFilter.ApplyInPlace(processed);

            for (int r = 0; r < 4; ++r)
            {
                for (int c = 0; c < 4; ++c)
                {
                    //  Берём очередной фрагмент - с дополнительными отступами (мы же там нарисовали прямоугольники)
                    AForge.Imaging.Filters.Crop cropFilter = new AForge.Imaging.Filters.Crop(new Rectangle(2 + settings.margin + c * blockSide, 2 + settings.margin + r * blockSide, sz - 4, sz - 4));
                    arrayPics[r, c] = cropFilter.Apply(processed);

                    //arrayPics[r, c] = processed.Clone(new Rectangle(2+settings.margin + c * blockSide, 2+settings.margin + r * blockSide, sz-4, sz-4), processed.PixelFormat);
                    //  И выполняем сопоставление
                    processSample(r, c);
                }
            }
            DrawNumbersOnOriginalBitmap(g, blockSide);
        }
예제 #4
0
        //przygotowanie do procesu ustawiania pozycji obrazu przez użytkownika
        public void pre_ocr(String file)
        {
            Bitmap source = (Bitmap)Bitmap.FromFile(file);
            int resX = 0;
            int resY = 0;
            //rozróżnianie obrazów poziomych od pionowych
            if (source.Width >= source.Height)
            {
                resX = 200;
                resY = (int)((source.Height * 200) / source.Width);
            }
            else
            {
                resX = (int)((source.Width * 200) / source.Height);
                resY = 200;
            }
            AForge.Imaging.Filters.ResizeBilinear resTool = new AForge.Imaging.Filters.ResizeBilinear(resX, resY);
            source = resTool.Apply(source);
            //source.Dispose();
            source.Save(Server.MapPath("~/img/prev.bmp"));

            //source.Dispose();
            Image1.Width = resX;
            Image1.Height = resY;
            Image1.ImageUrl = "img/prev.bmp";

            Panel1.Visible = true;
        }
예제 #5
0
        private Bitmap resize(Bitmap image, int newWidth, int newHeight)
        {
            if (KeepAspectRatio)
            {

                double ratio = (double)newHeight / (double)image.Height;
                newWidth = (int)((double)image.Width * ratio);

            }

            AForge.Imaging.Filters.Crop cropper = new AForge.Imaging.Filters.Crop(new Rectangle(0, 0, newWidth, newHeight));

            if (ScalingMethod == ScalingMethods.Nearest_Neighbor || ScalingMethod == ScalingMethods.Bicubic)
            {
                AForge.Imaging.Filters.ResizeNearestNeighbor resizer = new AForge.Imaging.Filters.ResizeNearestNeighbor(newWidth, newHeight);
                image = cropper.Apply(resizer.Apply((Bitmap)image));
            }
            if (ScalingMethod == ScalingMethods.Bicubic)
            {
                MessageBox.Show("Bicubic resize is not implimented for now.\nNReverting to nearest neighbor...");
                //AForge.Imaging.Filters.ResizeBicubic resizer = new AForge.Imaging.Filters.ResizeBicubic(newWidth, newHeight);
                //image = cropper.Apply(resizer.Apply((Bitmap)image));
            }
            if (ScalingMethod == ScalingMethods.Bilinear)
            {
                AForge.Imaging.Filters.ResizeBilinear resizer = new AForge.Imaging.Filters.ResizeBilinear(newWidth, newHeight);
                image = cropper.Apply(resizer.Apply((Bitmap)image));
            }

            return image;
        }
예제 #6
0
        private Bitmap resize(Bitmap image, int newWidth, int newHeight)
        {
            if (keepAspectRatio)
            {

                double ratio = (double)newHeight / (double)image.Height;
                newWidth = (int)((double)image.Width * ratio);

            }

            AForge.Imaging.Filters.Crop cropper = new AForge.Imaging.Filters.Crop(new Rectangle(0, 0, newWidth, newHeight));

            if (cmbScalingMethod.SelectedIndex == 0)
            {
                AForge.Imaging.Filters.ResizeNearestNeighbor resizer = new AForge.Imaging.Filters.ResizeNearestNeighbor(newWidth, newHeight);
                image = cropper.Apply(resizer.Apply((Bitmap)image));
            }
            if (cmbScalingMethod.SelectedIndex == 1)
            {
                AForge.Imaging.Filters.ResizeBicubic resizer = new AForge.Imaging.Filters.ResizeBicubic(newWidth, newHeight);
                image = cropper.Apply(resizer.Apply((Bitmap)image));
            }
            if (cmbScalingMethod.SelectedIndex == 2)
            {
                AForge.Imaging.Filters.ResizeBilinear resizer = new AForge.Imaging.Filters.ResizeBilinear(newWidth, newHeight);
                image = cropper.Apply(resizer.Apply((Bitmap)image));
            }

            return image;
        }
예제 #7
0
        /// <summary>
        /// Обработка одного сэмпла
        /// </summary>
        /// <param name="index"></param>
        public static string processSample(ref Imaging.UnmanagedImage unmanaged)
        {
            string rez = "Обработка";

            ///  Инвертируем изображение
            AForge.Imaging.Filters.Invert InvertFilter = new AForge.Imaging.Filters.Invert();
            InvertFilter.ApplyInPlace(unmanaged);

            ///    Создаём BlobCounter, выдёргиваем самый большой кусок, масштабируем, пересечение и сохраняем
            ///    изображение в эксклюзивном использовании
            AForge.Imaging.BlobCounterBase bc = new AForge.Imaging.BlobCounter();

            bc.FilterBlobs = true;
            bc.MinWidth    = 10;
            bc.MinHeight   = 10;
            // Упорядочиваем по размеру
            bc.ObjectsOrder = AForge.Imaging.ObjectsOrder.Size;
            // Обрабатываем картинку

            bc.ProcessImage(unmanaged);

            Rectangle[] rects = bc.GetObjectsRectangles();
            rez = "Насчитали " + rects.Length.ToString() + " прямоугольников!";
            //if (rects.Length == 0)
            //{
            //    finalPics[r, c] = AForge.Imaging.UnmanagedImage.FromManagedImage(new Bitmap(100, 100));
            //    return 0;
            //}

            // К сожалению, код с использованием подсчёта blob'ов не работает, поэтому просто высчитываем максимальное покрытие
            // для всех блобов - для нескольких цифр, к примеру, 16, можем получить две области - отдельно для 1, и отдельно для 6.
            // Строим оболочку, включающую все блоки. Решение плохое, требуется доработка
            int lx = unmanaged.Width;
            int ly = unmanaged.Height;
            int rx = 0;
            int ry = 0;

            for (int i = 0; i < rects.Length; ++i)
            {
                if (lx > rects[i].X)
                {
                    lx = rects[i].X;
                }
                if (ly > rects[i].Y)
                {
                    ly = rects[i].Y;
                }
                if (rx < rects[i].X + rects[i].Width)
                {
                    rx = rects[i].X + rects[i].Width;
                }
                if (ry < rects[i].Y + rects[i].Height)
                {
                    ry = rects[i].Y + rects[i].Height;
                }
            }

            // Обрезаем края, оставляя только центральные блобчики
            AForge.Imaging.Filters.Crop cropFilter = new AForge.Imaging.Filters.Crop(new Rectangle(lx, ly, rx - lx, ry - ly));
            unmanaged = cropFilter.Apply(unmanaged);

            //  Масштабируем до 100x100
            AForge.Imaging.Filters.ResizeBilinear scaleFilter = new AForge.Imaging.Filters.ResizeBilinear(100, 100);
            unmanaged = scaleFilter.Apply(unmanaged);

            return(rez);
        }
예제 #8
0
        public bool ProcessImage(Bitmap bitmap)
        {
            // На вход поступает необработанное изображение с веб-камеры

            //  Минимальная сторона изображения (обычно это высота)
            if (bitmap.Height > bitmap.Width)
            {
                throw new Exception("К такой забавной камере меня жизнь не готовила!");
            }
            //  Можно было, конечено, и не кидаться эксепшенами в истерике, но идите и купите себе нормальную камеру!
            int side = bitmap.Height;

            //  Отпиливаем границы, но не более половины изображения
            if (side < 4 * settings.border)
            {
                settings.border = side / 4;
            }
            side -= 2 * settings.border;

            //  Мы сейчас занимаемся тем, что красиво оформляем входной кадр, чтобы вывести его на форму
            Rectangle cropRect = new Rectangle((bitmap.Width - bitmap.Height) / 2 + settings.left + settings.border, settings.top + settings.border, side, side);

            //  Тут создаём новый битмапчик, который будет исходным изображением
            original = new Bitmap(cropRect.Width, cropRect.Height);

            //  Объект для рисования создаём
            Graphics g = Graphics.FromImage(original);

            g.DrawImage(bitmap, new Rectangle(0, 0, original.Width, original.Height), cropRect, GraphicsUnit.Pixel);
            Pen p = new Pen(Color.Red);

            p.Width = 1;

            //  Теперь всю эту муть пилим в обработанное изображение
            AForge.Imaging.Filters.Grayscale grayFilter = new AForge.Imaging.Filters.Grayscale(0.2125, 0.7154, 0.0721);
            var uProcessed = grayFilter.Apply(AForge.Imaging.UnmanagedImage.FromManagedImage(original));


            int blockWidth  = original.Width / settings.blocksCount;
            int blockHeight = original.Height / settings.blocksCount;

            for (int r = 0; r < settings.blocksCount; ++r)
            {
                for (int c = 0; c < settings.blocksCount; ++c)
                {
                    //  Тут ещё обработку сделать
                    g.DrawRectangle(p, new Rectangle(c * blockWidth, r * blockHeight, blockWidth, blockHeight));
                }
            }


            //  Масштабируем изображение до 500x500 - этого достаточно
            AForge.Imaging.Filters.ResizeBilinear scaleFilter = new AForge.Imaging.Filters.ResizeBilinear(settings.orignalDesiredSize.Width, settings.orignalDesiredSize.Height);
            uProcessed = scaleFilter.Apply(uProcessed);
            original   = scaleFilter.Apply(original);
            g          = Graphics.FromImage(original);
            //  Пороговый фильтр применяем. Величина порога берётся из настроек, и меняется на форме
            AForge.Imaging.Filters.BradleyLocalThresholding threshldFilter = new AForge.Imaging.Filters.BradleyLocalThresholding();
            threshldFilter.PixelBrightnessDifferenceLimit = settings.differenceLim;
            threshldFilter.ApplyInPlace(uProcessed);


            if (settings.processImg)
            {
                string info = processSample(ref uProcessed);
                Font   f    = new Font(FontFamily.GenericSansSerif, 20);
                g.DrawString(info, f, Brushes.Black, 30, 30);
            }

            processed = uProcessed.ToManagedImage();

            return(true);
        }
예제 #9
0
        public void LoadImage(System.Drawing.Image image)
        {
            currentImage = image;
            Graphics g = this.CreateGraphics();
            g.Clear(Color.White);
            double ratio = ((double)image.Width / (double)this.Width);

            Bitmap overlay = new Bitmap(image.Width, image.Height);
            Graphics gOverlay = Graphics.FromImage(overlay);

            int newWidth = (int)((double)image.Width / ratio);
            int newHeight = (int)((double)image.Height / ratio);

            if (drawInputGroupOverlay)
            {

                if (inputGroupType == InputGroupType.Horozontal || inputGroupType == InputGroupType.Grid)
                {

                    for (int i = 1; i < segments; i++)
                    {
                        gOverlay.DrawLine(new Pen(Brushes.Red, 0.5f), 0, (int)Math.Round((double)i * ((double)image.Height / (double)segments)), image.Width, (int)Math.Round((double)i * ((double)image.Height / (double)segments)));

                    }

                }

                if (inputGroupType == InputGroupType.Vertical || inputGroupType == InputGroupType.Grid)
                {

                    for (int i = 1; i < segments; i++)
                    {
                        gOverlay.DrawLine(Pens.Red, (int)Math.Round((double)i * ((double)image.Width / (double)segments)), 0, (int)Math.Round((double)i * ((double)image.Width / (double)segments)), image.Height);

                    }

                }

            }

            if( scalingMethod == ENFORM.Core.ScalingMethods.Bicubic)
            {
                MessageBox.Show("Not implimented yet, reverting to nearest neighbor...");
                /*
                scalingMethod = ENFORM.ScalingMethod.Nearest_Neighbor;
                AForge.Imaging.Filters.ResizeBicubic resize = new AForge.Imaging.Filters.ResizeBicubic(newWidth, newHeight);
                g.DrawImage(resize.Apply((Bitmap)image), new Point(0, 0));
                g.DrawImage(resize.Apply((Bitmap)overlay), new Point(0, 0));
                 * */
                scalingMethod = ENFORM.Core.ScalingMethods.Nearest_Neighbor;
            }
            if (scalingMethod == ENFORM.Core.ScalingMethods.Bilinear)
            {
                AForge.Imaging.Filters.ResizeBilinear resize = new AForge.Imaging.Filters.ResizeBilinear(newWidth, newHeight);
                g.DrawImage(resize.Apply((Bitmap)image), new Point(0, 0));
                g.DrawImage(resize.Apply((Bitmap)overlay), new Point(0, 0));
            }
            if (scalingMethod == ENFORM.Core.ScalingMethods.Nearest_Neighbor)
            {
                AForge.Imaging.Filters.ResizeNearestNeighbor resize = new AForge.Imaging.Filters.ResizeNearestNeighbor(newWidth, newHeight);
                g.DrawImage(resize.Apply((Bitmap)image), new Point(0, 0));
                AForge.Imaging.Filters.ResizeNearestNeighbor resizeB = new AForge.Imaging.Filters.ResizeNearestNeighbor(newWidth, newHeight);
                g.DrawImage(resizeB.Apply((Bitmap)overlay), new Point(0, 0));
            }

            //g.DrawImage(resize.Apply((Bitmap)image), new Point(0,0));
               // g.DrawImage(resize.Apply((Bitmap)overlay), new Point(0,0));

            editable = true;
        }
예제 #10
0
        public Bitmap getProcessedImage(Bitmap bitmap)
        {
//            if (bitmap.Height > bitmap.Width)
//                throw new Exception("К такой забавной камере меня жизнь не готовила!");
            //  Можно было, конечено, и не кидаться эксепшенами в истерике, но идите и купите себе нормальную камеру!
            int side = bitmap.Height;

            //  Отпиливаем границы, но не более половины изображения
            if (side < 4 * settings.border)
            {
                settings.border = side / 4;
            }
            side -= 2 * settings.border;

            //  Мы сейчас занимаемся тем, что красиво оформляем входной кадр, чтобы вывести его на форму
            Rectangle cropRect = new Rectangle((bitmap.Width - bitmap.Height),
                                               0, side, side);

            //  Тут создаём новый битмапчик, который будет исходным изображением
            original = new Bitmap(cropRect.Width, cropRect.Height);

            //  Объект для рисования создаём
            Graphics g = Graphics.FromImage(original);

            g.DrawImage(bitmap, new Rectangle(0, 0, original.Width, original.Height), cropRect, GraphicsUnit.Pixel);
            Pen p = new Pen(Color.Red);

            p.Width = 1;

            //  Теперь всю эту муть пилим в обработанное изображение
            AForge.Imaging.Filters.Grayscale grayFilter = new AForge.Imaging.Filters.Grayscale(0.2125, 0.7154, 0.0721);
            var uProcessed = grayFilter.Apply(AForge.Imaging.UnmanagedImage.FromManagedImage(original));


            int blockWidth  = original.Width / settings.blocksCount;
            int blockHeight = original.Height / settings.blocksCount;

            for (int r = 0; r < settings.blocksCount; ++r)
            {
                for (int c = 0; c < settings.blocksCount; ++c)
                {
                    //  Тут ещё обработку сделать
                    g.DrawRectangle(p, new Rectangle(c * blockWidth, r * blockHeight, blockWidth, blockHeight));
                }
            }


            //  Масштабируем изображение до 500x500 - этого достаточно
            AForge.Imaging.Filters.ResizeBilinear scaleFilter =
                new AForge.Imaging.Filters.ResizeBilinear(settings.orignalDesiredSize.Width,
                                                          settings.orignalDesiredSize.Height);
            uProcessed = scaleFilter.Apply(uProcessed);
            original   = scaleFilter.Apply(original);
            g          = Graphics.FromImage(original);
            //  Пороговый фильтр применяем. Величина порога берётся из настроек, и меняется на форме
            AForge.Imaging.Filters.Threshold threshldFilter = new AForge.Imaging.Filters.Threshold();
            threshldFilter.ThresholdValue = settings.threshold;
            threshldFilter.ApplyInPlace(uProcessed);

            return(uProcessed.ToManagedImage());
        }