protected void fastHarrisRansacBlendStraight(List <Bitmap> imgs) { List <IntPoint[]> harrisPoints = new List <IntPoint[]>(); MatrixH homography; //Calculate all the Harris Points HarrisCornersDetector harris = new HarrisCornersDetector(0.03f, 10000f); for (int i = 0; i < imgs.Count; i++) { harrisPoints.Add(harris.ProcessImage(imgs[i]).ToArray()); } Bitmap final = imgs[0]; for (int i = 1; i < imgs.Count; i++) { //Convert my frames to grayscale so I can find and adjust the normal vectors AForge.Imaging.Filters.GrayscaleBT709 grayscale = new AForge.Imaging.Filters.GrayscaleBT709(); AForge.Imaging.DocumentSkewChecker skew = new AForge.Imaging.DocumentSkewChecker(); double finalAngle = skew.GetSkewAngle(grayscale.Apply(final)); double imgAngle = skew.GetSkewAngle(grayscale.Apply(imgs[i])); //Less than 5% to account for human error with rotations and wobbles if (Math.Abs(finalAngle - imgAngle) < 5) { AForge.Imaging.Filters.RotateBilinear rotate = new AForge.Imaging.Filters.RotateBilinear(finalAngle - imgAngle); rotate.FillColor = Color.FromArgb(0, 255, 255, 255); imgs[i] = rotate.Apply(imgs[i]); //Update harris harrisPoints[i] = harris.ProcessImage(imgs[i]).ToArray(); } IntPoint[] harrisFinal = harris.ProcessImage(final).ToArray(); //Correlate the Harris pts between imgs CorrelationMatching matcher = new CorrelationMatching(5, final, imgs[i]); IntPoint[][] matches = matcher.Match(harrisFinal, harrisPoints[i]); //Create the homography matrix using ransac RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.025, 0.99); homography = ransac.Estimate(matches[0], matches[1]); Blend blend = new Blend(homography, final); blend.Gradient = true; final = blend.Apply(imgs[i]); } showImage(final); }
protected void surfRansacBlendStraight(List <Bitmap> imgs) { MatrixH homography; List <SpeededUpRobustFeaturePoint[]> surfPoints = new List <SpeededUpRobustFeaturePoint[]>(); //Calculate all the Surf Points SpeededUpRobustFeaturesDetector surf = new SpeededUpRobustFeaturesDetector(); double lastAngle = 0; for (int i = 0; i < imgs.Count; i++) { //Grayscale to find the edges and adjust the normal to point up AForge.Imaging.Filters.GrayscaleBT709 grayscale = new AForge.Imaging.Filters.GrayscaleBT709(); AForge.Imaging.DocumentSkewChecker skew = new AForge.Imaging.DocumentSkewChecker(); double angle = skew.GetSkewAngle(grayscale.Apply(imgs[i])); //Less than 5 deg change in angle to account for wobble, ignore big shifts if (Math.Abs(angle - lastAngle) < 5) { AForge.Imaging.Filters.RotateBilinear rotate = new AForge.Imaging.Filters.RotateBilinear(angle); rotate.FillColor = Color.FromArgb(0, 255, 255, 255); imgs[i] = rotate.Apply(imgs[i]); lastAngle = angle; } showImage(imgs[i]); surfPoints.Add(surf.ProcessImage(imgs[i]).ToArray()); } Bitmap final = imgs[0]; for (int i = 1; i < imgs.Count; i++) { SpeededUpRobustFeaturePoint[] surfFinal = surf.ProcessImage(final).ToArray(); //Correlate the Harris pts between imgs KNearestNeighborMatching matcher = new KNearestNeighborMatching(5); matcher.Threshold = 0.05; IntPoint[][] matches = matcher.Match(surfFinal, surfPoints[i]); //Create the homography matrix using RANSAC RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.015, 1); homography = ransac.Estimate(matches[0], matches[1]); Blend blend = new Blend(homography, final); blend.Gradient = true; final = blend.Apply(imgs[i]); } //Smooth/Sharpen if I wanted to AForge.Imaging.Filters.Sharpen filter = new AForge.Imaging.Filters.Sharpen(); //AForge.Imaging.Filters.Gaussian filter = new AForge.Imaging.Filters.Guassian(5); //filter.ApplyInPlace(final); showImage(final); }
public BitmapSource Apply(BitmapSource image) { var filter = new DocumentSkewChecker(); var bitmap = image.ToBitmap(); var grayscale = new Grayscale(0.2125, 0.7154, 0.0721).Apply(bitmap); var angle = filter.GetSkewAngle(grayscale); var rotationFilter = new RotateBilinear(-angle); return rotationFilter.Apply(grayscale).ToBitmapImage(); }
private void RotateImage() { DocumentSkewChecker skewChecker = new DocumentSkewChecker(); skewChecker.MaxSkewToDetect = 45; double angle = skewChecker.GetSkewAngle(_recogimg); //Максимальный угол, при котором идет поворот - 45 градусов, после этого изображение не поворачивается if (Math.Abs(angle) < 45) { RotateBilinear rotationFilter = new RotateBilinear(-angle, true); rotationFilter.FillColor = Color.Black; _recogimg = rotationFilter.Apply(_recogimg); _markersimg = rotationFilter.Apply(_markersimg); } }
// 기울어짐 바로잡기 public static Bitmap skew(Bitmap source) { // create grayscale filter (BT709) Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721); // 8비트 grayscale 로 바꾸고 // apply the filter Bitmap grayImage = filter.Apply(source); // create instance of skew checker DocumentSkewChecker skewChecker = new DocumentSkewChecker(); // 8비트 grayscale 로 넣어줘야 함 // // get documents skew angle double angle = skewChecker.GetSkewAngle(grayImage); // 기울어진 각도를 얻고 Bitmap tmp = source; // convert to 24 bits per pixel source = ImageProcess.Clone(tmp, PixelFormat.Format24bppRgb); // 로테이션 전에 24비트로 바꿔주고 // delete old image tmp.Dispose(); // create rotation filter RotateBilinear rotationFilter = new RotateBilinear(-angle); rotationFilter.FillColor = Color.White; // rotate image applying the filter Bitmap rotatedImage = rotationFilter.Apply(source); // 원래 이미지를 가져다가 각도만큼 돌리고(원래 이미지는 24비트로 넣어줘야함) return rotatedImage; }
public static System.Drawing.Image AforgeAutoCrop(Bitmap selectedImage, DetectBorderParam param) { // 一些参数的默认值 if (param.MinObjectWidth == 0) param.MinObjectWidth = 500; if (param.MinObjectHeight == 0) param.MinObjectHeight = 500; Bitmap autoCropImage = null; try { autoCropImage = selectedImage; // create grayscale filter (BT709) Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721); Bitmap grayImage = filter.Apply(autoCropImage); // create instance of skew checker DocumentSkewChecker skewChecker = new DocumentSkewChecker(); // get documents skew angle double angle = skewChecker.GetSkewAngle(grayImage); // create rotation filter RotateBilinear rotationFilter = new RotateBilinear(-angle); rotationFilter.FillColor = Color.White; // rotate image applying the filter Bitmap rotatedImage = rotationFilter.Apply(grayImage); new ContrastStretch().ApplyInPlace(rotatedImage); new Threshold(100).ApplyInPlace(rotatedImage); BlobCounter bc = new BlobCounter(); bc.FilterBlobs = true; bc.MinWidth = param.MinObjectWidth; // 500; bc.MinHeight = param.MinObjectHeight; // 500; bc.ProcessImage(rotatedImage); Rectangle[] rects = bc.GetObjectsRectangles(); if (rects.Length == 0) { System.Windows.Forms.MessageBox.Show("No rectangle found in image "); } else if (rects.Length == 1) { autoCropImage = rotatedImage.Clone(rects[0], rotatedImage.PixelFormat); } else if (rects.Length > 1) { // get largets rect Console.WriteLine("Using largest rectangle found in image "); var r2 = rects.OrderByDescending(r => r.Height * r.Width).ToList(); autoCropImage = rotatedImage.Clone(r2[1], rotatedImage.PixelFormat); } else { Console.WriteLine("Huh? on image "); } } catch (Exception ex) { // MessageBox.Show(ex.Message); throw ex; } return autoCropImage; }
public static bool GetSkewParam(Bitmap selectedImage, DetectBorderParam param, out double angle, out Rectangle rect) { // 一些参数的默认值 if (param.MinObjectWidth == 0) param.MinObjectWidth = 500; if (param.MinObjectHeight == 0) param.MinObjectHeight = 500; Bitmap autoCropImage = null; try { autoCropImage = selectedImage; #if NO // create grayscale filter (BT709) Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721); Bitmap grayImage = filter.Apply(autoCropImage); #endif Bitmap grayImage = selectedImage.Clone(new Rectangle(0, 0, selectedImage.Width, selectedImage.Height), System.Drawing.Imaging.PixelFormat.Format8bppIndexed); // create instance of skew checker DocumentSkewChecker skewChecker = new DocumentSkewChecker(); // get documents skew angle angle = skewChecker.GetSkewAngle(grayImage); // create rotation filter RotateBilinear rotationFilter = new RotateBilinear(-angle); rotationFilter.FillColor = Color.Black; // .White; rotationFilter.KeepSize = true; // rotate image applying the filter Bitmap rotatedImage = rotationFilter.Apply(grayImage); new ContrastStretch().ApplyInPlace(rotatedImage); new Threshold(100).ApplyInPlace(rotatedImage); BlobCounter bc = new BlobCounter(); bc.FilterBlobs = true; bc.MinWidth = param.MinObjectWidth; // 500; bc.MinHeight = param.MinObjectHeight; // 500; #if NO bc.MinWidth = 500;// grayImage.Width / 10; // 500 bc.MinHeight = 500;// grayImage.Height / 10; // 500 #endif bc.ProcessImage(rotatedImage); Rectangle[] rects = bc.GetObjectsRectangles(); if (rects.Length == 0) { // System.Windows.Forms.MessageBox.Show("No rectangle found in image "); rect = new Rectangle(0, 0, 0, 0); return false; } else if (rects.Length == 1) { rect = rects[0]; // autoCropImage = rotatedImage.Clone(rects[0], rotatedImage.PixelFormat); } else if (rects.Length > 1) { // TODO: 应该把这些矩形合并在一起 Rectangle first = new Rectangle(0, 0, 0, 0); int i = 0; foreach (Rectangle one in rects) { Debug.WriteLine("one=" + one.ToString()); if (i == 0) first = one; else first = Merge(first, one); i++; } rect = first; Debug.WriteLine("result=" + rect.ToString()); #if NO // get largets rect Console.WriteLine("Using largest rectangle found in image "); var r2 = rects.OrderByDescending(r => r.Height * r.Width).ToList(); rect = r2[1]; // autoCropImage = rotatedImage.Clone(r2[1], rotatedImage.PixelFormat); #endif } else { // Console.WriteLine("Huh? on image "); rect = new Rectangle(0, 0, 0, 0); return false; } #if NO Blob[] blobs = bc.GetObjectsInformation(); foreach (var blob in blobs) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob); List<IntPoint> cornerPoints; // use the shape checker to extract the corner points if (shapeChecker.IsQuadrilateral(edgePoints, out cornerPoints)) { // only do things if the corners form a rectangle if (shapeChecker.CheckPolygonSubType(cornerPoints) == PolygonSubType.Rectangle) { // here i use the graphics class to draw an overlay, but you // could also just use the cornerPoints list to calculate your // x, y, width, height values. List<Point> Points = new List<Point>(); foreach (var point in cornerPoints) { Points.Add(new Point(point.X, point.Y)); } Graphics g = Graphics.FromImage(image); g.DrawPolygon(new Pen(Color.Red, 5.0f), Points.ToArray()); image.Save("result.png"); } } } #endif } catch (Exception ex) { // MessageBox.Show(ex.Message); throw ex; } finally { if (autoCropImage != null) autoCropImage.Dispose(); } return true; }
// 기울기 보정 private void button51_Click(object sender, EventArgs e) { ///////////// ini 객체 생성 시작 ///////////////////////////////////////////////////// //현재 프로그램이 실행되고 있는정보 가져오기: 디버깅 모드라면 bin/debug/프로그램명.exe FileInfo exefileinfo = new FileInfo(@"C:\Program Files\PLOCR\PLOCR.exe"); string pathini = exefileinfo.Directory.FullName.ToString(); //프로그램 실행되고 있는데 path 가져오기 string fileName = @"\PLOCRconfig.ini"; // 환경설정 파일명 string filePath = pathini + fileName; //ini 파일 경로 DocumentAnalysis.IniUtil ini = new DocumentAnalysis.IniUtil(filePath); // 만들어 놓았던 iniUtil 객체 생성(생성자 인자로 파일경로 정보 넘겨줌) //////////// ini 객체 생성 끝 ///////////////////////////////////////////////////////// Bitmap source = Global.source; // create grayscale filter (BT709) Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721); // 8비트 grayscale 로 바꾸고 // apply the filter Bitmap grayImage = filter.Apply(source); grayImage.Save(@"C:\\Program Files\\PLOCR\\그레이스케일.png"); // create instance of skew checker DocumentSkewChecker skewChecker = new DocumentSkewChecker(); // 8비트 grayscale 로 넣어줘야 함 // // get documents skew angle double angle = skewChecker.GetSkewAngle(grayImage); // 기울어진 각도를 얻고 Bitmap tmp = source; // convert to 24 bits per pixel source = imageProcess.Clone(tmp, PixelFormat.Format24bppRgb); // 로테이션 전에 24비트로 바꿔주고 // delete old image tmp.Dispose(); // create rotation filter RotateBilinear rotationFilter = new RotateBilinear(-angle); rotationFilter.FillColor = Color.White; // rotate image applying the filter Bitmap rotatedImage = rotationFilter.Apply(source); // 원래 이미지를 가져다가 각도만큼 돌리고(원래 이미지는 24비트로 넣어줘야함) Global.source = rotatedImage; pictureBox1.Image = Global.source; pictureBox1.Invalidate(); ini.SetIniValue("기울어짐 바로잡기", "바로잡기 예/아니오", "예"); }
public static Bitmap Orient_Hough(Bitmap blob) { GC.Collect(); Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721); Bitmap documentImage = filter.Apply(blob); //Bitmap documentImage = AForge.Imaging.Image.Clone(blob, PixelFormat.Format16bppGrayScale); //force the jpgs // create instance of skew checker DocumentSkewChecker skewChecker = new DocumentSkewChecker(); // get documents skew angle double angle = skewChecker.GetSkewAngle(documentImage); // rotate image applying the filter return RotateImg(blob, (int)-angle, Color.Transparent); }
// Align scanned document private void documentAligningMenuItem_Click( object sender, EventArgs e ) { try { // get grayscale image from current image Bitmap grayImage = ( image.PixelFormat == PixelFormat.Format8bppIndexed ) ? AForge.Imaging.Image.Clone( image ) : AForge.Imaging.Filters.Grayscale.CommonAlgorithms.BT709.Apply( image ); // threshold it using adaptive Otsu thresholding OtsuThreshold threshold = new OtsuThreshold( ); threshold.ApplyInPlace( grayImage ); // get skew angle DocumentSkewChecker skewChecker = new DocumentSkewChecker( ); double angle = skewChecker.GetSkewAngle( grayImage ); if ( ( angle < -skewChecker.MaxSkewToDetect ) || ( angle > skewChecker.MaxSkewToDetect ) ) { throw new ApplicationException( ); } // create rotation filter RotateBilinear rotationFilter = new RotateBilinear( -angle ); rotationFilter.FillColor = Color.White; // rotate image applying the filter ApplyFilter( rotationFilter ); } catch { MessageBox.Show( "Failed determining skew angle. Is it reallly a scanned document?", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error ); } }