public mThresholdSIS() { BitmapType = BitmapTypes.GrayscaleBT709; Effect = new SISThreshold(); filter = Effect; }
/// <summary> /// Binarize image with SIS threshold filter /// </summary> /// <param name="image"></param> public static Image SisThreshold(this Bitmap image) { if (image.PixelFormat != PixelFormat.Format8bppIndexed) { throw new NotSupportedException("Filter can be applied to binary 8bpp images only"); } SISThreshold thresholdFilter = new SISThreshold(); return(thresholdFilter.Apply(image)); }
public void Execute() { Console.WriteLine("Execute OCR"); OCR.Statistics.Clear(); OCR.Statistics.AddCounter("Processors", System.Environment.ProcessorCount); SISThreshold filter = new SISThreshold(); int Threshold = filter.CalculateThreshold(m_Image.Image, m_Image.Area); OtsuThreshold filterOtsu = new OtsuThreshold(); Threshold = filterOtsu.CalculateThreshold(m_Image.Image, m_Image.Area); PreprocessPage Processor = new PreprocessPage(); Processor.Image = m_Image; Processor.Treshold = m_Image.CalculateOtsuThreshold(); m_Image.Threshold = 170; Processor.Execute(); resultBitmap = PageImage.CreateBitmapFromByteArray(m_Image.BinaryBytes, new Size(m_Image.Width, m_Image.Height)); DetectComponents Step2 = new DetectComponents(); Step2.Image = m_Image; Step2.Execute(); AnalyseComponents Step3 = new AnalyseComponents(); Step3.Image = m_Image; Step3.Execute(); DetectSentences Step4 = new DetectSentences(); Step4.Image = m_Image; Step4.Execute(); ExtractFeatures Step5 = new ExtractFeatures(); Step5.Image = m_Image; Step5.Execute(); RecogniseComponent Step6 = new RecogniseComponent(); Step6.Image = m_Image; Step6.Execute(); ProcessSentences Step7 = new ProcessSentences(); Step7.Image = m_Image; Step7.Execute(); }
public Bitmap FindTextBitmap() { Bitmap textBmp = new Bitmap(sets.BmpTextWidth, sets.BmpTextHeight); textBmp = sourceImage.Clone(new Rectangle(match.X + sets.TextMarginRight, match.Y + sets.TextMarginTop, sets.BmpTextWidth, sets.BmpTextHeight), PixelFormat.Format24bppRgb); Grayscale gs = new Grayscale(0.2125, 0.7154, 0.0721); SISThreshold th = new SISThreshold(); BinaryErosion3x3 bs = new BinaryErosion3x3(); ColorFiltering cf = new ColorFiltering(); cf.Red = new IntRange(90, 160); cf.Green = new IntRange(55, 110); cf.Blue = new IntRange(15, 85); cf.ApplyInPlace(textBmp); //for (int i = 0; i < textBmp.Width; i++) //{ // for (int j = 0; j < textBmp.Height; j++) // { // if (((textBmp.GetPixel(i, j).R > 95) && (textBmp.GetPixel(i, j).R < 155)) && ((textBmp.GetPixel(i, j).G > 60) && (textBmp.GetPixel(i, j).G > 105)) && ((textBmp.GetPixel(i, j).B > 20 && (textBmp.GetPixel(i, j).B < 80)))) // { // textBmp.SetPixel(i, j, Color.Black); // } // else // { // textBmp.SetPixel(i, j, Color.White); // } // } //} BilateralSmoothing bss = new BilateralSmoothing(); bss.KernelSize = 7; bss.SpatialFactor = 5; bss.ColorFactor = 30; bss.ColorPower = 0.5; bss.ApplyInPlace(textBmp); textBmp = gs.Apply(textBmp); th.ApplyInPlace(textBmp); //bs.ApplyInPlace(textBmp); //erose.ApplyInPlace(textBmp); return(textBmp); }
//TODO //FIXME public static string CalculateHash(Bitmap original, string save_filtered_to = null) { // Hash calculation is very discriminating. If a pixel changes in color, the whole hash will be different. // For us this is too rigid: we might support some "noise" or "error", manly because of animation of buttons. // For this reason, it is a good idea to apply some filter to the image in order to flattern common pizels. // A way to do this is to lower the image quality // Apply some common filter and then calculate the hash. if (original == null) { return(null); } using (Bitmap bmp = Grayscale.CommonAlgorithms.BT709.Apply(original)) { // Apply the Threshold var threshold = new SISThreshold(); threshold.ApplyInPlace(bmp); Erosion f = new Erosion(); f.ApplyInPlace(bmp); ImageConverter converter = new ImageConverter(); byte[] rawImageData = converter.ConvertTo(bmp, typeof(byte[])) as byte[]; MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider(); byte[] hash = md5.ComputeHash(rawImageData); StringBuilder sb = new StringBuilder(); for (int i = 0; i < hash.Length; i++) { sb.Append(hash[i].ToString("X2")); } string strhash = sb.ToString(); if (save_filtered_to != null) { bmp.Save(string.Format(save_filtered_to, strhash + "_filtered")); } return(strhash); } }
private void process_image(PictureBox box, bool toinvert) { Bitmap original = (Bitmap)Bitmap.FromFile(_fname); original.Save("C:\\users\\alberto geniola\\desktop\\dbg\\original_" + toinvert + ".bmp"); // Setup the Blob counter BlobCounter blobCounter = new BlobCounter(); blobCounter.BackgroundThreshold = Color.FromArgb(10, 10, 10); blobCounter.FilterBlobs = true; blobCounter.CoupledSizeFiltering = false; blobCounter.MinHeight = minHeight; blobCounter.MinWidth = minWidth; List <Blob> blobs = new List <Blob>(); // Button scanning // Apply the grayscale. This is needed for AForge's filters using (Bitmap grey_scaled = Grayscale.CommonAlgorithms.BT709.Apply(original)) { // Invert the image if requested if (toinvert) { Invert invert = new Invert(); invert.ApplyInPlace(grey_scaled); } using (Bitmap t1 = new Threshold(64).Apply(grey_scaled)) { using (var tmp = new Bitmap(t1.Width, t1.Height)) { using (Graphics g = Graphics.FromImage(tmp)) { g.DrawImage(t1, 0, 0); } tmp.Save("C:\\users\\alberto geniola\\desktop\\dbg\\filtered_" + toinvert + ".bmp"); // The blob counter will analyze the bitmap looking for shapes blobCounter.ProcessImage(tmp); var tmparr = blobCounter.GetObjectsInformation(); blobs.AddRange(tmparr); for (int i = 0, n = tmparr.Length; i < n; i++) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); if (edgePoints.Count > 1) { IntPoint p0, p1; PointsCloud.GetBoundingRectangle(edgePoints, out p0, out p1); var r = new Rectangle(p0.X, p0.Y, p1.X - p0.X, p1.Y - p0.Y); // Skip any shape representing the border of the whole window ( +10px padding) if (r.Width >= (original.Width - 10)) { continue; } using (var g = Graphics.FromImage(tmp)) { g.DrawRectangle(_marker, r); } } } tmp.Save("C:\\users\\alberto geniola\\desktop\\dbg\\processed_" + toinvert + ".bmp"); } } using (Bitmap t2 = new SISThreshold().Apply(grey_scaled)) { using (var tmp = new Bitmap(t2.Width, t2.Height)) { using (Graphics g = Graphics.FromImage(tmp)) { g.DrawImage(t2, 0, 0); } tmp.Save("C:\\users\\alberto geniola\\desktop\\dbg\\t2_" + toinvert + ".bmp"); // The blob counter will analyze the bitmap looking for shapes blobCounter.ProcessImage(tmp); var tmparr = blobCounter.GetObjectsInformation(); blobs.AddRange(tmparr); for (int i = 0, n = tmparr.Length; i < n; i++) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); if (edgePoints.Count > 1) { IntPoint p0, p1; PointsCloud.GetBoundingRectangle(edgePoints, out p0, out p1); var r = new Rectangle(p0.X, p0.Y, p1.X - p0.X, p1.Y - p0.Y); // Skip any shape representing the border of the whole window ( +10px padding) if (r.Width >= (original.Width - 10)) { continue; } using (var g = Graphics.FromImage(tmp)) { g.DrawRectangle(_marker, r); } } } tmp.Save("C:\\users\\alberto geniola\\desktop\\dbg\\t1_" + toinvert + ".bmp"); } } } Bitmap test = (Bitmap)original.Clone(); // Let's analyze every single shape for (int i = 0, n = blobs.Count; i < n; i++) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); if (edgePoints.Count > 1) { IntPoint p0, p1; PointsCloud.GetBoundingRectangle(edgePoints, out p0, out p1); var r = new Rectangle(p0.X, p0.Y, p1.X - p0.X, p1.Y - p0.Y); // Skip any shape representing the border of the whole window ( +10px padding) if (r.Width >= (original.Width - 10)) { continue; } using (var g = Graphics.FromImage(test)) { g.DrawRectangle(_marker, r); } // This is most-likely a button! // Crop the image and pass it to the OCR engine for text recognition using (Bitmap button = new Bitmap(r.Width, r.Height)) { // Scan the original shape String txt = null; using (var g1 = Graphics.FromImage(button)) { g1.DrawImage(original, 0, 0, r, GraphicsUnit.Pixel); } // Process OCR on that image txt = scanButton(button); if (String.IsNullOrEmpty(txt)) { using (Bitmap tmp = Grayscale.CommonAlgorithms.BT709.Apply(button)) { if (toinvert) { new Invert().ApplyInPlace(tmp); } new SISThreshold().ApplyInPlace(tmp); txt = scanButton(tmp); } } // If still nothing is found, repeat the analysis with the second version of the filter if (String.IsNullOrEmpty(txt)) { using (Bitmap tmp = Grayscale.CommonAlgorithms.BT709.Apply(button)) { if (toinvert) { new Invert().ApplyInPlace(tmp); } new Threshold(64).ApplyInPlace(tmp); txt = scanButton(tmp); } } if (!String.IsNullOrEmpty(txt)) { using (var g = Graphics.FromImage(test)) { int SPACING = 5; double angle = 45 * 2 * Math.PI / 360; // 45 degrees to radiants for (int x = 0; x < r.Width; x += SPACING) { PointF start = new PointF(r.X + x, r.Y); PointF end = new PointF((float)(r.X + x + r.Height * Math.Tan(angle)), r.Y + r.Height); if (end.X > (r.X + r.Width)) { // Calculate midpoint var delta = end.X - r.Width; end.X = r.X + r.Width; end.Y = r.Y + (float)(Math.Tan(angle) * r.Width) - x; // Draw the overflow line g.DrawLine(_marker2, r.X, end.Y, delta, r.Y + r.Height); } g.DrawLine(_marker2, start, end); } g.FillRectangle(_b, r); var dim = g.MeasureString(txt.Trim(), _f); g.DrawString(txt.Trim().ToUpper(), _f, _b2, r.X + (r.Width - dim.Width) / 2, r.Y + (r.Height - dim.Height) / 2); } } test.Save("C:\\users\\alberto geniola\\desktop\\dbg\\processed_" + toinvert + ".bmp"); /* * // At this point we should have a result. Add it to list if it does not overlap any UIAutomated element * UIControlCandidate t = new UIControlCandidate(); * t.PositionWindowRelative = r; * var winLoc = w.WindowLocation; * t.PositionScreenRelative = new Rectangle(r.X + winLoc.X, r.Y + winLoc.Y, r.Width, r.Height); * t.Text = txt; * t.Score = policy.RankElement(t); * * // If the item falls into the same area of a UI element, ignore it. * bool overlaps = false; * foreach (var el in res) * { * if (el.AutoElementRef != null && el.PositionScreenRelative.IntersectsWith(t.PositionScreenRelative)) * { * overlaps = true; * break; * } * } * if (!overlaps) * res.Add(t); */ } } box.Image = test; } }
private void video_NewFrame1(object sender, NewFrameEventArgs eventArgs) { videoCapture.Stop(); pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage; pictureBox2.SizeMode = PictureBoxSizeMode.CenterImage; pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone(); //pictureBox2.Image = (Bitmap)eventArgs.Frame.Clone(); image = (Bitmap)eventArgs.Frame.Clone(); byte[,] matrix = new byte[4, 4] { { 95, 233, 127, 255 }, { 159, 31, 191, 63 }, { 111, 239, 79, 207 }, { 175, 47, 143, 15 } }; switch (choice) { case 0: { } break; //Threshold case 1: { Grayscale g = new Grayscale(0.2125, 0.7154, 0.0721); image = g.Apply(image); Threshold filter = new Threshold(100); applyfilter(filter); } break; //OrderedDithering case 2: { Grayscale g = new Grayscale(0.2125, 0.7154, 0.0721); image = g.Apply(image); OrderedDithering filter = new OrderedDithering(matrix); applyfilter(filter); } break; //BayerDithering case 3: { Grayscale g = new Grayscale(0.2125, 0.7154, 0.0721); image = g.Apply(image); BayerDithering filter = new BayerDithering(); applyfilter(filter); } break; //floyd case 4: { Grayscale g = new Grayscale(0.2125, 0.7154, 0.0721); image = g.Apply(image); FloydSteinbergDithering filter = new FloydSteinbergDithering(); applyfilter(filter); } break; //burkes case 5: { Grayscale g = new Grayscale(0.2125, 0.7154, 0.0721); image = g.Apply(image); BurkesDithering filter = new BurkesDithering(); applyfilter(filter); } break; //jarvis case 6: { Grayscale g = new Grayscale(0.2125, 0.7154, 0.0721); image = g.Apply(image); JarvisJudiceNinkeDithering filter = new JarvisJudiceNinkeDithering(); applyfilter(filter); } break; //sierra case 7: { Grayscale g = new Grayscale(0.2125, 0.7154, 0.0721); image = g.Apply(image); SierraDithering filter = new SierraDithering(); applyfilter(filter); } break; //stucki case 8: { Grayscale g = new Grayscale(0.2125, 0.7154, 0.0721); image = g.Apply(image); StuckiDithering filter = new StuckiDithering(); applyfilter(filter); } break; //Homogenity case 9: { Grayscale g = new Grayscale(0.2125, 0.7154, 0.0721); image = g.Apply(image); HomogenityEdgeDetector filter = new HomogenityEdgeDetector(); applyfilter(filter); } break; //rotate case 10: { applyfilter(new RotateChannels()); } break; //sobel case 11: { Grayscale g = new Grayscale(0.2125, 0.7154, 0.0721); image = g.Apply(image); SobelEdgeDetector filter = new SobelEdgeDetector(); applyfilter(filter); } break; //canny case 12: { Grayscale g = new Grayscale(0.2125, 0.7154, 0.0721); image = g.Apply(image); CannyEdgeDetector filter = new CannyEdgeDetector(); applyfilter(filter); } break; case 13: { applyfilter(new YCbCrFiltering()); } break; case 14: { applyfilter(new HueModifier(180)); } break; //SIS Threshold case 15: { Grayscale g = new Grayscale(0.2125, 0.7154, 0.0721); image = g.Apply(image); SISThreshold filter = new SISThreshold(); applyfilter(filter); } break; //Difference case 16: { Grayscale g = new Grayscale(0.2125, 0.7154, 0.0721); image = g.Apply(image); DifferenceEdgeDetector filter = new DifferenceEdgeDetector(); applyfilter(filter); } break; //mirror case 17: { applyfilter(new Mirror(false, true)); } break; //flip case 18: { applyfilter(new RotateBilinear(180, true)); } break; //Erosion case 19: { applyfilter1(new Erosion()); } break; //Dilatation case 20: { applyfilter1(new Dilatation()); } break; //Opening case 21: { applyfilter1(new Opening()); } break; //closing case 22: { applyfilter1(new Closing()); } break; //jitter case 23: { applyfilter(new Jitter(15)); } break; //OilPainting case 24: { applyfilter(new OilPainting(10)); } break; //pixellate case 25: { applyfilter(new Pixellate(10)); } break; } }
static void Main(string[] args) { try { bool parm_error = false; if (args.Length == 0) { exitWithHelp(); // Exit! No param } //set mandatory parm string in_path = ""; //optional parm bool cropcenter = false; bool emulate = false; bool debug = false; //optional blob parm bool blob = false; string bfilterw = ""; double bfilterw_min = 1; double bfilterw_max = 1; string bfilterh = ""; double bfilterh_min = 1; double bfilterh_max = 1; bool blob_noff = false; bool blob_noshape = false; bool blob_notrotate = false; string blob_zone = ""; double blob_zonex = 0.5; double blob_zoney = 0.5; //parsing parm for (int p = 0; p < args.Length; p++) { //for each parm get type and value //ex. -parm value -parm2 value2 //get parm switch (args[p]) { case "-debug": debug = true; break; case "-f": in_path = args[p + 1]; break; case "-cropcenter": cropcenter = true; break; case "-emulate": emulate = true; break; case "-blob": blob = true; break; case "-bfilterw": bfilterw = args[p + 1]; break; case "-bfilterh": bfilterh = args[p + 1]; break; case "-bnoff": blob_noff = true; break; case "-bzone": blob_zone = args[p + 1]; break; case "-bnoshape": blob_noshape = true; break; case "-bnotrotate": blob_notrotate = true; break; default: if (args[p].StartsWith("-")) { exitNotValid(args[p]); // Exit! Invalid param } break; } } //check mandatory param if (in_path.Equals("")) { exitWithHelp(); } //check others param if (!bfilterw.Equals("")) { RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline; Regex pattern = new Regex(@"((?:[0]\.)?\d+)\-((?:[0]\.)?\d+)", options); Match match = pattern.Match(bfilterw); if (match.Success && match.Groups.Count.Equals(3)) { bfilterw_min = Convert.ToDouble(match.Groups[1].Value.Replace('.', ',')); bfilterw_max = Convert.ToDouble(match.Groups[2].Value.Replace('.', ',')); } else { exitWithError("Opzione '-bfilterw' non valida.", "Specificare i valori minimi e massimi nel seguente formato:", " -bfilterw valoremin-valoremax", " es. -bfilterw 0.30-0.40"); } } if (!bfilterh.Equals("")) { RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline; Regex pattern = new Regex(@"((?:[0]\.)?\d+)\-((?:[0]\.)?\d+)", options); Match match = pattern.Match(bfilterh); if (match.Success && match.Groups.Count.Equals(3)) { bfilterh_min = Convert.ToDouble(match.Groups[1].Value.Replace('.', ',')); bfilterh_max = Convert.ToDouble(match.Groups[2].Value.Replace('.', ',')); } else { exitWithError("Opzione '-bfilterh' non valida.", "Specificare i valori minimi e massimi nel seguente formato:", " -bfilterh valoremin-valoremax", " es. -bfilterh 0.30-0.40"); } } if (!blob_zone.Equals("")) { RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline; Regex pattern = new Regex(@"((?:[0]\.)?\d+)\,((?:[0]\.)?\d+)", options); Match match = pattern.Match(blob_zone); if (match.Success && match.Groups.Count.Equals(3)) { blob_zonex = Convert.ToDouble(match.Groups[1].Value.Replace('.', ',')); blob_zoney = Convert.ToDouble(match.Groups[2].Value.Replace('.', ',')); } else { exitWithError("Opzione '-bzone' non valida.", "Specificare le coordinate del punto dove cercare il barcode.", " -bzone x,y", " es. -bzone 0.5,0.5"); } } //check validity if (File.Exists(in_path)) { in_path = Path.GetFullPath(in_path); } else { exitFileNotFound(in_path); } //START Stopwatch stopWatch = new Stopwatch(); if (emulate) { stopWatch.Start(); } //Convert to image if PDF string tmp_path = ""; bool tmp_file = false; if (Path.GetExtension(in_path).Equals(".pdf")) { if (debug) { Console.WriteLine("Converting pdf..."); } tmp_path = in_path + ".png"; tmp_file = true; libImage.ConvertSingleImage(in_path, tmp_path, 300); } else { tmp_path = in_path; } //Load image in memory and del file System.Drawing.Bitmap tmp_img; using (System.Drawing.Bitmap img_source = (Bitmap)Bitmap.FromFile(tmp_path)) { tmp_img = new Bitmap(img_source); } if (tmp_file) { File.Delete(tmp_path); } //Get Info on page int page_w = tmp_img.Width; int page_h = tmp_img.Height; if (debug) { Console.WriteLine("File dimension: w=" + page_w + " h=" + page_h); } //Crop Center if (cropcenter) { if (debug) { Console.WriteLine("Cropping central image..."); } int crop_x = Convert.ToInt32(((double)tmp_img.Width * 0.3)), crop_y = Convert.ToInt32(((double)tmp_img.Height * 0.3)), crop_width = Convert.ToInt32(((double)tmp_img.Width * 0.7) - crop_x), crop_height = Convert.ToInt32(((double)tmp_img.Height * 0.7) - crop_y); //source = source.crop(crop_x, crop_y, crop_width, crop_height); tmp_img = tmp_img.Clone(new Rectangle(crop_x, crop_y, crop_width, crop_height), PixelFormat.Format32bppArgb); page_w = tmp_img.Width; page_h = tmp_img.Height; if (debug) { Console.WriteLine("New file dimension: w=" + page_w + " h=" + page_h); } } else { tmp_img = AForge.Imaging.Image.Clone(tmp_img, PixelFormat.Format32bppArgb); } //Blob Analysis if (blob) { if (debug) { Console.WriteLine("Starting Blob Analysis..."); } // filter GreyScale Grayscale filterg = new Grayscale(0.2125, 0.7154, 0.0721); tmp_img = filterg.Apply(tmp_img); Bitmap tmp_img_wrk = (Bitmap)tmp_img.Clone(); // filter Erosion3x3 BinaryErosion3x3 filter = new BinaryErosion3x3(); tmp_img_wrk = filter.Apply(tmp_img_wrk); tmp_img_wrk = filter.Apply(tmp_img_wrk); tmp_img_wrk = filter.Apply(tmp_img_wrk); tmp_img_wrk = filter.Apply(tmp_img_wrk); tmp_img_wrk = filter.Apply(tmp_img_wrk); tmp_img_wrk = filter.Apply(tmp_img_wrk); //Binarization SISThreshold filterSIS = new SISThreshold(); tmp_img_wrk = filterSIS.Apply(tmp_img_wrk); //Inversion Invert filterI = new Invert(); tmp_img_wrk = filterI.Apply(tmp_img_wrk); //Blob Analisys BlobCounterBase bc = new BlobCounter(); bc.FilterBlobs = true; if (!bfilterw.Equals("")) { bc.MinWidth = Convert.ToInt32(page_w * bfilterw_min); // 0.15 in proporzione è il 20% bc.MaxWidth = Convert.ToInt32(page_w * bfilterw_max); // 0.30 } if (!bfilterh.Equals("")) { bc.MinHeight = Convert.ToInt32(page_h * bfilterh_min); // 0.10 in proporzione è il 15% bc.MaxHeight = Convert.ToInt32(page_h * bfilterh_max); // 0.20 } if (debug) { Console.WriteLine("Searching blob (Dimension filter: w=" + bc.MinWidth + "-" + (bc.MaxWidth.Equals(int.MaxValue) ? "max" : bc.MaxWidth.ToString()) + " h=" + bc.MinHeight + "-" + (bc.MaxHeight.Equals(int.MaxValue) ? "max": bc.MaxHeight.ToString()) + ")"); } bc.ObjectsOrder = ObjectsOrder.Size; bc.ProcessImage(tmp_img_wrk); Blob[] blobs = bc.GetObjectsInformation(); if (debug) { Console.WriteLine("Blobs found: " + blobs.Count()); } //Esamina Blobs int i = 1; foreach (Blob b in blobs) { //Escludi blob contenitore (l'immagine stessa) if (b.Rectangle.Width == page_w) { if (debug) { Console.WriteLine("Blob " + i + ": skip! (is container)"); } i++; continue; } //check form factor if (!blob_noff) { double formf = (Convert.ToDouble(b.Rectangle.Width) / Convert.ToDouble(b.Rectangle.Height)) * 100; if (formf < 95) { //skip Form Factor Not a square if (debug) { Console.WriteLine("Blob " + i + ": Check 1 - Form factor > 95 Failed! (form factor is not square " + formf + "<95) Blob Skipped!"); Console.WriteLine("You can disable this check with -bnoff parameter."); } i++; continue; } if (debug) { Console.WriteLine("Blob " + i + ": Check 1 - Form factor > 95 " + formf + " Ok!"); } } else if (debug) { Console.WriteLine("Blob " + i + ": Check 1 - Form factor > 95 skipped by option -bnoff "); } //check zone if (!blob_zone.Equals("")) { Rectangle bZone = b.Rectangle; bZone.Inflate(Convert.ToInt32(b.Rectangle.Width * 0.2), Convert.ToInt32(b.Rectangle.Height * 0.2)); if (!bZone.Contains(Convert.ToInt32(page_w * blob_zonex), Convert.ToInt32(page_h * blob_zoney))) { //skip Zone Not in center if (debug) { Console.WriteLine("Blob " + i + ": Check 2 - Zone of blob Failed! (Not in the zone requested! blob zone:" + b.Rectangle.ToString() + " and requested point is at x=" + Convert.ToInt32(page_w * blob_zonex) + ",y=" + Convert.ToInt32(page_h * blob_zonex) + " ) Blob Skipped!"); } i++; continue; } if (debug) { Console.WriteLine("Blob " + i + ": Check 2 - Zone of blob contains " + Convert.ToInt32(page_w * blob_zonex) + "," + Convert.ToInt32(page_h * blob_zonex) + "... Ok!"); } } //check shape List <IntPoint> edgePoints = bc.GetBlobsEdgePoints(b); List <IntPoint> corners; SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); if (shapeChecker.IsQuadrilateral(edgePoints, out corners)) { if (!blob_noshape) { PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners); if (!subType.Equals(PolygonSubType.Square)) { //skip Not a square if (debug) { Console.WriteLine("Blob " + i + ": Check 3 - Shape is Square Failed! (Shape is not Square! " + subType.ToString() + " detected!) Blob Skipped!"); Console.WriteLine("You can disable this check with -bnoshape parameter."); } i++; continue; } else if (debug) { Console.WriteLine("Blob " + i + ": Check 3 - Shape is Square Ok!"); } } else if (debug) { Console.WriteLine("Blob " + i + ": Check 3 - Shape is Square skipped by option -bnoshape "); } } else { shapeChecker.ToString(); //skip Not a quadrilateral if (debug) { Console.WriteLine("Blob " + i + ": Check 3 - Shape is Square... Failed! (not a Quadrilateral! ConvexPolygon:" + shapeChecker.IsConvexPolygon(edgePoints, out corners) + " Triangle:" + shapeChecker.IsTriangle(edgePoints, out corners) + ") Blob Skipped!"); } i++; continue; } //if (debug){ Console.WriteLine("Blob " + i + ": Trying to decode..."); } //Calculate rotation angle 0 bottom left , 1 top left , 2 top right, 3 bottom right double dx = corners[2].X - corners[1].X; double dy = corners[1].Y - corners[2].Y; double ang = Math.Atan2(dx, dy) * (180 / Math.PI); if (ang > 90) { ang = ang - 90; } else { ang = 90 - ang; } //Extract Blob Rectangle cropRect = b.Rectangle; cropRect.Inflate(Convert.ToInt32(b.Rectangle.Width * 0.1), Convert.ToInt32(b.Rectangle.Height * 0.1)); Crop filter_blob = new Crop(cropRect); Bitmap tmp_img_blob = filter_blob.Apply(tmp_img); //Rotate if (!blob_notrotate) { RotateBilinear filterRotate = new RotateBilinear(ang, true); tmp_img_blob = filterRotate.Apply(tmp_img_blob); //Togli margine esterno (bande nere derivanti dalla rotazione) Rectangle cropRectInterno = new Rectangle(0, 0, tmp_img_blob.Width, tmp_img_blob.Height); cropRectInterno.Inflate(-Convert.ToInt32(b.Rectangle.Width * 0.05), -Convert.ToInt32(b.Rectangle.Height * 0.05)); Crop filterCropInterno = new Crop(cropRectInterno); tmp_img_blob = filterCropInterno.Apply(tmp_img_blob); if (debug) { Console.WriteLine("Blob " + i + ": Rotated and aligned! (angle:" + ang + ")"); } } else { if (debug) { Console.WriteLine("Blob " + i + ": Rotation skipped by option -bnotrotate (angle:" + ang + ")"); } } //Applica filtri var filter1 = new Median(); filter1.ApplyInPlace(tmp_img_blob); var filter2 = new OtsuThreshold(); filter2.ApplyInPlace(tmp_img_blob); //Decodifica if (debug) { Console.WriteLine("Blob " + i + ": Extracted! Trying to decode..."); } BarcodeReader reader = new BarcodeReader { AutoRotate = true }; Result result = reader.Decode(tmp_img_blob); //Output Results if (result != null) { if (emulate) { stopWatch.Stop(); Console.WriteLine("Success in " + stopWatch.Elapsed); } else { Console.WriteLine(result.Text); } Environment.Exit(0); } else if (debug) { Console.WriteLine("Blob " + i + ": Decode failed! (Result null)"); } } } else { BarcodeReader reader = new BarcodeReader { AutoRotate = true }; Result result = reader.Decode(tmp_img); //Output Results if (result != null) { if (emulate) { stopWatch.Stop(); Console.WriteLine(stopWatch.Elapsed); } else { Console.WriteLine(result.Text); Environment.Exit(0); } } else if (debug) { Console.WriteLine("Decode failed! (Result null)"); } } //Exit if (emulate && stopWatch.IsRunning) { stopWatch.Stop(); Console.WriteLine("Failure in " + stopWatch.Elapsed); } Environment.Exit(0); } catch (Exception ex) { Console.WriteLine("Fatal Error: " + ex.Message + "\n" + ex.InnerException); } }
private static void Main(string[] args) { Bitmap image = (Bitmap)Bitmap.FromFile(@"C:\Users\Slava\Downloads\garage2.jpg"); // create grayscale filter (BT709) Grayscale grayscale = new Grayscale(0.2125, 0.7154, 0.0721); SISThreshold sISThreshold = new SISThreshold(); Bitmap grayImage = grayscale.Apply(image); Bitmap bitmapImage = sISThreshold.Apply(grayImage); Bitmap pattern = new Bitmap(@"C:\Users\Slava\Downloads\garagePattern.png"); //you should use the ToArgb method to compare two Colors int currentAssesment = 0; int bestAssesment = 0; int bestStartX = 0; int bestStartY = 0; int inc = 10; //move pattern square inside image squate for (int i = 0; i < 2; i++) { int borderByWidth = bitmapImage.Width - pattern.Width; int borderByHeight = bitmapImage.Height - pattern.Height; if (i == 1) { inc = 1; borderByWidth = (bestStartX + 10) > borderByWidth ? borderByWidth : (bestStartX + 10); borderByHeight = (bestStartY + 10) > borderByHeight ? borderByHeight : (bestStartY + 10); } for (int startX = (i == 0) ? 0 : ((bestStartX - 10) < 0 ? 0 : (bestStartX - 10)); startX < borderByWidth; startX += inc) { for (int startY = (i == 0) ? 0 : ((bestStartY - 10) < 0 ? 0 : (bestStartY - 10)); startY < borderByHeight; startY += inc) { for (int w = 0; w < pattern.Width; w++) { for (int h = 0; h < pattern.Height; h++) { int bitmapPixel = bitmapImage.GetPixel(w + startX, h + startY).ToArgb(); int patternPixel = pattern.GetPixel(w, h).ToArgb(); if (bitmapPixel == patternPixel) { currentAssesment++; } //only this values //if (r != -1 && r != -16777216) //{ // System.Console.WriteLine(x); //} } } if (bestAssesment < currentAssesment) { bestAssesment = currentAssesment; bestStartX = startX; bestStartY = startY; } currentAssesment = 0; } System.Console.Write($"{startX}"); } System.Console.WriteLine($"done. best assesmet: {bestAssesment}, X: {bestStartX}, Y: {bestStartY}"); } }
private void Button_HSV_Filter_Click(object sender, EventArgs e) { Bitmap image = new Bitmap(pictureBox1.Image); HSLFiltering filterHsl = new HSLFiltering(); Mean filterMean = new Mean(); filterHsl.Luminance = new AForge.Range(0.1f, 1); filterHsl.UpdateHue = false; filterHsl.UpdateSaturation = false; filterHsl.UpdateLuminance = true; filterHsl.ApplyInPlace(image); filterMean.ApplyInPlace(image); SISThreshold filterThresold = new SISThreshold(); GrayscaleBT709 filterGray = new GrayscaleBT709(); image = filterGray.Apply(image); Bitmap clone = image.Clone(new Rectangle(0, 0, image.Width, image.Height), PixelFormat.Format8bppIndexed); filterThresold.ApplyInPlace(clone); image = clone; Bitmap clone2normal = image.Clone(new Rectangle(0, 0, image.Width, image.Height), PixelFormat.Format32bppRgb); image = clone2normal; BlobCounter bc = new BlobCounter(); bc.FilterBlobs = true; bc.MinWidth = 5; bc.MinHeight = 5; bc.ProcessImage(image); Blob[] blobs = bc.GetObjects(image, false); var rectanglesToClear = from blob in blobs select blob.Rectangle; using (var gfx = Graphics.FromImage(image)) { foreach (var rect in rectanglesToClear) { if (rect.Height < 20 && rect.Width < 20) { gfx.FillRectangle(Brushes.White, rect); } } gfx.Flush(); } Dilatation filterDilation = new Dilatation(); image = image.Clone(new Rectangle(0, 0, image.Width, image.Height), PixelFormat.Format48bppRgb); filterDilation.ApplyInPlace(image); filterDilation.ApplyInPlace(image); Erosion filterErosion = new Erosion(); filterErosion.ApplyInPlace(image); pictureBox2.Image = image; }
/// <summary> /// Given the Window UI Screenshot, tries to detect all the buttons in it and returns all of them. /// </summary> /// <param name="res">Where to put candidate controls</param> /// <param name="bitmap">Bitmap containing the pixels of the UI to analyze</param> /// <param name="shouldInvert">If true, the bitmap will be inverted before analysis</param> /// <param name="minWidth">Minimum width of patterns to recognize</param> /// <param name="minHeight">Minimum height of patterns to recognize</param> /// <returns>void</returns> private void ScanWithVisualRecognition(ref CandidateSet res, Bitmap original, bool shouldInvert, int minWidth, int minHeight, Window w, IRankingPolicy policy) { // Setup the Blob counter BlobCounter blobCounter = new BlobCounter(); blobCounter.BackgroundThreshold = Color.FromArgb(10, 10, 10); blobCounter.FilterBlobs = true; blobCounter.CoupledSizeFiltering = false; blobCounter.MinHeight = minHeight; blobCounter.MinWidth = minWidth; List <Blob> blobs = new List <Blob>(); // Button scanning // Apply the grayscale. This is needed for AForge's filters using (Bitmap grey_scaled = Grayscale.CommonAlgorithms.BT709.Apply(original)) { // Invert the image if requested if (shouldInvert) { Invert invert = new Invert(); invert.ApplyInPlace(grey_scaled); } //grey_scaled.Save("C:\\users\\alberto geniola\\desktop\\dbg\\gray_scaled_" + toinvert + ".bmp"); using (Bitmap t1 = new Threshold(64).Apply(grey_scaled)) { using (var tmp = new Bitmap(t1.Width, t1.Height)) { using (Graphics g = Graphics.FromImage(tmp)) { g.DrawImage(t1, 0, 0); } // The blob counter will analyze the bitmap looking for shapes blobCounter.ProcessImage(tmp); var tmparr = blobCounter.GetObjectsInformation(); blobs.AddRange(tmparr); } } using (Bitmap t2 = new SISThreshold().Apply(grey_scaled)) { using (var tmp = new Bitmap(t2.Width, t2.Height)) { using (Graphics g = Graphics.FromImage(tmp)) { g.DrawImage(t2, 0, 0); } //tmp.Save("C:\\users\\alberto geniola\\desktop\\dbg\\t2_" + toinvert + ".bmp"); // The blob counter will analyze the bitmap looking for shapes blobCounter.ProcessImage(tmp); var tmparr = blobCounter.GetObjectsInformation(); blobs.AddRange(tmparr); } } } // Let's analyze every single shape for (int i = 0, n = blobs.Count; i < n; i++) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); if (edgePoints.Count > 1) { IntPoint p0, p1; PointsCloud.GetBoundingRectangle(edgePoints, out p0, out p1); var r = new Rectangle(p0.X, p0.Y, p1.X - p0.X, p1.Y - p0.Y); // Skip any shape representing the border of the whole window ( +10px padding) if (r.Width >= (original.Width - 10)) { continue; } // This is most-likely a button! // Crop the image and pass it to the OCR engine for text recognition using (Bitmap button = new Bitmap(r.Width, r.Height)) { // Scan the original shape String txt = null; using (var g1 = Graphics.FromImage(button)) { g1.DrawImage(original, 0, 0, r, GraphicsUnit.Pixel); } // Process OCR on that image txt = scanButton(button); if (String.IsNullOrEmpty(txt)) { using (Bitmap tmp = Grayscale.CommonAlgorithms.BT709.Apply(button)) { if (shouldInvert) { new Invert().ApplyInPlace(tmp); } new SISThreshold().ApplyInPlace(tmp); txt = scanButton(tmp); } } // If still nothing is found, repeat the analysis with the second version of the filter if (String.IsNullOrEmpty(txt)) { using (Bitmap tmp = Grayscale.CommonAlgorithms.BT709.Apply(button)) { if (shouldInvert) { new Invert().ApplyInPlace(tmp); } new Threshold(64).ApplyInPlace(tmp); txt = scanButton(tmp); } } // At this point we should have a result. Add it to list if it does not overlap any UIAutomated element UIControlCandidate t = new UIControlCandidate(); t.PositionWindowRelative = r; var winLoc = w.WindowLocation; t.PositionScreenRelative = new Rectangle(r.X + winLoc.X, r.Y + winLoc.Y, r.Width, r.Height); t.Text = txt; t.Score = policy.RankElement(t); // If the item falls into the same area of a UI element, ignore it. bool overlaps = false; foreach (var el in res) { if (el.AutoElementRef != null && el.PositionScreenRelative.IntersectsWith(t.PositionScreenRelative)) { overlaps = true; break; } } if (!overlaps) { res.Add(t); } } } } }