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; } }
/// <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); }
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); }
//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; }
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; }
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; }
/// <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); }
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); }
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; }
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()); }