private void ApplyFilters(ref Bitmap bitmap) { if (IsLuminance.IsChecked != null && IsLuminance.IsChecked.Value) { bitmap = _grayscale.Apply(bitmap); } if (IsRemovedNoises.IsChecked != null && IsRemovedNoises.IsChecked.Value) { _noiseRemoval.ApplyInPlace(bitmap); } if (IsResized.IsChecked == null || !IsResized.IsChecked.Value) { return; } try { _resizer.NewWidth = int.Parse(NewWidthTextBox.Text); } catch { _resizer.NewWidth = DefaultResizeWidth; } _resizer.NewHeight = (int)(Convert.ToSingle(bitmap.Height) / bitmap.Width * _resizer.NewWidth); bitmap = _resizer.Apply(bitmap); }
private void NoiseReduction(ref Bitmap frame) { frame = Grayscale.CommonAlgorithms.RMY.Apply(frame); // Make gray switch (NoiseReduceValue) { case 1: BilateralSmoothing Bil_filter = new BilateralSmoothing(); Bil_filter.KernelSize = 7; Bil_filter.SpatialFactor = 10; Bil_filter.ColorFactor = 30; Bil_filter.ColorPower = 0.5; Bil_filter.ApplyInPlace(frame); break; case 2: Median M_filter = new Median(); M_filter.ApplyInPlace(frame); break; case 3: Mean Meanfilter = new Mean(); // apply the MirrFilter Meanfilter.ApplyInPlace(frame); break; default: Median Median_filter = new Median(); Median_filter.ApplyInPlace(frame); break; } GrayscaleToRGB RGBfilter = new GrayscaleToRGB(); // back to color format frame = RGBfilter.Apply(frame); }
public void VectorsRotate120(Bitmap image, List <double[]> vector360Contur, List <double[]> vector360Hull) { int i; ProcessingImage pi = new ProcessingImage(); List <System.Drawing.Point> localPt; for (i = 180; i < 360; i++) { QuickHull qh = new QuickHull(); Contur cont1 = new Contur(); //медианный фильтр для шумов границ размытых объектов Median filter = new Median(); filter.ApplyInPlace(image); //поворот на 1 градус Bitmap image1 = pi.RotateImg(image, i); image1 = pi.ProcImg(image1); localPt = pi.GetPoints(image1); //выделение выпуклой оболочки List <System.Drawing.Point> ConvexHullLocal = qh.quickHull(localPt); ConvexHullLocal = qh.DeleteAnglePoints(ConvexHullLocal); //и контура List <System.Drawing.Point> ConturLocal = cont1.kontur(image1); ConturLocal = cont1.DeleteAnglePoints(ConturLocal); Primary marks = new Primary(image1, ConturLocal, ConvexHullLocal); vector360Contur.Add(marks.Contour()); vector360Hull.Add(marks.Convex()); } }
/// <summary> /// Processes the specified SRC image. /// </summary> /// <param name="srcImage">The SRC image.</param> /// <remarks></remarks> public void Process(Bitmap srcImage) { resize.NewWidth = srcImage.Width / Scale; resize.NewHeight = srcImage.Height / Scale; FilteredBoard = resize.Apply(srcImage); ImageFilters.HSLFilter(FilteredBoard, targetHue, targetSat, targetBri, hueTol, satTol, briTol); median.ApplyInPlace(FilteredBoard); GaussianBlur blr = new GaussianBlur(1, 2); blr.ApplyInPlace(FilteredBoard); List <IntPoint> cors = new List <IntPoint>(); try { cors = quadFinder.ProcessImage(FilteredBoard); } catch { } if (ValidCorners(cors)) { EnlargeCorners(cors); SortCorners(cors); UpdateCorners(cors); } }
/// <summary> /// Filter: Median Blur /// Subtract the medium blur (block size ~letter size) from the image /// </summary> public void SubtractMedianBlur() { var filter = new Median(); // create filter filter.ApplyInPlace(Image); // apply the filter Save("medianBlurred"); }
/// <summary> /// Aforge median filtration /// </summary> /// <param name="image"></param> /// <param name="core">Median core size</param> public static Image Median(this Image image, int core) { var bitmapImage = new Bitmap(image); Median medianFilter = new Median(core); medianFilter.ApplyInPlace(bitmapImage); return(bitmapImage); }
public static Bitmap MedianFilter(Bitmap sourceImage, int squareSize) { var filter = new Median(); var tmp = new Bitmap(sourceImage); filter.ApplyInPlace(tmp); return(tmp); }
/* * 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 медианнаяToolStripMenuItem_Click(object sender, EventArgs e) { Median filter = new Median(); Bitmap srcBitmap = new Bitmap(sourcePictureBox.Image); filter.ApplyInPlace(srcBitmap); chart1.Series[0].Points.DataBindY(calculateChart(srcBitmap)); resultPictureBox.Image = srcBitmap; }
public static Bitmap Median(Bitmap bmp) { // create filter Median filter = new Median(); // apply the filter filter.ApplyInPlace(bmp); return(bmp); }
private void MedianFilterButton_Click(object sender, EventArgs e) { Bitmap bmp = (Bitmap)pictureBox1.Image; Median filter = new Median(); filter.ApplyInPlace(bmp); SaveAction(bmp); pictureBox1.Refresh(); Charts(); }
/// <summary> /// This method improve image resolution to 300X300. /// </summary> /// <param name="image"></param> /// <returns></returns> private Bitmap ImproveResolution(Bitmap image) { //improve resolution Bitmap b = new Bitmap(image); b.SetResolution(300, 300); Median median = new Median(); median.ApplyInPlace(b); //b.Save(@"C:\Users\Maor\Desktop\mode\ImproveResolution.jpeg"); return(b); }
private Bitmap GetEdgedImage(WriteableBitmap writeableBitmap) { var edgeFilter = new CannyEdgeDetector(255, 0); var smoothFilter = new Median(); var grayFilter = new Grayscale(0.2125, 0.7154, 0.0721); var bitmap = (Bitmap)writeableBitmap; bitmap = grayFilter.Apply(bitmap); smoothFilter.ApplyInPlace(bitmap); edgeFilter.ApplyInPlace(bitmap); return(bitmap); }
/// <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> /// Processes the specified SRC image. /// </summary> /// <param name="srcImage">The SRC image.</param> /// <remarks></remarks> public void Process(Bitmap srcImage) { if (srcImage == null || srcImage.Width < 10 || srcImage.Height < 10) { return; } resize.NewWidth = srcImage.Width / Scale; resize.NewHeight = srcImage.Height / Scale; FilteredBoard = resize.Apply(srcImage); if (Enhance) { ImageFilters.FlattenLighting(FilteredBoard); } ImageFilters.HSLFilter(FilteredBoard, targetHue, targetSat, targetBri, hueTol, satTol, briTol); median.ApplyInPlace(FilteredBoard); GaussianBlur blr = new GaussianBlur(2, 2); blr.ApplyInPlace(FilteredBoard); TileBlobs.Clear(); try { BlobCounter.ProcessImage(FilteredBoard); Blob[] blobs = BlobCounter.GetObjectsInformation(); TileBlobs.Clear(); foreach (Blob b in blobs) { if (b.Area < 10) { continue; } TileBlobs.Add(b); } } catch { } }
/// <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); }
public void addetalons(Bitmap etalon) { ProcessingImage pi = new ProcessingImage(); List <double[]> vector360Contur = new List <double[]>(); List <double[]> vector360Hull = new List <double[]>(); List <double[]> vector180360Contur = new List <double[]>(); List <double[]> vector180360Hull = new List <double[]>(); Bitmap ImageForThread1 = etalon.Clone( new Rectangle(0, 0, etalon.Width, etalon.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb); Bitmap Image24 = etalon.Clone( new Rectangle(0, 0, etalon.Width, etalon.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb); List <Point> localPt = new List <System.Drawing.Point>(); Thread t1 = new Thread(() => VectorsRotate120(ImageForThread1, vector180360Contur, vector180360Hull)); t1.Start(); //рассчет вектора признаков для каждого поворота for (int i = 0; i < 180; i++) { QuickHull qh = new QuickHull(); Contur cont1 = new Contur(); //медианный фильтр для шумов границ размытых объектов Median filter = new Median(); filter.ApplyInPlace(Image24); //поворот на 1 градус Bitmap image1 = pi.RotateImg(Image24, i); image1 = pi.ProcImg(image1); localPt = pi.GetPoints(image1); //выделение выпуклой оболочки List <System.Drawing.Point> ConvexHullLocal = qh.quickHull(localPt); ConvexHullLocal = qh.DeleteAnglePoints(ConvexHullLocal); //и контура List <System.Drawing.Point> ConturLocal = cont1.kontur(image1); ConturLocal = cont1.DeleteAnglePoints(ConturLocal); Primary marks = new Primary(image1, ConturLocal, ConvexHullLocal); vector360Contur.Add(marks.Contour()); vector360Hull.Add(marks.Convex()); progressBar1.Value = i + 1; cont1 = null; } progressBar1.Value = 0; for (int i = 0; i < vector180360Contur.Count; i++) { vector360Contur.Add(vector180360Contur[i]); vector360Hull.Add(vector180360Hull[i]); } //запись в файл по 1 объекту //WriteToFileBegin(vector360Contur, "Contours.txt"); //WriteToFileBegin(vector360Hull, "Hulls.txt"); //vector360Contur = ReadFromFile("Contours.txt", 18); //vector360Hull = ReadFromFile("Hulls.txt", 28); GetConturHullCentroid(vector360Contur, vector360Hull); GetConturHullMedoid(vector360Contur, vector360Hull, Contourvec, Hullvec); }
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; }
void cam_NewFrame(object sender, NewFrameEventArgs eventArgs) { Bitmap realimage = (Bitmap)eventArgs.Frame.Clone(); Bitmap rimage = (Bitmap)eventArgs.Frame.Clone(); Bitmap bimage = (Bitmap)eventArgs.Frame.Clone(); //Red Object detection GrayscaleBT709 grayscale = new GrayscaleBT709(); Subtract sfilter = new Subtract(grayscale.Apply(rimage)); ExtractChannel rchannel = new ExtractChannel(RGB.R); ExtractChannel bchannel = new ExtractChannel(RGB.B); rimage = rchannel.Apply(rimage); bimage = bchannel.Apply(bimage); sfilter.ApplyInPlace(rimage); sfilter.ApplyInPlace(bimage); Median mfilter = new Median(5); mfilter.ApplyInPlace(rimage); mfilter.ApplyInPlace(bimage); Threshold thresh = new Threshold(50); thresh.ApplyInPlace(rimage); thresh.ApplyInPlace(bimage); BlobCounter rblob = new BlobCounter(); rblob.ObjectsOrder = ObjectsOrder.Area; rblob.ProcessImage(rimage); BlobCounter bblob = new BlobCounter(); bblob.ObjectsOrder = ObjectsOrder.Area; bblob.ProcessImage(bimage); Rectangle[] rrect = rblob.GetObjectsRectangles(); Rectangle[] brect = bblob.GetObjectsRectangles(); p = new int[rrect.Length + brect.Length]; arr = 0; if (rrect.Length > 0) { for (int i = 0; i < rrect.Length; i++) { if (rrect[i].Height > 20 && rrect[i].Width > 20)//Object Min height width { Graphics g = Graphics.FromImage(realimage); g.DrawRectangle(new Pen(Color.Red), rrect[i]); objheight = rrect[i].Height; objwidth = rrect[i].Width; objx = rrect[i].X + (objwidth / 2); objy = rrect[i].Y + (objheight / 2); p[i] = getpartition(); arr++; g.DrawEllipse(new Pen(Color.Yellow), objx, objy, 5, 5); g.DrawString("Red Object", new Font("Arial", 10), new SolidBrush(Color.AntiqueWhite), objx, objy - 15); g.DrawString("X:" + objx + " Y:" + objy, new Font("Arial", 10), new SolidBrush(Color.LimeGreen), objx, objy); g.DrawString("H:" + objheight + " W:" + objwidth, new Font("Arial", 10), new SolidBrush(Color.LightCyan), objx, objy + 15); g.DrawString("P:" + p[i], new Font("Arial", 10), new SolidBrush(Color.LightSkyBlue), objx, objy + 25); } } obj = largest(); if (obj == 0) { obj = prevobj; } prevobj = obj; } if (brect.Length > 0) { for (int i = 0; i < brect.Length; i++) { if (brect[i].Height > 20 && brect[i].Width > 20)//Object Min height width { Graphics g = Graphics.FromImage(realimage); g.DrawRectangle(new Pen(Color.Red), brect[i]); objheight = brect[i].Height; objwidth = brect[i].Width; objx = brect[i].X + (objwidth / 2); objy = brect[i].Y + (objheight / 2); p[i + arr] = getpartition(); g.DrawEllipse(new Pen(Color.Yellow), objx, objy, 5, 5); g.DrawString("Blue Object", new Font("Arial", 10), new SolidBrush(Color.AntiqueWhite), objx, objy - 15); g.DrawString("X:" + objx + " Y:" + objy, new Font("Arial", 10), new SolidBrush(Color.LimeGreen), objx, objy); g.DrawString("H:" + objheight + " W:" + objwidth, new Font("Arial", 10), new SolidBrush(Color.LightCyan), objx, objy + 15); g.DrawString("P:" + p[i + arr], new Font("Arial", 10), new SolidBrush(Color.LightSkyBlue), objx, objy + 25); } } obj = largest(); if (obj == 0) { obj = prevobj; } prevobj = obj; } displayBox.Image = realimage; }
}//FrameGrapper #region 눈 검출 방법 : 눈 떳을 때, 눈 감았을 때의 threshold 값의 변화에 따라 눈 깜빡임 인식 public void thresholdEffect(int catchThreshold) { // Black 픽셀이 잡힌 경우 재귀 함수 빠져나가기 if (Form1.catchBlackPixel.Equals(true)) { return; } // 눈 깜빡임을 검출할 눈 영역 Median Blur 필터 적용 Thimage = (Bitmap)imageBox1.Image.Bitmap; Median filter = new Median(); filter.ApplyInPlace(Thimage); // 눈 깜빡임을 검출할 눈 영역 Threshold 필터 적용 - (catchThreshold 값으로) IFilter threshold = new Threshold(catchThreshold); Thimage = Grayscale.CommonAlgorithms.RMY.Apply(Thimage); Thimage = threshold.Apply(Thimage); // 눈 검출할 영역의 가로 길이가 50mm가 넘는다면 40x30 size로 변환 // (카메라 가까이에 얼굴이 있으면 눈 영역도 커지기 때문에 계산량 일정하게 만들기) if (Thimage.Width > 50) { Thimage = ResizeImage(Thimage, new Size(40, 30)); } // 필터링 된 이미지 blur 처리 후 한 픽셀이라도 검은 Pixel이 존재한 다면 // catchBlackPixel = true로 변경. for (int x = blurAmount + 5; x <= Thimage.Width - blurAmount; x++) { for (int y = blurAmount + 5; y <= Thimage.Height - blurAmount; y++) { try { Color prevX = Thimage.GetPixel(x - blurAmount, y); Color nextX = Thimage.GetPixel(x + blurAmount, y); Color prevY = Thimage.GetPixel(x, y - blurAmount); Color nextY = Thimage.GetPixel(x, y + blurAmount); int avgR = (int)((prevX.R + nextX.R + prevY.R + nextY.R) / 4); if (avgR < 150) { Form1.catchBlackPixel = true; break; } } catch (Exception) { } } } // 검은 Pixel 존재 할 경우 if (Form1.catchBlackPixel.Equals(true)) { // Tresholdvalue = Label에 투영시킬 변수 TV = catchThreshold; // 이 동작을 3번 ㅇ if (averageThresholdValue.Count > 3) { averageThresholdValue.Add((averageThresholdValue[1] + averageThresholdValue[2]) / 2); Double doubleValue = averageThresholdValue.Average() - averageThresholdValue.Average() % 10; int a = (int)doubleValue; thresholdValue = a; } else { averageThresholdValue.Add(catchThreshold); } // catchThreshold와 평균 Threshold값을 비교하여 눈 깜빡임 detect // 만약 직전에도 이 값일 경우엔 Pass if (catchThreshold > averageThresholdValue.Average() + 8 && catchThreshold < averageThresholdValue.Average() + 25) { if (!catchBlink) { blinkNum++; catchBlink = true; label3.Text = blinkNum.ToString(); } else { catchBlink = true; } } else { catchBlink = false; } //label2.Text = ((double)prevThresholdValue / (double)catchThreshold).ToString(); return; } // 만약 해당 이미지에 검은 픽셀이 존재하지 않을경우 // catchThreshold값을 1 증가시켜 재귀 함수를 통해 다시 계산시키기 else { if (catchThreshold < 120) { catchThreshold += 1; prevThresholdValue = catchThreshold; thresholdEffect(catchThreshold); } } }
public int SetImage(Bitmap image) { leftEdges.Clear(); rightEdges.Clear(); topEdges.Clear(); bottomEdges.Clear(); hulls.Clear(); quadrilaterals.Clear(); selectedBlobID = 0; Bitmap imageclone = AForge.Imaging.Image.Clone(image, image.PixelFormat); // create filter Median filterMedian = new Median(); // apply the filter // create filter Threshold filterThreshold = new Threshold(250); // configure filter // create filter BlobsFiltering filterBlobsFiltering = new BlobsFiltering(); filterBlobsFiltering.CoupledSizeFiltering = false; filterBlobsFiltering.MinWidth = 6; //7 filterBlobsFiltering.MinHeight = 6; //7 filterBlobsFiltering.MaxWidth = 8; //8 filterBlobsFiltering.MaxHeight = 8; //8 // apply the filter filterThreshold.ApplyInPlace(imageclone); filterBlobsFiltering.ApplyInPlace(imageclone); filterMedian.ApplyInPlace(imageclone); //this.image = AForge.Imaging.Image.Clone( image, PixelFormat.Format16bppGrayScale ); //imageclone = AForge.Imaging.Image.Clone(image); imageWidth = imageclone.Width; imageHeight = imageclone.Height; blobCounter.ProcessImage(imageclone); blobs = blobCounter.GetObjectsInformation(); center = new List <AForge.Point>(); GrahamConvexHull grahamScan = new GrahamConvexHull(); foreach (Blob blob in blobs) { List <IntPoint> leftEdge = new List <IntPoint>(); List <IntPoint> rightEdge = new List <IntPoint>(); List <IntPoint> topEdge = new List <IntPoint>(); List <IntPoint> bottomEdge = new List <IntPoint>(); // collect edge points blobCounter.GetBlobsLeftAndRightEdges(blob, out leftEdge, out rightEdge); blobCounter.GetBlobsTopAndBottomEdges(blob, out topEdge, out bottomEdge); AForge.Point centering = blob.CenterOfGravity; leftEdges.Add(blob.ID, leftEdge); rightEdges.Add(blob.ID, rightEdge); topEdges.Add(blob.ID, topEdge); bottomEdges.Add(blob.ID, bottomEdge); // find convex hull List <IntPoint> edgePoints = new List <IntPoint>(); edgePoints.AddRange(leftEdge); edgePoints.AddRange(rightEdge); List <IntPoint> hull = grahamScan.FindHull(edgePoints); hulls.Add(blob.ID, hull); List <IntPoint> quadrilateral = null; // List array center of gravity center.Add(centering); // find quadrilateral // if (hull.Count < 4) { quadrilateral = new List <IntPoint>(hull); } else { quadrilateral = PointsCloud.FindQuadrilateralCorners(hull); } quadrilaterals.Add(blob.ID, quadrilateral); // shift all points for vizualization IntPoint shift = new IntPoint(1, 1); PointsCloud.Shift(leftEdge, shift); PointsCloud.Shift(rightEdge, shift); PointsCloud.Shift(topEdge, shift); PointsCloud.Shift(bottomEdge, shift); PointsCloud.Shift(hull, shift); PointsCloud.Shift(quadrilateral, shift); } double xhair = imageWidth / 2; double yhair = imageHeight / 2; if (image.PixelFormat != PixelFormat.Format24bppRgb) { //filterBlobX(516.0, 670.0); //filterBlobY(360.0, 520.0); filterBlobX(516.0, 1117.0); filterBlobY(357.0, 460.0); refPointList = new List <AForge.Point>(); //findRef(388.0, 0.5); findRef(20.0, 1.5);// findPick(refPoint.X, refPoint.Y); } //UpdatePosition(); //Invalidate(); //if (!Directory.Exists(path)) //{ // System.IO.Directory.CreateDirectory(path); //} ////file = path + DateTime.Now.ToString(datePatt); file = path + "visimg.bmp"; imageclone.Save(file); if (blobs.Length > 0) { return(blobs.Length); } else { return(0); } }
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); } }
// Slow version (eventually pictures could be resized for more performance) private void FindPersonPosition(UnmanagedImage frameImage) { var stopwatch = Stopwatch.StartNew(); Difference diffFilter = new Difference(_baseImage); UnmanagedImage diffImg = diffFilter.Apply(frameImage); //diffImg.ToManagedImage().Save(@"c:\temp\recognition\diff.png"); // TODO ev. ColorFilter Grayscale grayFilter = new GrayscaleBT709(); diffImg = grayFilter.Apply(diffImg); //diffImg.ToManagedImage().Save(@"c:\temp\recognition\diff-gray.png"); Threshold thresholdFilter = new Threshold(30); thresholdFilter.ApplyInPlace(diffImg); //diffImg.ToManagedImage().Save(@"c:\temp\recognition\diff-gray-thres.png"); Median medianFilter = new Median(3); medianFilter.ApplyInPlace(diffImg); //diffImg.ToManagedImage().Save(@"c:\temp\recognition\diff-gray-thres-med.png"); // Find Person Borders (TODO ev. Performance Boost, wenn CollectActivePixels vermieden wird) // per Iteration durch Pixeldaten koennte ev. die groesste und die kleinste x-Koordinate schneller // gefunden werden.. List <AForge.IntPoint> whites = diffImg.CollectActivePixels(BOTTOM_BASE_STRIPE); int minX = whites.Min(obj => obj.X); int maxX = whites.Max(obj => obj.X); // Schneller als MS Algorithmus fuer Min und Max // (auch wenn es assymptotisch gleich schnell sein muesste) //int minX = int.MaxValue; //int maxX = int.MinValue; //foreach(AForge.IntPoint whitePixel in whites) //{ // //if (whitePixel.X < minX) // //{ // // minX = whitePixel.X; // //} // if (whitePixel.X > maxX) // { // maxX = whitePixel.X; // } //} var elapsedStage1 = stopwatch.ElapsedMilliseconds; Debug.WriteLine("Person is this fat: {0}, {1}", minX, maxX); // Find Arm whites = diffImg.CollectActivePixels(new Rectangle(maxX, 0, 640 - maxX, 480 - BOTTOM_BASE_STRIPE.Height)); maxX = whites.Max(obj => obj.X); var armPoint = whites.First(obj => obj.X == maxX); Debug.WriteLine("Persons arm is here: {0}, {1}", armPoint.X, armPoint.Y); Bitmap b = frameImage.ToManagedImage(); using (Graphics g = Graphics.FromImage(b)) { g.DrawEllipse(Pens.Red, armPoint.X, armPoint.Y, 5, 5); b.Save(@"c:\temp\recognition\gach.png"); } Debug.WriteLine("Time: {0}", elapsedStage1); stopwatch.Stop(); }
public Bitmap[] processImage(string filePath, int thresholdValueFromTrackBar) { OtsuThreshold otsuFilter = new OtsuThreshold(); //Фильтр, котор Median medianFilter = new Median(); Grayscale grayFilter = new Grayscale(0.2125, 0.7154, 0.0721); Bitmap srcBitmap = new Bitmap(filePath); Bitmap resultImage = grayFilter.Apply(srcBitmap); int threshold = otsuFilter.CalculateThreshold(resultImage, new Rectangle(0, 0, resultImage.Width, resultImage.Height)) + thresholdValueFromTrackBar; int delta = 10; Threshold filter = new Threshold(threshold - delta); filter.ApplyInPlace(resultImage); medianFilter.ApplyInPlace(resultImage); objectsMap = new int[resultImage.Width, resultImage.Height]; int objectCounter = 1; //Счетчик объектов int pointsCount = 0; //Счетчик пикселей, из которых состоит объект List <Vector2D_Int> objectPoints = new List <Vector2D_Int>(); //Список для рекурсивного обхода точек по объекту Dictionary <int, int> objectsSpaces = new Dictionary <int, int>(); int max = 0; //Количество точек в самом больщом объекте //В цикле проходим по всем пикселям изображения for (int x = 0; x < resultImage.Width; x++) { for (int y = 0; y < resultImage.Height; y++) { //Если встречаем черную точку и данную точку мы еще не посещали, //то начинаем поиск соседних черных точек, чтобы обойти весь объект if ((resultImage.GetPixel(x, y).R == 0) && (objectsMap[x, y] == 0)) { pointsCount = 1; objectsMap[x, y] = objectCounter; //Заполняем массив, в котором указаны какие точки относятся к какому объекту objectPoints.Add(new Vector2D_Int(x, y)); //Добавляем текущую точку в список для проверки соседних точек while (objectPoints.Count > 0) //Если в списке точек на проверку имеются записи (при первом входе там будет минимум одна запись с текущей точкой { Vector2D_Int currentPoint = objectPoints[0]; //Проходим по 8 соседним точкам for (int dy = -1; dy < 2; dy++) { for (int dx = -1; dx < 2; dx++) { //Проверка на выход текущей точки за пределы изображения int currentPosX = Math.Min(Math.Max(currentPoint.X + dx, 0), resultImage.Width - 1); int currentPosY = Math.Min(Math.Max(currentPoint.Y + dy, 0), resultImage.Height - 1); byte tempR = resultImage.GetPixel(currentPosX, currentPosY).R; //Если проверяемая точка черная и мы её не посещали if ((tempR == 0) && (objectsMap[currentPosX, currentPosY] == 0) && ((dx != 0) || (dy != 0))) { //То в массиве объектов указываем отношение данной точки к объекту objectsMap[currentPosX, currentPosY] = objectCounter; //Добавляем точку в список для последующей проверки objectPoints.Add(new Vector2D_Int(currentPosX, currentPosY)); //Увеличиваем счетчик точек в объкте pointsCount++; } } } //После проверки текущей точки удаляем её из списка, чтобы на первое место встала следующая точка objectPoints.RemoveAt(0); } //Сохраняем идентификатор и размер объекта objectsSpaces.Add(objectCounter, pointsCount); //Инкрементируем счетик объектов objectCounter++; max = Math.Max(max, pointsCount); pointsCount = 0; } } } pointsCount = 0; List <int> listObjectsId = new List <int>(); //Список идентификаторов объектов, которые удовлетворяют условию порога boundingBox[] boundingBoxesObject = new boundingBox[objectsSpaces.Count]; for (int i = 0; i < boundingBoxesObject.Length; i++) { boundingBoxesObject[i] = new boundingBox(resultImage.Width, resultImage.Height); } for (int x = 0; x < resultImage.Width; x++) { for (int y = 0; y < resultImage.Height; y++) { if (objectsMap[x, y] != 0) { int idObject = objectsMap[x, y] - 1; boundingBoxesObject[idObject].maxX = Math.Max(x, boundingBoxesObject[idObject].maxX); boundingBoxesObject[idObject].minX = Math.Min(x, boundingBoxesObject[idObject].minX); boundingBoxesObject[idObject].maxY = Math.Max(y, boundingBoxesObject[idObject].maxY); boundingBoxesObject[idObject].minY = Math.Min(y, boundingBoxesObject[idObject].minY); } } } max = 0; for (int i = 0; i < boundingBoxesObject.Length; i++) { int square = (boundingBoxesObject[i].maxX - boundingBoxesObject[i].minX) * (boundingBoxesObject[i].maxY - boundingBoxesObject[i].minY); double squareTreshold = Convert.ToDouble(objectsSpaces[i + 1]) / Convert.ToDouble(square); if (squareTreshold > 0.45) { max = Math.Max(max, objectsSpaces[i + 1]); listObjectsId.Add(i + 1); } } int sizeThreshold = Convert.ToInt32((max / 2) / Math.Sqrt(3)); //Порог для отсеивания маленьких объектов List <int> resultListObjectsId = new List <int>(); foreach (int i in listObjectsId) { if (objectsSpaces[i] > sizeThreshold) { resultListObjectsId.Add(i); } } Bitmap result = new Bitmap(resultImage.Width, resultImage.Height); //Составление изображение на основе списка тех объектов, которые прошли порог for (int x = 0; x < resultImage.Width; x++) { for (int y = 0; y < resultImage.Height; y++) { if (resultListObjectsId.Contains(objectsMap[x, y])) { result.SetPixel(x, y, Color.Black); } else { objectsMap[x, y] = 0; result.SetPixel(x, y, Color.White); } } } boundingBox targetBox = boundingBoxesObject[resultListObjectsId[0] - 1]; int squareObject = (targetBox.maxX - targetBox.minX) * (targetBox.maxY - targetBox.minY); int perimetrObject = ((targetBox.maxX - targetBox.minX) + (targetBox.maxY - targetBox.minY)) * 2; int diagonalObject = Convert.ToInt32(Math.Pow(Math.Pow(Convert.ToDouble(targetBox.maxX - targetBox.minX), 2) + Math.Pow(Convert.ToDouble(targetBox.maxY - targetBox.minY), 2), 0.5)); string messageText = "Площадь объекта: " + squareObject + "\n" + "Периметр объекта: " + perimetrObject + "\n" + "Диагональ объекта: " + diagonalObject; //MessageBox.Show(messageText, "Данные об объекте", MessageBoxButtons.OK, MessageBoxIcon.Information); Graphics gResult = Graphics.FromImage(result); Graphics gSource = Graphics.FromImage(srcBitmap); Pen pen = new Pen(Color.DarkBlue, 3); gResult.DrawRectangle(pen, targetBox.getRectangle()); string diagonalInfo = "d1 = " + diagonalObject.ToString() + "pxl; d2 = " + diagonalObject.ToString() + "pxl"; Font drawFont = new Font("Arial", 16); SolidBrush drawBrush = new SolidBrush(Color.DarkBlue); gResult.DrawString(diagonalInfo, drawFont, drawBrush, targetBox.minX, targetBox.minY - 25); gSource.DrawString(diagonalInfo, drawFont, drawBrush, targetBox.minX, targetBox.minY - 25); gSource.DrawRectangle(pen, targetBox.getRectangle()); gResult.Save(); gSource.Save(); Bitmap[] resultedImages = new Bitmap[2]; resultedImages[1] = result; resultedImages[0] = srcBitmap; return(resultedImages); }