public Bitmap DocumentAlign(Bitmap image) { 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 return(rotationFilter.Apply(image)); } catch { Console.WriteLine("Failed determining skew angle. Is it reallly a scanned document?"); return(image); } }
void ThresholdingToolStripMenuItemClick(object sender, EventArgs e) { //jika gambar kosong/null maka akan mengembalikan nilai kosong/null if (gambar == null) { return; } //clone variable gambar ke variable gambar2 dan menginisiasi class Rectangle //dan menerapkan format pixel 24bppRgb gambar2 = gambar.Clone(new Rectangle(0, 0, gambar.Width, gambar.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb); //convert ke grayscale terlebih dahulu lalu aplikasikan filter thresholding. //inisiasi filter grayscale disertai argumen Grayscale grayscaleF = new Grayscale(0.2125, 0.7154, 0.0721); //aplikasikan filter grayscale ke gambar2 gambar2 = grayscaleF.Apply(gambar2); //inisiasi filter thresholding OtsuThreshold otsuThreshold = new OtsuThreshold( ); //aplikasikan filter pada gambar2 otsuThreshold.ApplyInPlace(gambar2); //tampilkan pada picturebox2 pictureBox2.Image = gambar2; }
public static int GetThreshold(Bitmap image) { var unmanagedImage = UnmanagedImage.FromManagedImage(image); UnmanagedImage grayImage; if (unmanagedImage.PixelFormat == PixelFormat.Format8bppIndexed) { grayImage = unmanagedImage; } else { grayImage = UnmanagedImage.Create(unmanagedImage.Width, unmanagedImage.Height, PixelFormat.Format8bppIndexed); Grayscale.CommonAlgorithms.BT709.Apply(unmanagedImage, grayImage); unmanagedImage.Dispose(); } var otsuThresholdFilter = new OtsuThreshold(); otsuThresholdFilter.ApplyInPlace(grayImage); var threshold = otsuThresholdFilter.ThresholdValue; grayImage.Dispose(); return(threshold); }
private void process() { stopwatch.Reset(); stopwatch.Start(); plates = new List <string>(); frame = contrastCorrectionFilter.Apply(originalImage); frame = grayscaleFilter.Apply(frame); BitmapData frameData = frame.LockBits(new Rectangle(0, 0, frame.Width, frame.Height), ImageLockMode.ReadWrite, frame.PixelFormat); UnmanagedImage data = new UnmanagedImage(frameData); bradleyLocalFilter.ApplyInPlace(data); fillHoles.ApplyInPlace(data); openingFilter.ApplyInPlace(data); blobCounter.ProcessImage(data); data.Dispose(); frame.UnlockBits(frameData); Graphics g = Graphics.FromImage(originalImage); Blob[] blobs = blobCounter.GetObjectsInformation(); foreach (Blob blob in blobs) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob); List <IntPoint> corners = null; // da li je četverougao? if (!shapeChecker.IsQuadrilateral(edgePoints, out corners)) { continue; } if (FindNewCornersAndCheckAspectRatio(corners)) { SimpleQuadrilateralTransformation sqt = new SimpleQuadrilateralTransformation(corners, 300, 66); Bitmap plate = sqt.Apply(originalImage); plate = grayscaleFilter.Apply(plate); otsuThresholdFilter.ApplyInPlace(plate); if (!IsLicensePlate(plate)) { continue; } String plateText; if (FindText(plate, out plateText)) { g.DrawPolygon(pen, ToPointsArray(corners)); frame = plate; plates.Add(plateText); } } } g.Dispose(); stopwatch.Stop(); }
/* * 1- gray scale transform; * */ public void ToGray(ref Bitmap image) { image = (Bitmap)ResizeImage((System.Drawing.Image)image); // Create a blank bitmap with the same dimensions Bitmap imageGray = new Bitmap(image); Median medianFilter = new Median(); // apply the filter medianFilter.ApplyInPlace(image); // create grayscale filter (BT709) Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721); // apply the filter image = filter.Apply(imageGray); // create filter Invert invertFilter = new Invert(); // apply the filter invertFilter.ApplyInPlace(image); // create filter OtsuThreshold filterOtsuThreshold = new OtsuThreshold(); // apply the filter filterOtsuThreshold.ApplyInPlace(image); // check threshold value int t = filterOtsuThreshold.ThresholdValue; /* * // create and configure the filter * FillHoles holesFilter = new FillHoles(); * holesFilter.MaxHoleHeight = 2; * holesFilter.MaxHoleWidth = 2; * holesFilter.CoupledSizeFiltering = false; * // apply the filter * Bitmap result = holesFilter.Apply(image); * * * BinaryDilatation3x3 bd = new BinaryDilatation3x3(); * bd.ApplyInPlace(image); * bd.ApplyInPlace(image); * * // create filter * BlobsFiltering filterBlobsFiltering = new BlobsFiltering(); * // configure filter * filterBlobsFiltering.CoupledSizeFiltering = true; * filterBlobsFiltering.MinWidth = 5; * filterBlobsFiltering.MinHeight = 5; * // apply the filter * filterBlobsFiltering.ApplyInPlace(image); */ }
private void button1_Click(object sender, EventArgs e) { OtsuThreshold filter = new OtsuThreshold(); Grayscale grayFilter = new Grayscale(0.2125, 0.7154, 0.0721); Bitmap srcBitmap = new Bitmap(sourcePictureBox.Image); Bitmap grayImage = grayFilter.Apply(srcBitmap); filter.ApplyInPlace(grayImage); resultPictureBox.Image = grayImage; chart1.Series[0].Points.DataBindY(calculateChart(grayImage)); }
// Try recognizing the glyph in the specified image defined by the specified quadrilateral private ExtractedGlyphData RecognizeGlyph(UnmanagedImage image, List <IntPoint> quadrilateral, int counter) // counter -> HLE { // extract glyph image quadrilateralTransformation.SourceQuadrilateral = quadrilateral; UnmanagedImage glyphImage = quadrilateralTransformation.Apply(image); // otsu thresholding otsuThresholdFilter.ApplyInPlace(glyphImage); // recognize raw glyph float confidence; byte[,] glyphValues = binaryGlyphRecognizer.Recognize(glyphImage, new Rectangle(0, 0, glyphImage.Width, glyphImage.Height), out confidence); if (confidence >= minConfidenceLevel) { if ((Glyph.CheckIfGlyphHasBorder(glyphValues)) && (Glyph.CheckIfEveryRowColumnHasValue(glyphValues))) { // ---HLE //Save out image for checking System.Drawing.Bitmap managedglyphImage = glyphImage.ToManagedImage(); managedglyphImage.Save("C:\\Users\\heve\\Documents\\_Work_PointCloud\\AAG\\ImageProcessing\\glyphImage_" + counter.ToString() + ".png", System.Drawing.Imaging.ImageFormat.Png); // ---HLE ExtractedGlyphData foundGlyph = new ExtractedGlyphData(quadrilateral, glyphValues, confidence); if (glyphDatabase != null) { int rotation; foundGlyph.RecognizedGlyph = glyphDatabase.RecognizeGlyph(glyphValues, out rotation); if (rotation != -1) { foundGlyph.RecognizedQuadrilateral = foundGlyph.Quadrilateral; while (rotation > 0) { foundGlyph.RecognizedQuadrilateral.Add(foundGlyph.RecognizedQuadrilateral[0]); foundGlyph.RecognizedQuadrilateral.RemoveAt(0); rotation -= 90; } } } return(foundGlyph); } } return(null); }
private void OtsuThreshold_Click(object sender, RoutedEventArgs e) { System.Drawing.Bitmap temp = canvasTool.getBitmapFromCanvas(); temp = Grayscale.CommonAlgorithms.RMY.Apply(temp); OtsuThreshold filter = new OtsuThreshold(); // apply the filter filter.ApplyInPlace(temp); // check threshold value int t = filter.ThresholdValue; canvasTool.SetBmpImageToCanvas(temp); MessageBox.Show("OtsuThreshold Calculated Vaule: " + t, "ThresholdValue", MessageBoxButton.OK, MessageBoxImage.Information); }
private void button4_Click(object sender, EventArgs e) { Grayscale grayfilter = new Grayscale(0.2125, 0.7154, 0.0721); Bitmap edgeImg = grayfilter.Apply(img1); OtsuThreshold filter = new OtsuThreshold(); filter.ApplyInPlace(edgeImg); CannyEdgeDetector filter2 = new CannyEdgeDetector(); img2 = filter2.Apply(edgeImg); pictureBox2.Image = img2; }
// Try recognizing the glyph in the specified image defined by the specified quadrilateral private ExtractedGlyphData RecognizeGlyph(UnmanagedImage image, List <IntPoint> quadrilateral) { // extract glyph image quadrilateralTransformation.SourceQuadrilateral = quadrilateral; UnmanagedImage glyphImage = quadrilateralTransformation.Apply(image); // otsu thresholding otsuThresholdFilter.ApplyInPlace(glyphImage); // recognize raw glyph float confidence; byte[,] glyphValues = binaryGlyphRecognizer.Recognize(glyphImage, new Rectangle(0, 0, glyphImage.Width, glyphImage.Height), out confidence); if (confidence >= minConfidenceLevel) { if ((Glyph.CheckIfGlyphHasBorder(glyphValues)) && (Glyph.CheckIfEveryRowColumnHasValue(glyphValues))) { ExtractedGlyphData foundGlyph = new ExtractedGlyphData(quadrilateral, glyphValues, confidence); if (glyphDatabase != null) { int rotation; foundGlyph.RecognizedGlyph = glyphDatabase.RecognizeGlyph(glyphValues, out rotation); if (rotation != -1) { foundGlyph.RecognizedQuadrilateral = foundGlyph.Quadrilateral; while (rotation > 0) { foundGlyph.RecognizedQuadrilateral.Add(foundGlyph.RecognizedQuadrilateral[0]); foundGlyph.RecognizedQuadrilateral.RemoveAt(0); rotation -= 90; } } } return(foundGlyph); } } return(null); }
/// <summary> /// This method binarize image. /// </summary> /// <param name="image"></param> /// <returns></returns> private Bitmap Binarize(Bitmap image) { Median median = new Median(); median.ApplyInPlace(image); var bmp8bpp = Grayscale.CommonAlgorithms.BT709.Apply(image); OtsuThreshold OtsuThreshold = new OtsuThreshold(); OtsuThreshold.ApplyInPlace(bmp8bpp); //bmp8bpp.Save(@"C:\Users\Maor\Desktop\mode\BinarizeWithoutDilation.jpeg"); Closing closing = new Closing(); closing.ApplyInPlace(bmp8bpp); return(bmp8bpp); }
/// <summary> /// This method binarize dnd dilate image. /// </summary> /// <param name="image"></param> /// <returns></returns> private Bitmap BinarizeAndDilationWithMedian(Bitmap image) { int[,] kernel = { { -2, -1, 0 }, { -1, 1, 1 }, { 0, 1, 2 } }; // create filter Convolution Convolution = new Convolution(kernel); // apply the filter Convolution.ApplyInPlace(image); var bmp8bpp = Grayscale.CommonAlgorithms.BT709.Apply(image); Invert invert = new Invert(); invert.ApplyInPlace(bmp8bpp); Dilatation dilatation = new Dilatation(); dilatation.ApplyInPlace(bmp8bpp); invert.ApplyInPlace(bmp8bpp); Median median = new Median(); median.ApplyInPlace(bmp8bpp); Closing closing = new Closing(); closing.ApplyInPlace(bmp8bpp); OtsuThreshold OtsuThreshold = new OtsuThreshold(); OtsuThreshold.ApplyInPlace(bmp8bpp); //bmp8bpp.Save(@"C:\Users\Maor\Desktop\mode\BinarizeAndDilationWithMedian.jpeg"); return(bmp8bpp); }
private void etal1btn_Click(object sender, EventArgs e) { Grayscale grayfilter = new Grayscale(0.2125, 0.7154, 0.0721); // применяем фильтр grayImage = grayfilter.Apply((Bitmap)vebpb.Image); //выводим на пичербокс //pictureBox1.Image = grayImage; mainImage = grayImage.Clone( new Rectangle(0, 0, grayImage.Width, grayImage.Height), System.Drawing.Imaging.PixelFormat.Format8bppIndexed); Bitmap Image24 = grayImage.Clone( new Rectangle(0, 0, grayImage.Width, grayImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb); Bitmap Image8 = grayImage.Clone( new Rectangle(0, 0, grayImage.Width, grayImage.Height), System.Drawing.Imaging.PixelFormat.Format8bppIndexed); ProcessingImage pi = new ProcessingImage(); OtsuThreshold filter = new OtsuThreshold(); // apply the filter filter.ApplyInPlace(Image8); // check threshold value Invert filter1 = new Invert(); ////// apply the filter filter1.ApplyInPlace(Image8); //изменить блобкаунтер BlobCounter bc = new BlobCounter(); // process binary image bc.ProcessImage(Image8); Rectangle[] rects = bc.GetObjectsRectangles(); Bitmap bp = new Bitmap(Image8); Bitmap final = new Bitmap(Image24.Width, Image24.Height); Bitmap bp8 = new Bitmap(Image8); int xCenter = Image8.Width / 2; int yCenter = Image8.Height / 2; Bitmap tempImage = grayImage.Clone( new Rectangle(0, 0, grayImage.Width, grayImage.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(tempImage); //получаю объект графики из битмап SolidBrush b = new SolidBrush(Color.Black); //кисть для заливки bp = tempImage.Clone(rects[0], System.Drawing.Imaging.PixelFormat.Format24bppRgb); bp8 = Image8.Clone(rects[0], System.Drawing.Imaging.PixelFormat.Format8bppIndexed); g.FillRectangle(b, new Rectangle(0, 0, tempImage.Width, tempImage.Height)); //заполняю for (int x = 0; x < bp8.Width; x++) { for (int y = 0; y < bp8.Height; y++) { if (bp8.GetPixel(x, y).R == 0) { bp.SetPixel(x, y, Color.Black); } } } int shiftX = xCenter - rects[0].Width / 2; int shiftY = yCenter - rects[0].Height / 2; g.DrawImage(bp, shiftX, shiftY, rects[0].Width, rects[0].Height); //etalonimages.Add(tempImage); foreach (PictureBox pb in etalonpanel.Controls.OfType <PictureBox>()) { if (pb.Image == null) { pb.Image = tempImage; break; } } }
private void recognize_Click(object sender, EventArgs e) { label15.Text = ""; if (etalonimages.Count == 0) { foreach (PictureBox pb in etalonpanel.Controls.OfType <PictureBox>()) { if (pb.Image != null) { etalonimages.Add((Bitmap)pb.Image); } } //чтение из файлов параметров ContourEtalCentr = ReadFromFile("ContourCentr.txt", 18); HullEtalCentr = ReadFromFile("HullCentr.txt", 28); ContourEtalMedoid = ReadFromFile("ContourMed.txt", 18); HullEtalMedoid = ReadFromFile("HullCentrMed.txt", 28); } Grayscale grayfilter = new Grayscale(0.2125, 0.7154, 0.0721); // применяем фильтр grayImage = grayfilter.Apply((Bitmap)vebpb.Image); //выводим на пичербокс //pictureBox1.Image = grayImage; //Application.Idle -= GetVideo; mainImage = grayImage.Clone( new Rectangle(0, 0, grayImage.Width, grayImage.Height), System.Drawing.Imaging.PixelFormat.Format8bppIndexed); //медианный фильтр для шумов границ размытых объектов Median filter1 = new Median(); filter1.ApplyInPlace(mainImage); OtsuThreshold filter = new OtsuThreshold(); // apply the filter filter.ApplyInPlace(mainImage); // check threshold value Invert filter2 = new Invert(); // apply the filter filter2.ApplyInPlace(mainImage); // исправили потомучто надо //RecursiveBlobCounter bc = new RecursiveBlobCounter(); BlobCounter bc = new BlobCounter(); // process binary image bc.ProcessImage(mainImage); Rectangle[] rects = bc.GetObjectsRectangles(); List <Bitmap> images = new List <Bitmap>(); List <Bitmap> imagesWithEdge = new List <Bitmap>(); Bitmap bp; int i = 0; foreach (Rectangle rect in rects) { images.Add(new Bitmap(mainImage.Width, mainImage.Height)); Graphics g = Graphics.FromImage(images[i]); //получаю объект графики из битмап SolidBrush b = new SolidBrush(Color.Black); //кисть для заливки g.FillRectangle(b, new Rectangle(0, 0, images[i].Width, images[i].Height)); //заполняю bp = mainImage.Clone(rects[i], System.Drawing.Imaging.PixelFormat.Format8bppIndexed); g.DrawImage(bp, rects[i].X, rects[i].Y, rects[i].Width, rects[i].Height); i++; } //List <List<System.Drawing.Point>> convexHull = new List<List<System.Drawing.Point>>(); ProcessingImage pi = new ProcessingImage(); QuickHull qh = new QuickHull(); Contur cont = new Contur(); List <System.Drawing.Point> localPt = new List <System.Drawing.Point>(); foreach (Bitmap img in images) { //формирование выпуклой оболочки localPt = pi.GetPoints(img); List <System.Drawing.Point> ConvexHullLocal = qh.quickHull(localPt); ConvexHullLocal = qh.DeleteAnglePoints(ConvexHullLocal); convexHull.Add(ConvexHullLocal); //и контура List <System.Drawing.Point> ConturLocal = cont.kontur(img); ConturLocal = cont.DeleteAnglePoints(ConturLocal); edgePoint.Add(ConturLocal); imagesWithEdge.Add(img.Clone(new Rectangle(0, 0, img.Width, img.Height), System.Drawing.Imaging.PixelFormat.Format32bppRgb)); } int hullimagenum = 0; foreach (PictureBox pb in Hullpanel.Controls) { if (hullimagenum < images.Count) { pb.Image = images[hullimagenum]; } hullimagenum++; } //выделение векторов признаков List <Primary> marks = new List <Primary>(); List <double[]> objectMarksHull = new List <double[]>(); List <double[]> objectMarksContur = new List <double[]>(); List <double[]> etallMarksCentrHull = new List <double[]>(); List <double[]> etallMarksCentrContur = new List <double[]>(); List <double[]> etallMarksMedHull = new List <double[]>(); List <double[]> etallMarksMedContur = new List <double[]>(); for (i = 0; i < images.Count; i++) { marks.Add(new Primary(images[i], edgePoint[i], convexHull[i])); objectMarksContur.Add(marks[i].Contour()); objectMarksHull.Add(marks[i].Convex()); } //Отрисовка выпуклой оболочки for (i = 0; i < convexHull.Count; i++) { Graphics gr1 = Graphics.FromImage(images[i]); List <System.Drawing.Point> pt = new List <System.Drawing.Point>(convexHull[i]); for (int j = 0; j < pt.Count; j++) { qh.PutPixel(gr1, Color.Red, pt[j].X, pt[j].Y, 255); } gr1 = Graphics.FromImage(imagesWithEdge[i]); List <System.Drawing.Point> pt1 = new List <System.Drawing.Point>(edgePoint[i]); for (int j = 0; j < pt1.Count; j++) { cont.PutPixel(gr1, Color.Red, pt1[j].X, pt1[j].Y, 255); } } int contourimagenum = 0; foreach (PictureBox pb in Contourpanel.Controls) { if (contourimagenum < imagesWithEdge.Count) { pb.Image = imagesWithEdge[contourimagenum]; } contourimagenum++; } //int hullimagenum = 0; //foreach (PictureBox pb in Hullpanel.Controls) //{ // if (hullimagenum < images.Count) // pb.Image = images[hullimagenum]; // hullimagenum++; //} for (int j = 0; j < etalonimages.Count; j++) { etallMarksCentrContur.Add(ContourEtalCentr[j]); etallMarksMedContur.Add(ContourEtalMedoid[j]); etallMarksCentrHull.Add(HullEtalCentr[j]); etallMarksMedHull.Add(HullEtalMedoid[j]); } for (int l = 0; l < images.Count; l++) { compareobjects(objectMarksHull, objectMarksContur, etallMarksCentrContur, etallMarksMedContur, etallMarksCentrHull, etallMarksMedHull, l); } images.Clear(); convexHull.Clear(); edgePoint.Clear(); imagesWithEdge.Clear(); marks.Clear(); //contourMarks.Clear(); i = 0; }
public static Tuple <Bitmap, double, Rectangle> smate_rotate(Bitmap src) { Bitmap retB = null; Rectangle retR = Rectangle.Empty; double retAngle = 90.0; double angle = 0.0; RotateBicubic filter = new RotateBicubic(retAngle); Bitmap src1 = filter.Apply(src); //Bitmap src1 = (Bitmap)src.Clone(); Bitmap g = Grayscale.CommonAlgorithms.BT709.Apply(src1); Invert it = new Invert(); it.ApplyInPlace(g); //g.Save("temp_1.jpg"); ImageStatistics stat = new ImageStatistics(g); Threshold t = new Threshold((int)(stat.Gray.Mean - stat.Gray.StdDev)); t.ApplyInPlace(g); //g.Save("temp_2.jpg"); stat = new ImageStatistics(g); DifferenceEdgeDetector edgeDetector = new DifferenceEdgeDetector(); edgeDetector.ApplyInPlace(g); //g.Save("temp_3.jpg"); HoughLineTransformation lineTransform = new HoughLineTransformation(); lineTransform.ProcessImage(g); HoughLine[] lines = lineTransform.GetLinesByRelativeIntensity(0.8); foreach (HoughLine l in lines) { Program.logIt(string.Format("Intensity={0}, Radius={1}, Theta={2}", l.Intensity, l.Radius, l.Theta)); if (l.Radius < 0) { if (l.Theta < 90) { angle = -l.Theta; } else { angle = 180.0 - l.Theta; } } else { if (l.Theta < 90) { angle = -l.Theta; } else { angle = 180.0 - l.Theta; } } if (Math.Abs(angle) < 45.0) { break; } } Program.logIt(string.Format("angle={0}", angle)); retAngle += angle; RotateBicubic r_filter = new RotateBicubic(angle); Bitmap rotated = r_filter.Apply(src1); // crop if (rotated != null) { Grayscale g_filter = new Grayscale(0.2125, 0.7154, 0.0721); Bitmap grayImage = g_filter.Apply(rotated); Blur bf = new Blur(); bf.ApplyInPlace(grayImage); OtsuThreshold o_filter = new OtsuThreshold(); o_filter.ApplyInPlace(grayImage); BlobCounter blobCounter = new BlobCounter(); blobCounter.MinHeight = 20; blobCounter.MinWidth = 20; blobCounter.FilterBlobs = false; blobCounter.BlobsFilter = null; blobCounter.ObjectsOrder = ObjectsOrder.YX; blobCounter.ProcessImage(grayImage); Blob[] blobs = blobCounter.GetObjectsInformation(); Program.logIt(string.Format("blobs={0}", blobCounter.ObjectsCount)); Rectangle r = Rectangle.Empty; for (int i = 1; i < blobs.Length; i++) { Blob b = blobs[i]; Program.logIt(string.Format("{0}: {1}", b.ID, b.Rectangle)); if (r == Rectangle.Empty) { r = b.Rectangle; } else { r = Rectangle.Union(r, b.Rectangle); } } Program.logIt(string.Format("rect: {0}", r)); retR = r; Crop c_filter = new Crop(r); retB = c_filter.Apply(rotated); } return(new Tuple <Bitmap, double, Rectangle>(retB, retAngle, retR)); }
public double[] detectionGlyph(bool CalculTailleTerrain) { bool Trouve = false; double[] ratio = new double[2] { 0, 0 }; SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); BlobCounter blobCounter = new BlobCounter(); blobCounter.MinHeight = 23; blobCounter.MinWidth = 23; blobCounter.FilterBlobs = true; blobCounter.ObjectsOrder = ObjectsOrder.Size; // 4 - find all stand alone blobs blobCounter.ProcessImage(imgContour); Blob[] blobs = blobCounter.GetObjectsInformation(); // 5 - check each blob for (int i = 0, n = blobs.Length; i < n; i++) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List <IntPoint> corners = null; // Test de la forme selectionnée if (shapeChecker.IsQuadrilateral(edgePoints, out corners)) { // Détection des points de coutour List <IntPoint> leftEdgePoints, rightEdgePoints, topEdgePoints, bottomEdgePoints; Line Horizontale = Line.FromPoints(new IntPoint(0, 0), new IntPoint(10, 0)); blobCounter.GetBlobsLeftAndRightEdges(blobs[i], out leftEdgePoints, out rightEdgePoints); blobCounter.GetBlobsTopAndBottomEdges(blobs[i], out topEdgePoints, out bottomEdgePoints); // calculate average difference between pixel values from outside of the // shape and from inside float diff = CalculateAverageEdgesBrightnessDifference(leftEdgePoints, rightEdgePoints, imgNB); // check average difference, which tells how much outside is lighter than // inside on the average if (diff > 20) { // Transformation de l'image reçu en un carré pour la reconnaissance QuadrilateralTransformation quadrilateralTransformation = new QuadrilateralTransformation(corners, 60, 60); UnmanagedImage glyphImage = quadrilateralTransformation.Apply(imgNB); // Filtre de contraste OtsuThreshold otsuThresholdFilter = new OtsuThreshold(); otsuThresholdFilter.ApplyInPlace(glyphImage); imgContour = glyphImage; // Reconnaissance du Glyph Glyph Gl = new Glyph(glyphImage, GlyphSize); Gl.ReconnaissanceGlyph(corners, imgNB); // Si le Glyph est valide if (Gl.getIdentifiant() > 0) { if (AutAffichage[0]) { // Coloration des contours des zones détectées UnImgReel.SetPixels(leftEdgePoints, Color.Red); UnImgReel.SetPixels(rightEdgePoints, Color.Red); UnImgReel.SetPixels(topEdgePoints, Color.Red); UnImgReel.SetPixels(bottomEdgePoints, Color.Red); } // Détection du milieu Line line = Line.FromPoints(corners[0], corners[2]); Line line2 = Line.FromPoints(corners[1], corners[3]); IntPoint intersection = (IntPoint)line.GetIntersectionWith(line2); if (AutAffichage[1]) { dessinePoint(intersection, UnImgReel, 4, Color.Yellow); } // Calcul de la rotation Line ComparasionAngle = Line.FromPoints(corners[0], corners[1]); Double rotation = (int)ComparasionAngle.GetAngleBetweenLines(Horizontale); rotation += 90 * Gl.getNbRotation(); Gl.rotation = 360 - rotation; rotation *= (Math.PI / 180.0); // Calcul d'un point en bout de pince float Taille = corners[0].DistanceTo(corners[1]); float taille = (Taille / BibliotequeGlyph.Biblioteque[Gl.getPosition()].taille) * BibliotequeGlyph.Biblioteque[Gl.getPosition()].DistancePince; int x = -(int)(System.Math.Sin(rotation) * taille); int y = -(int)(System.Math.Cos(rotation) * taille); x += (int)intersection.X; y += (int)intersection.Y; Gl.Position = new int[2] { x, y }; if (AutAffichage[2]) { dessinePoint(new IntPoint(x, y), UnImgReel, 4, Color.Cyan); } imgContour = Gl.getImage(); addGlyph(Gl); if (CalculTailleTerrain == true && Trouve == false) { Trouve = true; int tailleglyph = BibliotequeGlyph.Biblioteque[Gl.getPosition()].taille; // Pythagore pour detection taille Rectangle a = blobs[i].Rectangle; double angle = -Gl.rotation + 180; List <IntPoint> coins = new List <IntPoint>(); coins.Add(new IntPoint(100, 100)); coins.Add(new IntPoint(100, 100 + tailleglyph)); coins.Add(new IntPoint(100 + tailleglyph, 100 + tailleglyph)); coins.Add(new IntPoint(100 + tailleglyph, 100)); IntPoint Centre = new IntPoint((coins[2].X + coins[0].X) / 2, (coins[2].Y + coins[0].Y) / 2); int radius = (int)(0.5 * Math.Sqrt(coins[0].DistanceTo(coins[1]) * coins[0].DistanceTo(coins[1]) + coins[1].DistanceTo(coins[2]) * coins[1].DistanceTo(coins[2]))); double alpha = Math.Atan2(coins[0].DistanceTo(coins[1]), coins[1].DistanceTo(coins[2])) * (180 / Math.PI); double ang = 0; for (i = 0; i < 4; i++) { IntPoint tmp = coins[i]; switch (i) { case 0: ang = alpha - 180 + angle; break; case 1: ang = +angle - alpha; break; case 2: ang = +angle + alpha; break; case 3: ang = -alpha + 180 + angle; break; } ang *= (Math.PI / 180); tmp.X = (int)(Centre.X + radius * Math.Cos(ang)); tmp.Y = (int)(Centre.Y + radius * Math.Sin(ang)); coins[i] = tmp; } Rectangle r = new Rectangle(min(coins[0].X, coins[1].X, coins[2].X, coins[3].X), min(coins[0].Y, coins[1].Y, coins[2].Y, coins[3].Y), max(coins[0].X, coins[1].X, coins[2].X, coins[3].X) - min(coins[0].X, coins[1].X, coins[2].X, coins[3].X), max(coins[0].Y, coins[1].Y, coins[2].Y, coins[3].Y) - min(coins[0].Y, coins[1].Y, coins[2].Y, coins[3].Y)); ratio[0] = ((double)r.Width / (double)a.Width) * 1.48; ratio[1] = ((double)r.Height / (double)a.Height) * 1.48; } } } } } if (Trouve == false || ratio[0] == 0 || ratio[0] == 1 || ratio[1] == 0 || ratio[1] == 1) { return(null); } ratio[0] *= 0.7; ratio[1] *= 0.7; return(ratio); }
// New frame received by the player private void videoSourcePlayer_NewFrame(object sender, ref Bitmap image) { BitmapData imageData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, image.PixelFormat); try { UnmanagedImage unmanagedImg = new UnmanagedImage(imageData); int x = (int)(unmanagedImg.Width / 3.19); // 443 int y = (int)(unmanagedImg.Height / 2.2); // 490 int w = (int)(unmanagedImg.Width / 2.7); // 553 int h = (int)(unmanagedImg.Height / 4); // 270 int s = (int)(unmanagedImg.Width / 10.2); // 141 // Crop the player scroll window. Speeds up the next couple operations Crop onePlayer = new Crop(new Rectangle(x, y, w, h)); UnmanagedImage img = onePlayer.Apply(unmanagedImg); // Use a quadrilateral transformation to make the scroller a big square. List <IntPoint> corners = new List <IntPoint>(); corners.Add(new IntPoint(s, 0)); corners.Add(new IntPoint(img.Width - s, 0));; corners.Add(new IntPoint(img.Width, img.Height)); corners.Add(new IntPoint(0, img.Height)); QuadrilateralTransformation filter = new QuadrilateralTransformation(corners, img.Width, img.Height); img = filter.Apply(img); // Crop the bottom half since it appears to have the best imagery Crop bottom = new Crop(new Rectangle(0, img.Height / 2, img.Width, img.Height / 2)); img = bottom.Apply(img); UnmanagedImage grayImg = UnmanagedImage.Create(img.Width, img.Height, PixelFormat.Format8bppIndexed); Grayscale.CommonAlgorithms.BT709.Apply(img, grayImg); OtsuThreshold threshold = new OtsuThreshold(); threshold.ApplyInPlace(grayImg); // Divide the square into 5 peices. One for each color. UnmanagedImage[] colorImg = new UnmanagedImage[5]; for (int i = 0; i < 5; i++) { int colorWidth = grayImg.Width / 5; int colorHeight = grayImg.Height; Crop colorCrop = new Crop(new Rectangle(colorWidth * i, 0, colorWidth, colorHeight)); colorImg[i] = colorCrop.Apply(grayImg); } greenCol.Image = colorImg[GREEN].ToManagedImage(); redCol.Image = colorImg[RED].ToManagedImage(); yellowCol.Image = colorImg[YELLOW].ToManagedImage(); blueCol.Image = colorImg[BLUE].ToManagedImage(); orangeCol.Image = colorImg[ORANGE].ToManagedImage(); VerticalIntensityStatistics[] hist = new VerticalIntensityStatistics[5]; for (int i = 0; i < 5; i++) { hist[i] = new VerticalIntensityStatistics(colorImg[i]); } findPucks(hist); greenHist.Values = hist[GREEN].Gray.Values; redHist.Values = hist[RED].Gray.Values; yellowHist.Values = hist[YELLOW].Gray.Values; blueHist.Values = hist[BLUE].Gray.Values; orangeHist.Values = hist[ORANGE].Gray.Values; pictureBox1.Image = img.ToManagedImage(); } finally { image.UnlockBits(imageData); } }
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 void scan_code() { List <IntPoint> TempCorners = new List <IntPoint>(); // 2 - Edge detection DifferenceEdgeDetector edgeDetector = new DifferenceEdgeDetector(); UnmanagedImage edgesImage = edgeDetector.Apply(grayImage); // 3 - Threshold edges Threshold thresholdFilter = new Threshold(40); thresholdFilter.ApplyInPlace(edgesImage); // create and configure blob counter BlobCounter blobCounter = new BlobCounter(); blobCounter.MinHeight = 32; blobCounter.MinWidth = 32; blobCounter.FilterBlobs = true; blobCounter.ObjectsOrder = ObjectsOrder.Size; // 4 - find all stand alone blobs blobCounter.ProcessImage(edgesImage); Blob[] blobs = blobCounter.GetObjectsInformation(); // 5 - check each blob for (int i = 0, n = blobs.Length; i < n; i++) { // ... List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List <IntPoint> corners = null; // does it look like a quadrilateral ? SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); if (shapeChecker.IsQuadrilateral(edgePoints, out corners)) { TempCorners.AddRange(corners); // ... // get edge points on the left and on the right side List <IntPoint> leftEdgePoints, rightEdgePoints; blobCounter.GetBlobsLeftAndRightEdges(blobs[i], out leftEdgePoints, out rightEdgePoints); // calculate average difference between pixel values fro+m outside of the // shape and from inside float diff = CalculateAverageEdgesBrightnessDifference( leftEdgePoints, rightEdgePoints, grayImage); // check average difference, which tells how much outside is lighter than // inside on the average if (diff > 20) { QuadrilateralTransformation quadrilateralTransformation = new QuadrilateralTransformation(corners, 100, 100); UnmanagedImage glyphImage = quadrilateralTransformation.Apply(grayImage); //// otsu thresholding hier fehler OtsuThreshold otsuThresholdFilter = new OtsuThreshold(); otsuThresholdFilter.ApplyInPlace(glyphImage); image = glyphImage; //// recognize raw glyph float confidence; //code geändert byte[,] LeftUpMarker = new byte[5, 5]; LeftUpMarker[0, 0] = 0; LeftUpMarker[0, 1] = 0; LeftUpMarker[0, 2] = 0; LeftUpMarker[0, 3] = 0; LeftUpMarker[0, 4] = 0; LeftUpMarker[1, 0] = 0; LeftUpMarker[1, 1] = 0; LeftUpMarker[1, 2] = 1; LeftUpMarker[1, 3] = 0; LeftUpMarker[1, 4] = 0; LeftUpMarker[2, 0] = 0; LeftUpMarker[2, 1] = 1; LeftUpMarker[2, 2] = 0; LeftUpMarker[2, 3] = 1; LeftUpMarker[2, 4] = 0; LeftUpMarker[3, 0] = 0; LeftUpMarker[3, 1] = 0; LeftUpMarker[3, 2] = 1; LeftUpMarker[3, 3] = 0; LeftUpMarker[3, 4] = 0; LeftUpMarker[4, 0] = 0; LeftUpMarker[4, 1] = 0; LeftUpMarker[4, 2] = 0; LeftUpMarker[4, 3] = 0; LeftUpMarker[4, 4] = 0; byte[,] RightUpMarker = new byte[5, 5]; RightUpMarker[0, 0] = 0; RightUpMarker[0, 1] = 0; RightUpMarker[0, 2] = 0; RightUpMarker[0, 3] = 0; RightUpMarker[0, 4] = 0; RightUpMarker[1, 0] = 0; RightUpMarker[1, 1] = 1; RightUpMarker[1, 2] = 0; RightUpMarker[1, 3] = 1; RightUpMarker[1, 4] = 0; RightUpMarker[2, 0] = 0; RightUpMarker[2, 1] = 0; RightUpMarker[2, 2] = 0; RightUpMarker[2, 3] = 0; RightUpMarker[2, 4] = 0; RightUpMarker[3, 0] = 0; RightUpMarker[3, 1] = 1; RightUpMarker[3, 2] = 0; RightUpMarker[3, 3] = 1; RightUpMarker[3, 4] = 0; RightUpMarker[4, 0] = 0; RightUpMarker[4, 1] = 0; RightUpMarker[4, 2] = 0; RightUpMarker[4, 3] = 0; RightUpMarker[4, 4] = 0; byte[,] LeftDownMarker = new byte[5, 5]; LeftDownMarker[0, 0] = 0; LeftDownMarker[0, 1] = 0; LeftDownMarker[0, 2] = 0; LeftDownMarker[0, 3] = 0; LeftDownMarker[0, 4] = 0; LeftDownMarker[1, 0] = 0; LeftDownMarker[1, 1] = 0; LeftDownMarker[1, 2] = 1; LeftDownMarker[1, 3] = 0; LeftDownMarker[1, 4] = 0; LeftDownMarker[2, 0] = 0; LeftDownMarker[2, 1] = 1; LeftDownMarker[2, 2] = 1; LeftDownMarker[2, 3] = 1; LeftDownMarker[2, 4] = 0; LeftDownMarker[3, 0] = 0; LeftDownMarker[3, 1] = 0; LeftDownMarker[3, 2] = 1; LeftDownMarker[3, 3] = 0; LeftDownMarker[3, 4] = 0; LeftDownMarker[4, 0] = 0; LeftDownMarker[4, 1] = 0; LeftDownMarker[4, 2] = 0; LeftDownMarker[4, 3] = 0; LeftDownMarker[4, 4] = 0; byte[,] ReightDownMarker = new byte[5, 5]; ReightDownMarker[0, 0] = 0; ReightDownMarker[0, 1] = 0; ReightDownMarker[0, 2] = 0; ReightDownMarker[0, 3] = 0; ReightDownMarker[0, 4] = 0; ReightDownMarker[1, 0] = 0; ReightDownMarker[1, 1] = 1; ReightDownMarker[1, 2] = 1; ReightDownMarker[1, 3] = 1; ReightDownMarker[1, 4] = 0; ReightDownMarker[2, 0] = 0; ReightDownMarker[2, 1] = 1; ReightDownMarker[2, 2] = 0; ReightDownMarker[2, 3] = 1; ReightDownMarker[2, 4] = 0; ReightDownMarker[3, 0] = 0; ReightDownMarker[3, 1] = 1; ReightDownMarker[3, 2] = 1; ReightDownMarker[3, 3] = 1; ReightDownMarker[3, 4] = 0; ReightDownMarker[4, 0] = 0; ReightDownMarker[4, 1] = 0; ReightDownMarker[4, 2] = 0; ReightDownMarker[4, 3] = 0; ReightDownMarker[4, 4] = 0; byte[,] glyphValues = Recognize(glyphImage, new System.Drawing.Rectangle(0, 0, glyphImage.Width, glyphImage.Height), out confidence); Boolean bool_LeftUpMarkerMarker = true; for (int l = 0; l < 5; l++) { for (int m = 0; m < 5; m++) { if (LeftUpMarker[l, m] != glyphValues[l, m]) { bool_LeftUpMarkerMarker = false; break; } } } if (bool_LeftUpMarkerMarker) { Debug.Log("Marker erkannt"); } Boolean bool_RightUpMarker = true; for (int l = 0; l < 5; l++) { for (int m = 0; m < 5; m++) { if (RightUpMarker[l, m] != glyphValues[l, m]) { bool_RightUpMarker = false; break; } } } if (bool_RightUpMarker) { Debug.Log("Marker erkannt"); } Boolean bool_LeftDownMarker = true; for (int l = 0; l < 5; l++) { for (int m = 0; m < 5; m++) { if (LeftDownMarker[l, m] != glyphValues[l, m]) { bool_LeftDownMarker = false; break; } } } if (bool_LeftDownMarker) { Debug.Log("Marker erkannt"); } Boolean bool_ReightDownMarker = true; for (int l = 0; l < 5; l++) { for (int m = 0; m < 5; m++) { if (ReightDownMarker[l, m] != glyphValues[l, m]) { bool_ReightDownMarker = false; break; } } } if (bool_ReightDownMarker) { Debug.Log("Marker erkannt"); } } } } if (TempCorners.Count > 0) { Corners = TempCorners; } }
private void PatternRecognition(Bitmap bitmap) { // Prvi korak - grayscalling originalne slike Bitmap frame = grayscaleFilter.Apply(bitmap); BitmapData frameData = frame.LockBits(new Rectangle(0, 0, frame.Width, frame.Height), ImageLockMode.ReadWrite, frame.PixelFormat); // Drugi korak - detekcija ivica pomocu Sobel filtra sobelFilter.ApplyInPlace(frameData); // Treći korak - konvertuj sliku u crno-bijelu pri čemu je threshold = 100 odnoso od 0 do 155 je crna boja, a od 156 do 255 je bijela boja thresholdFilter.ApplyInPlace(frameData); // Četvrti korak - dilitacija / pojacavanje bijele boje jer dilitationFilter.ApplyInPlace(frameData); // Peti korak - kreiranje binarne slike frame = frame.Clone(new Rectangle(0, 0, frame.Width, frame.Height), PixelFormat.Format8bppIndexed); // Šesti korak - pronalazak potencijalnih oblika na slici blobCounter.ProcessImage(frameData); Blob[] blobs = blobCounter.GetObjectsInformation(); // za crtanje po originalnoj slici Graphics g = Graphics.FromImage(bitmap); // Sedmi korak - provjeri svaki oblik foreach (Blob blob in blobs) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob); List<IntPoint> hullPoints = hullFinder.FindHull(edgePoints); List<IntPoint> corners = null; // da li je četverougao? if (shapeChecker.IsQuadrilateral(hullPoints, out corners)) // da li je kvadrat? if (shapeChecker.CheckPolygonSubType(corners) == PolygonSubType.Square) { if (!detected) { // Osmi korak - odrđivanje centra gravitacije i gornjeg lijevog tjemena FindNewCorners(corners); // Deveti korak - ekstrakcija prepoznatog kvadrata sa originalne slike u novu sliku dimenzija 100x100 SimpleQuadrilateralTransformation quadrilateralTransformation = new SimpleQuadrilateralTransformation(corners, 100, 100); Bitmap recognizedSquare = quadrilateralTransformation.Apply(bitmap); recognizedSquare = recognizedSquare.Clone(new Rectangle(0, 0, recognizedSquare.Width, recognizedSquare.Height), PixelFormat.Format8bppIndexed); // Deseti korak - od nove slike ponovo napravi crno-bijelu otsuThresholdFilter.ApplyInPlace(recognizedSquare); // Jedanaesti korak - invertuj boje invertFilter.ApplyInPlace(recognizedSquare); //Dvanaesti korak - prepoznaj oblik (formiraj matricu) float confidence; // vjerovatnoća da je prepoznat pravi oblik (odnos borja crnih i bijelih piksela u ćeliji byte[,] pattern = binaryGlyphRecognizer.Recognize(recognizedSquare, new Rectangle(0, 0, recognizedSquare.Width, recognizedSquare.Height), out confidence); recognizedSquare.Dispose(); if (confidence >= 0.6) { oldPatterns.Add(pattern); Boolean canDraw = CheckPrevious(); if (canDraw) { // Trinaesti korak - iscrtaj matricu DrawPattern(pattern); detected = true; // pravim delay od 3s nakon što prepozna pattern new Task(() => { Thread.Sleep(3*1000); detected = false; }).Start(); // Komunikacija sa warehouse uređajem. //new Thread(new RS232Communication(shape).Run).Start(); } } } // iscrtaj ivice oko prepoznatog kvadrata g.DrawPolygon(pen, ToPointsArray(hullPoints)); } } g.Dispose(); frame.UnlockBits(frameData); frame.Dispose(); }