public static Bitmap Apply(Bitmap selectedImage, double angle, Rectangle rect) { System.Drawing.Imaging.PixelFormat old_format = selectedImage.PixelFormat; RotateBilinear rotationFilter = new RotateBilinear(-angle); rotationFilter.FillColor = Color.White; rotationFilter.KeepSize = true; // 格式必须为其中之一: rotationFilter.FormatTranslations; // rotate image applying the filter Bitmap temp = selectedImage.Clone(new Rectangle(0, 0, selectedImage.Width, selectedImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb); Bitmap rotatedImage = rotationFilter.Apply(temp); #if NO return rotatedImage.Clone(rect, old_format // rotatedImage.PixelFormat ); #endif return rotatedImage; }
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(); }
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); }
public IEnumerable<Bitmap> Apply(Bitmap bitmap) { // assuming scanned background is white we need to invert for the algo to work var copy = new Invert().Apply(bitmap); copy = EnsureGrayscale(copy); new Threshold { ThresholdValue = 25 }.ApplyInPlace(copy); new FillHoles().ApplyInPlace(copy); var blobCounter = new BlobCounter { // set filtering options FilterBlobs = true, MinWidth = 50, MinHeight = 50, }; blobCounter.ProcessImage(copy); var blobs = blobCounter.GetObjectsInformation(); if (blobs.Any()) { var invertedOriginal = new Invert().Apply(bitmap); foreach (var blob in blobs) { // use inverted source to ensure correct edge colors blobCounter.ExtractBlobsImage(invertedOriginal, blob, false); var blobImage = blob.Image.ToManagedImage(); // straighten var angle = new DocumentSkewChecker().GetSkewAngle(EnsureGrayscale(blobImage)); var rotationFilter = new RotateBilinear(-angle) { FillColor = Color.Black }; blobImage = rotationFilter.Apply(blobImage); // crop blobImage = new ExtractBiggestBlob().Apply(blobImage); new Invert().ApplyInPlace(blobImage); yield return blobImage; } } else { yield return bitmap; } }
/// <summary> /// Detect hand on a given frame /// </summary> /// <param name="image">Image to detect the hand palm within</param> /// <param name="cycles">Number of snapshot cycles to check against</param> /// <param name="similarityRate">The threshold percent of pixels that have to match for a positive result</param> /// <param name="trainingPic">A reference to secondary frame field. Temporary.</param> /// <returns>IntPoint point at the centre of detected hand palm</returns> public IntPoint DetectHand(Bitmap image, int cycles, int similarityRate, PictureBox trainingPic) { IntPoint dimensions = new IntPoint(image.Width, image.Height); BlobCounterBase bc = new BlobCounter(); Crop cropFilter; bc.FilterBlobs = true; bc.MinWidth = (int)(avgSize.x * 0.6); bc.MinHeight = (int)(avgSize.y * 0.6); bc.ObjectsOrder = ObjectsOrder.Size; bc.ProcessImage(image); Blob[] blobs = bc.GetObjectsInformation(); int blobWidth = 0; int blobHeight = 0; float blobAspectRatio; double angle; RotateBilinear rotate; ResizeBilinear resize = new ResizeBilinear((int)avgSize.x, (int)avgSize.y); Bitmap bmp; List<IntPoint> edges = new List<IntPoint>(); for (int b = 0; b < blobs.Length; b++) { Rectangle br = blobs[b].Rectangle; cropFilter = new Crop(br); image = cropFilter.Apply(image); bmp = AForge.Imaging.Image.Clone(image); //bc.ExtractBlobsImage(image, blobs[b], false); //bmp = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb); edges = bc.GetBlobsEdgePoints(blobs[b]); IntPoint circleCenter = FindLargestCircleCenter(edges, blobs[b].Rectangle); //bmp = ImageFilters.Draw(bmp, edges); //Highlight circle center //Graphics gfx = Graphics.FromImage(bmp); //gfx.DrawRectangle(new Pen(Color.Red, 3), circleCenter.X - 10, circleCenter.Y - 10, 20, 20); blobWidth = blobs[b].Rectangle.Width; blobHeight = blobs[b].Rectangle.Height; blobAspectRatio = (float)blobWidth / blobHeight; if((blobAspectRatio) > avgAspectRatio + 0.08) { float test3 = avgSize.y / avgSize.x; if ((blobAspectRatio - avgAspectRatio) <= 1) { angle = ((blobAspectRatio - avgAspectRatio) / (test3 - avgAspectRatio)) * 90 + (1 - (blobAspectRatio - avgAspectRatio)) * 30; } else { angle = ((blobAspectRatio - avgAspectRatio) / (test3 - avgAspectRatio)) * 90; } rotate = new RotateBilinear(angle, false); image = rotate.Apply(image); //bmp = rotate.Apply(bmp); } image = resize.Apply(image); //bmp = resize.Apply(bmp); //image = cropFilter.Apply(image); //image = maxBlobFilter.Apply(image); int scannedPixels = 0; int matches = 0; float test = 0; float threshold = (float)similarityRate / 100; int imgHeight, imgWidth; for (int i = 0; i < cycles; i++) { for (int smpl = 0; smpl < 10; smpl++) { if (image.Size.Width < samples[i, smpl].Size.Width) imgWidth = image.Size.Width; else imgWidth = samples[i, smpl].Size.Width; if (image.Size.Height < samples[i, smpl].Size.Height) imgHeight = image.Size.Height; else imgHeight = samples[i, smpl].Size.Height; for (int y = 0; y < imgHeight; y += 3) for (int x = 0; x < imgWidth; x += 3) { scannedPixels++; lock (samples[i, smpl]) { lock (image) { if (image.GetPixel(x, y).Equals(samples[i, smpl].GetPixel(x, y))) { matches++; } } } } test = (float)matches / (float)scannedPixels; if (test >= threshold) { //bc.ExtractBlobsImage(image, blobs[b], false); //bmp.Save("detect" + detectedNum + "o.bmp"); //image.Save("detect" + detectedNum + "r.bmp"); detectedNum++; return new IntPoint(dimensions.X - circleCenter.X, circleCenter.Y); //return new IntPoint(image.Width - (int)blobs[b].CenterOfGravity.X, (int)blobs[b].CenterOfGravity.Y); } matches = 0; scannedPixels = 0; } } } return new IntPoint(); }
public static Bitmap RotateBilinear(Bitmap bmp, int degree) { // create filter - rotate for 30 degrees keeping original image size RotateBilinear filter = new RotateBilinear(degree, true); // apply the filter Bitmap newImage = filter.Apply(bmp); return newImage; }
// 기울어짐 바로잡기 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; }
private void RotateImageButtonPress(object sender, EventArgs e) { int angle = 0; if(!int.TryParse(angleForRotationTextBox.Text, out angle)) { MessageBox.Show("Check input data and try again !"); return; } image.RotateAngle = angle % 360; RotateBilinear filter = new RotateBilinear(image.RotateAngle, true); Bitmap newImage = filter.Apply(image.SourceImage); ClearCurrentImage(); pictureBox1.Image = newImage; }
//private void RotateImage(Bitmap srcimg, int angle) //{ // if (srcimg == null) // throw new ArgumentNullException("image"); // if (!_rotatedimg_table.ContainsKey(angle)) // { // const double pi2 = Math.PI / 2.0; // // Why can't C# allow these to be const, or at least readonly // // *sigh* I'm starting to talk like Christian Graus :omg: // double oldWidth = _width; // double oldHeight = _height; // // Convert degrees to radians // double theta = ((double)angle) * Math.PI / 180.0; // double locked_theta = theta; // // Ensure theta is now [0, 2pi) // while (locked_theta < 0.0) // locked_theta += 2 * Math.PI; // double newWidth, newHeight; // int nWidth, nHeight; // The newWidth/newHeight expressed as ints // #region Explaination of the calculations // #endregion // double adjacentTop, oppositeTop; // double adjacentBottom, oppositeBottom; // // We need to calculate the sides of the triangles based // // on how much rotation is being done to the bitmap. // // Refer to the first paragraph in the explaination above for // // reasons why. // if ((locked_theta >= 0.0 && locked_theta < pi2) || // (locked_theta >= Math.PI && locked_theta < (Math.PI + pi2))) // { // adjacentTop = Math.Abs(Math.Cos(locked_theta)) * oldWidth; // oppositeTop = Math.Abs(Math.Sin(locked_theta)) * oldWidth; // adjacentBottom = Math.Abs(Math.Cos(locked_theta)) * oldHeight; // oppositeBottom = Math.Abs(Math.Sin(locked_theta)) * oldHeight; // } // else // { // adjacentTop = Math.Abs(Math.Sin(locked_theta)) * oldHeight; // oppositeTop = Math.Abs(Math.Cos(locked_theta)) * oldHeight; // adjacentBottom = Math.Abs(Math.Sin(locked_theta)) * oldWidth; // oppositeBottom = Math.Abs(Math.Cos(locked_theta)) * oldWidth; // } // newWidth = adjacentTop + oppositeBottom; // newHeight = adjacentBottom + oppositeTop; // nWidth = (int)Math.Ceiling(newWidth); // nHeight = (int)Math.Ceiling(newHeight); // Bitmap rotatedBmp = new Bitmap(nWidth, nHeight); // using (Graphics g = Graphics.FromImage(rotatedBmp)) // { // g.Clear(Color.White); // // This array will be used to pass in the three points that // // make up the rotated srcimg // Point[] points; // if (locked_theta >= 0.0 && locked_theta < pi2) // { // points = new Point[] { // new Point( (int) oppositeBottom, 0 ), // new Point( nWidth, (int) oppositeTop ), // new Point( 0, (int) adjacentBottom ) // }; // } // else if (locked_theta >= pi2 && locked_theta < Math.PI) // { // points = new Point[] { // new Point( nWidth, (int) oppositeTop ), // new Point( (int) adjacentTop, nHeight ), // new Point( (int) oppositeBottom, 0 ) // }; // } // else if (locked_theta >= Math.PI && locked_theta < (Math.PI + pi2)) // { // points = new Point[] { // new Point( (int) adjacentTop, nHeight ), // new Point( 0, (int) adjacentBottom ), // new Point( nWidth, (int) oppositeTop ) // }; // } // else // { // points = new Point[] { // new Point( 0, (int) adjacentBottom ), // new Point( (int) oppositeBottom, 0 ), // new Point( (int) adjacentTop, nHeight ) // }; // } // g.DrawImage(srcimg, points); // g.Dispose(); // } // //Console.WriteLine((int)angle); // _rotatedimg_table.Add(angle, rotatedBmp); // Rectangle bbx = BBX(rotatedBmp); // if (_max_width < bbx.Width) // { // _max_width = bbx.Width; // _max_width_idx = angle; // } // } //} //private void RotateImage(string path, int angle) //{ // Bitmap srcimg = new Bitmap(path); // if (srcimg == null) // throw new ArgumentNullException("image"); // if (!_rotatedimg_table.ContainsKey(angle)) // { // const double pi2 = Math.PI / 2.0; // // Why can't C# allow these to be const, or at least readonly // // *sigh* I'm starting to talk like Christian Graus :omg: // double oldWidth = _width; // double oldHeight = _height; // // Convert degrees to radians // double theta = ((double)angle) * Math.PI / 180.0; // double locked_theta = theta; // // Ensure theta is now [0, 2pi) // while (locked_theta < 0.0) // locked_theta += 2 * Math.PI; // double newWidth, newHeight; // int nWidth, nHeight; // The newWidth/newHeight expressed as ints // #region Explaination of the calculations // #endregion // double adjacentTop, oppositeTop; // double adjacentBottom, oppositeBottom; // // We need to calculate the sides of the triangles based // // on how much rotation is being done to the bitmap. // // Refer to the first paragraph in the explaination above for // // reasons why. // if ((locked_theta >= 0.0 && locked_theta < pi2) || // (locked_theta >= Math.PI && locked_theta < (Math.PI + pi2))) // { // adjacentTop = Math.Abs(Math.Cos(locked_theta)) * oldWidth; // oppositeTop = Math.Abs(Math.Sin(locked_theta)) * oldWidth; // adjacentBottom = Math.Abs(Math.Cos(locked_theta)) * oldHeight; // oppositeBottom = Math.Abs(Math.Sin(locked_theta)) * oldHeight; // } // else // { // adjacentTop = Math.Abs(Math.Sin(locked_theta)) * oldHeight; // oppositeTop = Math.Abs(Math.Cos(locked_theta)) * oldHeight; // adjacentBottom = Math.Abs(Math.Sin(locked_theta)) * oldWidth; // oppositeBottom = Math.Abs(Math.Cos(locked_theta)) * oldWidth; // } // newWidth = adjacentTop + oppositeBottom; // newHeight = adjacentBottom + oppositeTop; // nWidth = (int)Math.Ceiling(newWidth); // nHeight = (int)Math.Ceiling(newHeight); // Bitmap rotatedBmp = new Bitmap(nWidth, nHeight); // using (Graphics g = Graphics.FromImage(rotatedBmp)) // { // g.Clear(Color.White); // // This array will be used to pass in the three points that // // make up the rotated srcimg // Point[] points; // if (locked_theta >= 0.0 && locked_theta < pi2) // { // points = new Point[] { // new Point( (int) oppositeBottom, 0 ), // new Point( nWidth, (int) oppositeTop ), // new Point( 0, (int) adjacentBottom ) // }; // } // else if (locked_theta >= pi2 && locked_theta < Math.PI) // { // points = new Point[] { // new Point( nWidth, (int) oppositeTop ), // new Point( (int) adjacentTop, nHeight ), // new Point( (int) oppositeBottom, 0 ) // }; // } // else if (locked_theta >= Math.PI && locked_theta < (Math.PI + pi2)) // { // points = new Point[] { // new Point( (int) adjacentTop, nHeight ), // new Point( 0, (int) adjacentBottom ), // new Point( nWidth, (int) oppositeTop ) // }; // } // else // { // points = new Point[] { // new Point( 0, (int) adjacentBottom ), // new Point( (int) oppositeBottom, 0 ), // new Point( (int) adjacentTop, nHeight ) // }; // } // g.DrawImage(srcimg, points); // g.Dispose(); // } // //Console.WriteLine((int)angle); // _rotatedimg_table.Add(angle, rotatedBmp); // Rectangle bbx = BBX(rotatedBmp); // if (_max_width < bbx.Width) // { // _max_width = bbx.Width; // _max_width_idx = angle; // } // } //} private void RotateImage(Bitmap srcimg, int angle) { if (!_rotatedimg_table.ContainsKey(angle)) { RotateBilinear filter = new RotateBilinear(angle); Bitmap rotateimg = ImageUtils.InvertColors(filter.Apply(ImageUtils.InvertColors(srcimg))); _rotatedimg_table.Add(angle, rotateimg); } }
public void Apply(string input_dir, string output_dir, string fn, int char_size, double size_ratio, bool preprocessing, int tnum, string lang) { MergeTextStrings mts = new MergeTextStrings(); ImageSlicer imgslicer = new ImageSlicer(); List<TextString> text_string_list = new List<TextString>(); List<string> imgpath_list = imgslicer.Apply(1, 1, 100, input_dir + fn, output_dir); Log.WriteLine("Grouping text strings..."); for (int s = 0; s < imgpath_list.Count; s++) { Bitmap srcimg = null; if (lang == "eng") { using (Bitmap tileimg = new Bitmap(imgpath_list[s])) { RemoveBoarderAndNoiseCC removeBoarderAndNoiseCC = new RemoveBoarderAndNoiseCC(); srcimg = removeBoarderAndNoiseCC.Apply(tileimg, char_size, 0.18); Log.WriteBitmap2FolderExactFileName(output_dir, srcimg, "CDAInput.png"); } } else { using (Bitmap tileimg = new Bitmap(imgpath_list[s])) { RemoveBoarderCC removeBoarderCC = new RemoveBoarderCC(); srcimg = removeBoarderCC.Apply(tileimg); Log.WriteBitmap2FolderExactFileName(output_dir, srcimg, "CDAInput.png"); } } ConditionalDilationAutomatic cda = new ConditionalDilationAutomatic(); cda.ang_threshold = angle_ratio; string outputImagePath = output_dir + s + ".png"; cda.Apply(tnum, srcimg, size_ratio, angle_ratio, preprocessing, outputImagePath); using (Bitmap dilatedimg = new Bitmap(outputImagePath)) { DetectTextStrings detectTS = new DetectTextStrings(); List<TextString> string_list = detectTS.Apply(srcimg, dilatedimg); List<Bitmap> string_img_list = new List<Bitmap>(); for (int i = 0; i < string_list.Count; i++) string_img_list.Add(string_list[i].srcimg); int[] offset = imgslicer.xy_offset_list[s]; for (int i = 0; i < string_list.Count; i++) { string_list[i].x_offset = offset[0]; string_list[i].y_offset = offset[1]; mts.AddTextString(string_list[i]); } } using (Bitmap CDAInputwithLabel=new Bitmap (outputImagePath)) { Graphics g = Graphics.FromImage(CDAInputwithLabel); for (int i = 0; i < mts.text_string_list.Count; i++) { Font font = new Font("Arial", 20); g.DrawString(i.ToString(), font, Brushes.Red, mts.text_string_list[i].bbx.X, mts.text_string_list[i].bbx.Y); g.DrawRectangle(new Pen(Color.Green, 4), mts.text_string_list[i].bbx); } Log.WriteBitmap2FolderExactFileName(output_dir, CDAInputwithLabel, "CDAInputwithLabel.png"); g.Dispose(); g=null; } srcimg.Dispose(); srcimg = null; } Log.WriteLine("Detecting long string orientation..."); DetectTextOrientation detectTextOrientation = new DetectTextOrientation(); detectTextOrientation.Apply(mts, tnum); Log.WriteLine("Detecting short string orientation..."); for (int i = 0; i < mts.text_string_list.Count; i++) { if (mts.text_string_list[i].char_list.Count <= 3) { List<int> nearest_string_list = detectTextOrientation.findNearestSrings(i, mts.text_string_list); int initial_orientation_count = mts.text_string_list[i].orientation_list.Count; for (int j = 0; j < nearest_string_list.Count; j++) mts.text_string_list[i].orientation_list.AddRange(mts.text_string_list[nearest_string_list[j]].orientation_list); for (int j = initial_orientation_count; j < mts.text_string_list[i].orientation_list.Count; j++) { RotateBilinear filter = new RotateBilinear(mts.text_string_list[i].orientation_list[j]); Bitmap rotateimg = ImageUtils.InvertColors(filter.Apply(ImageUtils.InvertColors(mts.text_string_list[i].srcimg))); mts.text_string_list[i].rotated_img_list.Add(rotateimg); } } } Log.WriteLine("Writing string results..."); mts.WriteBMP(output_dir); }
// 기울기 보정 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("기울어짐 바로잡기", "바로잡기 예/아니오", "예"); }
// 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 ); } }
private void CheckUp() { List<double> disttohight = new List<double>(); AForge.Point hightpoint = new AForge.Point((float)_markersimg.Width / 2.0f, 0); for (int iteration = 0; iteration < 4; iteration++) { FindCenterMarker(); // RotateBicubic rbf = new RotateBicubic(-90); RotateBilinear rbf = new RotateBilinear(-90); _markersimg = rbf.Apply(_markersimg); disttohight.Add(Geometry.EuclidianDistance(_tcmarker.Blob.CenterOfGravity, hightpoint)); } double mindist = disttohight.Min(); double angle = disttohight.IndexOf(mindist) * -90; RotateBilinear _recogimgrotator = new RotateBilinear(angle); _recogimg = _recogimgrotator.Apply(_recogimg); _markersimg = _recogimgrotator.Apply(_markersimg); }
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 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); } }
/// <summary> /// Crop the blob from the image /// </summary> private Bitmap CropBlob(BlobPanel blob, System.Drawing.Image source, int rotationAngel = 0) { // Create the target image, this is a squared image. int size = Math.Max(blob.Height, blob.Width); Bitmap newImage = new Bitmap(size, size, PixelFormat.Format24bppRgb); // Get the graphics object of the image. Graphics g = Graphics.FromImage(newImage); // Create the background color to use (the image we create is larger than the blob (as we squared it) // so this would be the color of the excess areas. Color bColor = Color.FromArgb((int)txtExtractedBackColor.Value, (int)txtExtractedBackColor.Value, (int)txtExtractedBackColor.Value); // Fill back color. g.FillRectangle(new SolidBrush(bColor), 0, 0, size, size); // Now we clip the blob from the PictureBox image. g.DrawImage(source, new Rectangle(0, 0, blob.Width, blob.Height), blob.Left, blob.Top, blob.Width, blob.Height, GraphicsUnit.Pixel); g.Dispose(); if (rotationAngel != 0) { RotateBilinear filter = new RotateBilinear(rotationAngel, true); filter.FillColor = bColor; // apply the filter newImage = filter.Apply(newImage); } // Resize the image. ResizeBilinear resizefilter = new ResizeBilinear((int)txtExportSize.Value, (int)txtExportSize.Value); newImage = resizefilter.Apply(newImage); return newImage; }