public AlgorithmResult DetectContours( string filename, ContourRetrType rtype, ContourMethodType mtype, double threshold1, double threshold2, int apertureSize) { AlgorithmResult result = new AlgorithmResult(); Image <Bgr, byte> image = ImageHelper.GetImage(filename); var cannyImage = new Image <Gray, byte>(image.Width, image.Height); var resultImage = new Image <Bgr, byte>(filename); var contours = new VectorOfVectorOfPoint(); // Apply canny algorithm CvInvoke.Canny( image.Convert <Gray, byte>(), cannyImage, threshold1, threshold2, apertureSize); // Find the contours CvInvoke.FindContours( cannyImage, contours, null, GetRetrType(rtype), GetMethodType(mtype)); resultImage = cannyImage.Convert <Bgr, byte>(); // Draw the contours resultImage.DrawPolyline( contours.ToArrayOfArray(), false, new Bgr(Color.FromArgb(255, 77, 77)), 3); // Return collection of contours result.ImageArray = ImageHelper.SetImage(resultImage); result.ContourDatas = new List <ContourPointModel>(); result.ContourDatas = contours.ToArrayOfArray().Select(c => new ContourPointModel() { Count = c.Select(p => new PointF(p.X, p.Y)).ToArray().Length, StartX = c.Length > 0 ? c[0].X : float.NaN, StartY = c.Length > 0 ? c[0].Y : float.NaN, EndX = c.Length > 0 ? c[c.Length - 1].X : float.NaN, EndY = c.Length > 0 ? c[c.Length - 1].Y : float.NaN, Length = GetLength(c.Select(p => new PointF(p.X, p.Y)).ToArray()) }).ToList(); return(result); }
/// <summary> /// Detect scene text from the given image /// </summary> /// <param name="image">The image</param> /// <returns>The detected scene text.</returns> public DetectedObject[] Detect(IInputArray image) { using (VectorOfVectorOfPoint vvp = new VectorOfVectorOfPoint()) using (VectorOfFloat confidents = new VectorOfFloat()) { _textDetector.Detect(image, vvp, confidents); Point[][] detectionResults = vvp.ToArrayOfArray(); float[] confidentResult = confidents.ToArray(); List <DetectedObject> results = new List <DetectedObject>(); for (int i = 0; i < detectionResults.Length; i++) { DetectedObject st = new DetectedObject(); PointF[] detectedPointF = Array.ConvertAll(detectionResults[i], p => new PointF((float)p.X, (float)p.Y)); st.Region = CvInvoke.BoundingRectangle(detectionResults[i]); st.Confident = confidentResult[i]; using (Mat textSubMat = new Mat()) { FourPointsTransform(image, detectedPointF, new Size(100, 32), textSubMat); String text = _ocr.Recognize(textSubMat); st.Label = text; } results.Add(st); } return(results.ToArray()); } }
public List <Contour> Contours(RetrType retrievalMode = RetrType.Tree, ChainApproxMethod approximationMethod = ChainApproxMethod.ChainApproxSimple) { VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint(); Mat hierarchy = new Mat(); CvInvoke.FindContours(this.Data, contours, hierarchy, retrievalMode, approximationMethod); Point[][] contourArray = contours.ToArrayOfArray(); int[,,] hierarchyArray = (int[, , ])hierarchy.GetData(); List <Contour> output = new List <Contour>(); for (int i = 0; i < contourArray.Length; i++) { Contour c = new Contour(contourArray[i]) { Hierarchy = new int[] { hierarchyArray[0, i, 0], hierarchyArray[0, i, 1], hierarchyArray[0, i, 2], hierarchyArray[0, i, 3], } }; output.Add(c); } return(output); }
private void Draw(Mat image, int x, int y) { VectorOfVectorOfPoint cnt = new VectorOfVectorOfPoint(); CvInvoke.FindContours(image, cnt, null, RetrType.List, ChainApproxMethod.ChainApproxNone); Point[][] pts = cnt.ToArrayOfArray(); for (int i = 0; i < pts.Length; i++) { for (int j = 0; j < pts[i].Length; j++) { Point pt = pts[i][j]; if ((_lastPoint.X != -1 && !_lastPoint.Equals(MousePosition)) || _pid != GetActiveProcess()) { return; } pt.X += x; pt.Y += y; LeftMouseClick(pt.X, pt.Y, pt.X, pt.Y); Thread.Sleep(10); } } Fill(image, x, y); }
public static List <RawDefectInfo> FindDefectInfo( this VectorOfVectorOfPoint src) { return(src?.ToArrayOfArray() .Select(ptarr => ptarr.PointArr2DefectInfo()) .ToList()); }
public void _findOutline() { using (var im = _mat.Clone()) { VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint(); CvInvoke.FindContours(im, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple); var cts = contours.ToArrayOfArray() .Select(x => CvInvoke.ConvexHull(x.Select(y => new PointF(y.X, y.Y)).ToArray())).ToArray(); var cnt = cts.OrderByDescending(z => CvInvoke.ContourArea(new VectorOfPointF(z))).ToList(); var result = new VectorOfPointF(); foreach (var c in cnt) { var vop = new VectorOfPointF(c); var peri = CvInvoke.ArcLength(vop, true); var approx = new VectorOfPointF(); CvInvoke.ApproxPolyDP(vop, approx, _approxE * peri, true); if (approx.Size == 4) { result = approx; break; } } _outline = result; } }
public override void Process(Image <Bgr, byte> image, out Image <Bgr, byte> annotatedImage, out List <object> data) { base.Process(image, out annotatedImage, out data); using (var contours = new VectorOfVectorOfPoint()) { // find the contours for an image CvInvoke.FindContours(image.Convert <Gray, byte>(), contours, null, _mode, _method); // draw the contours annotatedImage.DrawPolyline(contours.ToArrayOfArray(), false, new Bgr(_annoColor.Color()), _lineThick); // return collection of contours data = contours.ToArrayOfArray().Select(c => new Contour(c)).Cast <object>().ToList(); } }
public override void Process(Image <Bgr, byte> image, out Image <Bgr, byte> annotatedImage, out List <object> data) { base.Process(image, out annotatedImage, out data); using (var contours = new VectorOfVectorOfPoint()) { // find the contours CvInvoke.FindContours( image.Convert <Gray, byte>(), contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple); // optionally show the contours if (_showContours) { annotatedImage.DrawPolyline(contours.ToArrayOfArray(), false, new Bgr(_contourColor.Color()), _lineThick); } // flatten the points of the contours into a single array var points = contours .ToArrayOfArray() .SelectMany(c => c) .Select(p => new PointF(p.X, p.Y)) .ToArray(); // get the convex hull var convexHull = CvInvoke.ConvexHull(points); // draw the convex hull annotatedImage.DrawPolyline( convexHull.Select(Point.Round).ToArray(), true, new Bgr(_annoColor.Color()), _lineThick); // set the data as a single contour for the convex hull data = new List <object> { new Contour(convexHull) }; } }
public void MSER() { var sourceBitmap = Samples.sample13; var w = sourceBitmap.Width; var h = sourceBitmap.Height; using var src = new UMat(); using var srcMat = sourceBitmap.ToMat(); srcMat.CopyTo(src); using var gray = new UMat(); CvInvoke.CvtColor(src, gray, ColorConversion.Bgra2Gray); using var detector = new MSERDetector( minArea: 5, maxArea: 80, edgeBlurSize: 5); using var msers = new VectorOfVectorOfPoint(); using var bboxes = new VectorOfRect(); detector.DetectRegions(gray, msers, bboxes); var sw = new Stopwatch(); sw.Start(); var n = 100; for (var i = 0; i < n; i++) { detector.DetectRegions(gray, msers, bboxes); } sw.Stop(); Console.WriteLine($"{(int)(sw.Elapsed.TotalMicroseconds() / n)} us"); var result = new byte[w * h]; foreach (var mser in msers.ToArrayOfArray()) { foreach (var point in mser) { result[point.Y * w + point.X] = 255; } } foreach (var bbox in bboxes.ToArray()) { } Run("samples/sample13.png"); //result.RunAs(w, h, 1, "mser.png"); }
public static Func <VectorOfVectorOfPoint> FnSortcontours(VectorOfVectorOfPoint inputContours) { var sort = new Func <VectorOfVectorOfPoint>(() => { var temp = inputContours.ToArrayOfArray(); var sorted = temp.OrderBy(p => p[0].Y).ThenBy(p => p[0].X).ToArray(); return(new VectorOfVectorOfPoint(sorted)); }); return(sort); }
private static IEnumerable <Point[]> FindContours(Bitmap image) { using (var cvImage = image.ToCvImage()) { var contour = new VectorOfVectorOfPoint(); CvInvoke.CvtColor(cvImage, cvImage, ColorConversion.Rgb2Gray); CvInvoke.FindContours(cvImage, contour, new Mat(), RetrType.External, ChainApproxMethod.ChainApproxTc89Kcos); return(contour.ToArrayOfArray()); } }
public static List <RotatedRect> FindMinimalBox( this VectorOfVectorOfPoint src) { return(src?.ToArrayOfArray() .Select(ptarr => ptarr.Select(pt => new System.Drawing.PointF(pt.X, pt.Y)) .ToArray()) .ToArray() .Select(ptfArr => CvInvoke.MinAreaRect(ptfArr)) .ToList()); }
/// <summary> /// Bound the contours. /// </summary> /// <param name="contours">The contours.</param> /// <param name="annotatedImage">The image with bound rectangles.</param> /// <param name="data">The raw data for rectangles.</param> private void BoundContours(VectorOfVectorOfPoint contours, ref Image <Bgr, byte> annotatedImage, ref List <object> data) { // optionally show the contours if (_showContours) { annotatedImage.DrawPolyline(contours.ToArrayOfArray(), false, new Bgr(_contourColor.Color()), _lineThick); } // bound object for each contour or all contours if (!_foreachContour) { var points = contours.ToArrayOfArray().SelectMany(p => p).ToArray(); FindRect(new VectorOfPoint(points), ref annotatedImage, ref data); } else { foreach (var contour in contours.ToArrayOfArray()) { FindRect(new VectorOfPoint(contour), ref annotatedImage, ref data); } } }
private void ProcessImage() { while (true) { // Read from webcam Mat m = new Mat(); capture.Read(m); img = m.Clone().ToImage <Bgr, byte>(); Image <Bgr, byte> tempImage = img.Clone(); // Blur image to remove noise tempImage = tempImage.SmoothGaussian(5); // Threshold image to find regions var greyImage = tempImage.Convert <Gray, byte>().ThresholdBinary(new Gray(100), new Gray(255)); VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint(); // Get points along edges CvInvoke.FindContours(greyImage, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple); // For debugging output CvInvoke.DrawContours(tempImage, contours, -1, new MCvScalar(1, 1, 0), -1); foreach (var contour in contours.ToArrayOfArray()) { VectorOfPoint poly = new VectorOfPoint(); // Finds polygon of contour CvInvoke.ApproxPolyDP(new VectorOfPoint(contour), poly, CvInvoke.ArcLength(new VectorOfPoint(contour), true) * 0.05, true); // Draw corners foreach (var point in poly.ToArray()) { tempImage.Draw(new CircleF(point, 2), new Bgr(255, 255, 0), -1); } // Triangle if (poly.Size == 3) { // Paint it blue tempImage.FillConvexPoly(poly.ToArray(), new Bgr(255, 0, 0)); } } // Update display pictureBoxFilter.Image = tempImage.ToBitmap(); pictureBoxOriginal.Image = img.ToBitmap(); Thread.Sleep(1); } }
// 补全轮廓并填充 private Image <Bgr, byte> ContourFilling(Image <Gray, byte> pic) { Image <Bgr, byte> outpic = new Image <Bgr, byte>(pic.Size); pic = pic.Canny(100, 255); Image <Gray, byte> outcon = new Image <Gray, byte>(pic.Size); VectorOfVectorOfPoint con = new VectorOfVectorOfPoint(); CvInvoke.FindContours(pic, con, outcon, RetrType.External, ChainApproxMethod.ChainApproxNone); Point[][] con1 = con.ToArrayOfArray(); PointF[][] con2 = Array.ConvertAll(con1, new Converter <Point[], PointF[]>(PointToPointF)); PointF[] hull = new PointF[con[0].Size]; for (int i = 0; i < con.Size; i++) { hull = CvInvoke.ConvexHull(con2[i], true); for (int j = 0; j < hull.Length; j++) { Point p1 = new Point((int)(hull[j].X + 0.5), (int)(hull[j].Y + 0.5)); Point p2; if (j == hull.Length - 1) { p2 = new Point((int)(hull[0].X + 0.5), (int)(hull[0].Y + 0.5)); } else { p2 = new Point((int)(hull[j + 1].X + 0.5), (int)(hull[j + 1].Y + 0.5)); } CvInvoke.Line(outpic, p1, p2, new MCvScalar(255, 0, 255, 255), 2, 0, 0); } } Image <Gray, byte> gray = new Image <Gray, byte>(pic.Size); gray = outpic.Convert <Gray, byte>(); gray = gray.ThresholdBinary(new Gray(100), new Gray(255)); gray = gray.Canny(100, 255); VectorOfVectorOfPoint con3 = new VectorOfVectorOfPoint(); CvInvoke.FindContours(gray, con3, outcon, RetrType.External, ChainApproxMethod.ChainApproxNone); for (int i = 0; i < con3.Size; i++) { CvInvoke.DrawContours(outpic, con3, i, new MCvScalar(255, 0, 0), -1); } return(outpic); }
public void ApplyFilter(Mat src) { CvInvoke.CvtColor(src, src, ColorConversion.Bgr2Hsv); Mat threshold = new Mat(src.Height, src.Width, src.Depth, src.NumberOfChannels); MCvScalar min = new MCvScalar(m_hmin, m_smin, m_vmin); MCvScalar max = new MCvScalar(m_hmax, m_smax, m_vmax); CvInvoke.InRange(src, new ScalarArray(min), new ScalarArray(max), threshold); Mat element = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(3, 3), Point.Empty); CvInvoke.Erode(threshold, threshold, element, Point.Empty, 1, BorderType.Constant, new MCvScalar(1.0f)); CvInvoke.Canny(threshold, threshold, 100, 255); VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint(); Mat hierarchy = new Mat(); CvInvoke.FindContours(threshold, contours, hierarchy, RetrType.Tree, ChainApproxMethod.ChainApproxSimple, Point.Empty); Mat draw = new Mat(src.Height, src.Width, src.Depth, 1); draw.SetTo(new MCvScalar(0.0)); int i = 0; //Debug.Log("CONTOURS"); var contoursArray = contours.ToArrayOfArray(); foreach (Point[] contour in contoursArray) { CvInvoke.DrawContours(draw, contours, i, new MCvScalar(255.0), 1, LineType.EightConnected, null, int.MaxValue, Point.Empty); double a = CvInvoke.ContourArea(new VectorOfPoint(contour)); //Debug.Log("Contour: " + a); i++; } //Emgu.CV.UI.ImageViewer.Show(draw, "test"); if (m_onFrame != null) { m_onFrame.Invoke(draw); } }
//OnClick of Capture Button private void Button1_Click(object sender, EventArgs e) { try { if (worker != null) { worker.Abort(); } using (var img = new Image <Bgr, byte>(CaptureScreen(Helper.ScreenBounds()))) { var filtrdimg = img.InRange(new Bgr(189, 189, 189), new Bgr(205, 205, 205)); //Threshold the image, the window we need is usually within these colors VectorOfVectorOfPoint cnts = new VectorOfVectorOfPoint(); CvInvoke.FindContours(filtrdimg, cnts, null, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple); //Get contours in the thresholded image var biggstcontour = (from u in cnts.ToArrayOfArray() orderby CvInvoke.ContourArea(new VectorOfPoint(u)) descending select u).FirstOrDefault(); //Get the contour with the biggest area /* Store the location of the biggest contour */ regionRectangle = CvInvoke.BoundingRectangle(new VectorOfPoint(biggstcontour)); selectX = regionRectangle.X; selectY = regionRectangle.Y; using (var imgcrpd = new Image <Bgr, byte>(CaptureScreen(regionRectangle))) { using (var template = new Image <Bgr, Byte>("startsmile.png")) //startmsile.png is the smiley that appears on game start { var res = imgcrpd.MatchTemplate(template, Emgu.CV.CvEnum.TemplateMatchingType.Ccorr); //Match the smiley to find the contour of the game window res.MinMax(out double[] min_val, out double[] max_val, out Point[] min_loc, out Point[] max_loc); startcords = new Point(selectX + max_loc[0].X + 7, selectY + max_loc[0].Y + 7); //Get the coordinates of the smiley button, with 7px extra to account for middle of the button DoLogic(regionRectangle); } } } } catch { MessageBox.Show("The game window was not found. This programs only supports the Windows XP Minesweeper application or http://minesweeperonline.com/"); } }
//sort contours public void contourSort() { sortedContours.Clear(); List <List <Point> > list = arrToList(contours.ToArrayOfArray()); sortedContours.Add(extractVector(list, 0)); // extract the first vector while (list.Count != 0) { int save = 0; //find the closest vector for (int i = 1; i < list.Count; i++) { if (isVectorCloser(sortedContours.Last(), list[i], list[save])) { save = i; } } //sort and insert vector into contours object contourSortInsert(ref sortedContours, extractVector(list, save)); } }
private void button2_Click(object sender, EventArgs e) { Image <Gray, byte> image2 = new Image <Gray, byte>(image1.Width, image1.Height); Image <Gray, byte> image3 = new Image <Gray, byte>(image1.Width, image1.Height); Image <Bgr, byte> image4 = new Image <Bgr, byte>(image1.Width, image1.Height); CvInvoke.Canny(image1, image2, 100, 60); VectorOfVectorOfPoint con = new VectorOfVectorOfPoint(); CvInvoke.FindContours(image2, con, image3, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple); Point[][] con1 = con.ToArrayOfArray(); PointF[][] con2 = Array.ConvertAll <Point[], PointF[]>(con1, new Converter <Point[], PointF[]>(PointToPointF)); for (int i = 0; i < con.Size; i++) { PointF[] hull = CvInvoke.ConvexHull(con2[i], true); for (int j = 0; j < hull.Length; j++) { Point p1 = new Point((int)(hull[j].X + 0.5), (int)(hull[j].Y + 0.5)); Point p2; if (j == hull.Length - 1) { p2 = new Point((int)(hull[0].X + 0.5), (int)(hull[0].Y + 0.5)); } else { p2 = new Point((int)(hull[j + 1].X + 0.5), (int)(hull[j + 1].Y + 0.5)); } CvInvoke.Circle(image4, p1, 3, new MCvScalar(0, 255, 255, 255), 6); CvInvoke.Line(image4, p1, p2, new MCvScalar(255, 255, 0, 255), 3); } } for (int i = 0; i < con.Size; i++) { CvInvoke.DrawContours(image4, con, i, new MCvScalar(255, 0, 255, 255), 2); } imageBox2.Image = image1.ConcateVertical(image4); }
public void UpdateInfo(VectorOfVectorOfPoint VVP) { Contours = VVP; rect = new System.Drawing.Rectangle[Contours.Size]; if (Contours.Size <= threshold) { masterHeights = new List <double>(); masterWidths = new List <double>(); masterArea = new List <double>(); masterCenterX = new List <double>(); masterCenterY = new List <double>(); Points = VVP.ToArrayOfArray(); getRectangles(); publish(); } else { Console.WriteLine("Threshold of {0} contours has been met. \nStopping processing of contours.", threshold); } //iterate(); }
public Result <Point[][]> Process(Mat input) { var contoursDetected = new VectorOfVectorOfPoint(); CvInvoke.FindContours(input, contoursDetected, null, RetrType.List, ChainApproxMethod.ChainApproxSimple); var contours = contoursDetected.ToArrayOfArray(); Result <Point[][]> result; if (contours.Length > 0) { result = Result.Ok(contours); } else { result = Result.Fail <Point[][]>("Contours hasn't been found"); } _debugLogger.Log(logBuilder => { if (result.Success) { var imageToDrawContours = new Mat(input.Size, DepthType.Cv8U, 3); imageToDrawContours.SetTo(new MCvScalar(0, 0, 0)); var random = new Random(); for (int i = 0; i < contours.Length; i++) { CvInvoke.DrawContours(imageToDrawContours, contoursDetected, i, new MCvScalar(random.Next(255), random.Next(255), random.Next(255))); } logBuilder.AddMessage($"Found {contours.Length} contours").AddImage(imageToDrawContours); } else { logBuilder.AddMessage(result.Error); } }); return(result); }
/// <summary>Поиск контура объекта</summary><returns>Изображение с выделенным контуром объекта</returns> /// реализовать проверку на наличие изображения в pictureBox /// Реализовать нахождения максимального по площади контура private Image <Bgr, byte> searchСounters() { try { Image <Gray, byte> outputImage = image.Convert <Gray, byte>().ThresholdBinary(new Gray(150), new Gray(255)); VectorOfVectorOfPoint countors = new VectorOfVectorOfPoint(); Mat hierarchy = new Mat(); CvInvoke.FindContours(inversion(outputImage), countors, hierarchy, Emgu.CV.CvEnum.RetrType.Tree, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxNone); Image <Bgr, byte> save = new Image <Bgr, byte>(image.Width, image.Height, new Bgr(255, 255, 255)); CvInvoke.DrawContours(save, countors, 0, new MCvScalar(0, 0, 255), 1); CvInvoke.DrawContours(image, countors, 0, new MCvScalar(0, 0, 255), 1); save.Save("C:\\Users\\PC\\Desktop\\Тестовые изображения\\test2.png"); Point[][] list; list = countors.ToArrayOfArray(); Point[] test; test = list[0]; int[] point = CharacteristicObject.Curvature_calculation_points_counter(test); listBox1.Items.Add("Выпуклые 90: " + point[0]); listBox1.Items.Add("Вогнутые 90: " + point[1]); listBox1.Items.Add("Выпуклые 135: " + point[2]); listBox1.Items.Add("Вогнутые 135: " + point[3]); listBox1.Items.Add("Нулевая кривизна: " + point[4]); int[] pointN = CharacteristicObject.SearchForConnectedPoints(test); listBox1.Items.Add("N1: " + pointN[0]); listBox1.Items.Add("N2: " + pointN[1]); listBox1.Items.Add("N3: " + pointN[2]); listBox1.Items.Add("N4: " + pointN[3]); listBox1.Items.Add("N5: " + pointN[4]); listBox1.Items.Add("N6: " + pointN[5]); listBox1.Items.Add("N7: " + pointN[6]); listBox1.Items.Add("N8: " + pointN[7]); return(save); } catch (ExeptionSearchСounters ex) { throw new ExeptionSearchСounters(ex); } }
private void test(Image <Gray, byte> img) { int n = Convert.ToInt32(comboBox1.SelectedIndex); isCouterFind = false; //Image<Gray, byte> Dyncontour = new Image<Gray, byte>(src.Size); //VectorOfVectorOfPoint use_Dyncontour = new VectorOfVectorOfPoint(); //VectorOfVectorOfPoint Dynstorage = new VectorOfVectorOfPoint(); Mat dst1 = new Mat(); CvInvoke.Threshold(img, dst1, threshold_value, 255, threshs[n]); // imageBox2.Image = dst1.Bitmap; VectorOfVectorOfPoint vvp = new VectorOfVectorOfPoint(); VectorOfVectorOfPoint use_vvp = new VectorOfVectorOfPoint(); CvInvoke.FindContours(dst1, vvp, null, Emgu.CV.CvEnum.RetrType.List, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple); int number = vvp.ToArrayOfArray().Length;//取得轮廓的数量. for (int i = 0; i < number; i++) { VectorOfPoint vp = vvp[i]; double area = CvInvoke.ContourArea(vp); if (area > minArea && area < maxArea) //可按实际图片修改 { use_vvp.Push(vp); } } if (use_vvp.Size > 0) { Mat result = new Mat(img.Size, Emgu.CV.CvEnum.DepthType.Cv8U, 3); result.SetTo(new MCvScalar(0, 0, 0)); CvInvoke.DrawContours(result, use_vvp, -1, new MCvScalar(0, 255, 0)); imageBox2.Image = result; } }
/// <summary> /// 身份证号区域 /// </summary> /// <param name="img"></param> /// <returns></returns> public static RotatedRect IdRotatedRect(Image <Bgr, byte> img) { Image <Bgr, byte> a = new Image <Bgr, byte>(img.Size); VectorOfVectorOfPoint con = GetContours(BinImg(img)); Point[][] con1 = con.ToArrayOfArray(); PointF[][] con2 = Array.ConvertAll <Point[], PointF[]>(con1, new Converter <Point[], PointF[]>(PointToPointF)); for (int i = 0; i < con.Size; i++) { RotatedRect rrec = CvInvoke.MinAreaRect(con2[i]); float w = rrec.Size.Width; float h = rrec.Size.Height; if (w / h > 6 && w / h < 10 && h > 20) { PointF[] pointfs = rrec.GetVertices(); for (int j = 0; j < pointfs.Length; j++) { CvInvoke.Line(a, new Point((int)pointfs[j].X, (int)pointfs[j].Y), new Point((int)pointfs[(j + 1) % 4].X, (int)pointfs[(j + 1) % 4].Y), new MCvScalar(0, 0, 255, 255), 4); } return(rrec); } } return(new RotatedRect()); }
public static Contours GetContours(System.Drawing.Bitmap bmp) { //var newbmp = bmp.Scale(2); //StringBuilder msgBuilder = new StringBuilder("Performance: "); //var imgfile = AppDomain.CurrentDomain.BaseDirectory + imageUrl; //Load the image from file and resize it for display Image <Gray, Byte> img = new Image <Gray, byte>(bmp); //.Resize(400, 400, Emgu.CV.CvEnum.Inter.Linear, true); //Convert the image to grayscale and filter out the noise //UMat uimage = new UMat(); //CvInvoke.CvtColor(img, uimage, ColorConversion.Bgr2Gray); //var imageGray = img.Convert<Gray, Byte>(); //var imagethreshold = img.ThresholdBinary(new Gray(1), new Gray(255)); CvInvoke.Threshold(img, img, 1, 255, ThresholdType.Binary); //imagethreshold.FillConvexPoly(); //use image pyr to remove noise //UMat pyrDown = new UMat(); //CvInvoke.PyrDown(uimage, pyrDown); //CvInvoke.PyrUp(pyrDown, uimage); //Image<Gray, Byte> gray = img.Convert<Gray, Byte>().PyrDown().PyrUp(); //#region circle detection //Stopwatch watch = Stopwatch.StartNew(); //double cannyThreshold = 100;//180.0; //double cannyThresholdLinking = 100;//120.0; //UMat cannyEdges = new UMat(); //CvInvoke.Canny(uimage, cannyEdges, cannyThreshold, cannyThresholdLinking); //int[,] tempStructure = { { 1, 1, 1 } }; //Mat structuringElement = CvInvoke.GetStructuringElement(ElementShape.Ellipse, new System.Drawing.Size(2, 2), new System.Drawing.Point(-1, -1)); //CvInvoke.Dilate(img, img, structuringElement, new System.Drawing.Point(-1, -1), 1, BorderType.Default, new MCvScalar(0, 0, 0)); //CvInvoke.Dilate(img, img, structuringElement, new System.Drawing.Point(-1, -1), 1, BorderType.Default, // new MCvScalar(0, 0, 0)); //CvInvoke.Erode(img, img, structuringElement, new System.Drawing.Point(-1, -1), 1, BorderType.Default, // new MCvScalar(0, 0, 0)); ///////////////////////////////////// using (Mat hierachy = new Mat()) using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint()) { CvInvoke.FindContours(img, contours, hierachy, RetrType.Tree, ChainApproxMethod.ChainApproxSimple); //CvInvoke.DrawContours(); ////////////////////////////////////// //多边形逼近 //List<VectorOfPoint> results = new List<VectorOfPoint>(); //for (int i = 0; i < contours.Size; i++) //{ // var contour = contours[i]; // VectorOfPoint approxContour = new VectorOfPoint(); // CvInvoke.ApproxPolyDP(contour, approxContour, 0.5, true); // results.Add(approxContour); // count1 += contour.Size; // count2 += approxContour.Size; // CvInvoke.Dilate(contour, contour,); //} var list = contours.ToArrayOfArray().Select(v => new Contour { Pts = v }).OrderByDescending(v => v.Pts.Length).ToList(); //var list = results.Select(v => new Contour { Pts = v.ToArray() }).OrderByDescending(v => v.Pts.Length).ToList(); Contours Cons = new Contours(); Cons.Items = list; Cons.Width = img.Width; Cons.Height = img.Height; return(Cons); } }
/// <summary> /// Rozpoznaje pionki na planszy. Przed wywołaniem należy wywołać funkcję RozpoznajPola. /// </summary> /// <returns>Zwraca pozycje pionków na warcabnicy. Jeśli nie wywołano funkcji RozpoznajPola lub zwróciła ona inną wartość niż 32, funkcja zwraca null.</returns> public Pionek[] RozpoznajPionki() { if (Plansza == null) { return(null); } Mat obr = WczytajObraz(); HashSet <Pionek> pionki = new HashSet <Pionek>(); DanePionka[] dane = new DanePionka[] { new DanePionka() { min = pionki_min, max = pionki_max, typ = TypObiektu.Pionki }, new DanePionka() { min = damki_min, max = damki_max, typ = TypObiektu.Damki }, new DanePionka() { min = pionki_wrog_min, max = pionki_wrog_max, typ = TypObiektu.PionkiWrog }, new DanePionka() { min = damki_wrog_min, max = damki_wrog_max, typ = TypObiektu.DamkiWrog } }; for (int d = 0; d < dane.Length; d++) { VectorOfVectorOfPoint kontury = new VectorOfVectorOfPoint(); Mat wyciety = new Mat(); AnalizujPlansze(obr, dane[d].min, dane[d].max, ref kontury, ref wyciety); Point[][] punkty = kontury.ToArrayOfArray(); Pole pole; Point srodek; Pole pp; bool znaleziono; for (int i = 0; i < punkty.Length; i++) { pole = new Pole(punkty[i].Min(p => p.X), punkty[i].Max(p => p.X), punkty[i].Min(p => p.Y), punkty[i].Max(p => p.Y)); srodek = new Point(pole.xmin + (pole.xmax - pole.xmin) / 2, pole.ymin + (pole.ymax - pole.ymin) / 2); znaleziono = false; for (int x = 0; x < POLA_WIERSZ; x++) { for (int y = 0; y < POLA_WIERSZ; y++) { pp = Plansza[x, y]; if (pp.xmin < srodek.X && pp.xmax > srodek.X && pp.ymin < srodek.Y && pp.ymax > srodek.Y) { pionki.Add(new Pionek() { x = x, y = y, typ = dane[d].typ }); znaleziono = true; break; } } if (znaleziono) { break; } } } } return(pionki.ToArray()); }
/// <summary> /// Rozpoznaje białe pola na warcabnicy. /// </summary> /// <returns>Ilość rozpoznanych pól.</returns> public int RozpoznajPola() { Mat obr = WczytajObraz(); VectorOfVectorOfPoint kontury = new VectorOfVectorOfPoint(); Mat wyciety = new Mat(); AnalizujPlansze(obr, pola_min, pola_max, ref kontury, ref wyciety); if (kontury.Size != ILOSC_POL_KOLOR) { Plansza = null; return(kontury.Size); } Point[][] punkty = kontury.ToArrayOfArray(); Pole[] biale = new Pole[punkty.Length]; int srednia_szer = 0; int srednia_wys = 0; Pole pole; Point[] pola = new Point[ILOSC_POL]; //Oblicz srednie rozmiary pol bialych for (int i = 0; i < punkty.Length; i++) { pole = new Pole(punkty[i].Min(p => p.X), punkty[i].Max(p => p.X), punkty[i].Min(p => p.Y), punkty[i].Max(p => p.Y)); biale[i] = pole; srednia_szer += pole.xmax - pole.xmin; srednia_wys += pole.ymax - pole.ymin; } srednia_szer /= punkty.Length; srednia_wys /= punkty.Length; //Wyznacz granice pol biale = biale.OrderBy(p => p.ymin).ToArray(); Pole plansza_rozm = new Pole(biale.Min(p => p.xmin), biale.Max(p => p.xmax), biale.Min(p => p.ymin), biale.Max(p => p.ymax)); Plansza = new Pole[POLA_WIERSZ, POLA_WIERSZ]; int ixw = 0; int ixk = 0; for (int i = 0; i < biale.Length; i += 4) { Pole[] wiersz = new Pole[POLA_WIERSZ_KOLOR]; for (int j = 0; j < POLA_WIERSZ_KOLOR; j++) { wiersz[j] = biale[i + j]; } wiersz = wiersz.OrderBy(p => p.xmin).ToArray(); if (wiersz[0].xmin > (plansza_rozm.xmin + srednia_szer)) //W wierszu najpierw czarne { Plansza[0, ixk] = new Pole(plansza_rozm.xmin, wiersz[0].xmin, wiersz[0].ymin, wiersz[0].ymax, KolorPola.czarne); ixw = 1; for (int j = 0; j < POLA_WIERSZ_KOLOR; j++) { Plansza[ixw, ixk] = new Pole(wiersz[j], KolorPola.biale); ixw++; if (j != POLA_WIERSZ_KOLOR - 1) { Plansza[ixw, ixk] = new Pole(wiersz[j].xmax, wiersz[j + 1].xmin, wiersz[j].ymin, wiersz[j].ymax, KolorPola.czarne); ixw++; } } } else //W wierszu najpierw biale { ixw = 0; for (int j = 0; j < POLA_WIERSZ_KOLOR; j++) { Plansza[ixw, ixk] = new Pole(wiersz[j], KolorPola.biale); ixw++; if (j != POLA_WIERSZ_KOLOR - 1) { Plansza[ixw, ixk] = new Pole(wiersz[j].xmax, wiersz[j + 1].xmin, wiersz[j].ymin, wiersz[j].ymax, KolorPola.czarne); ixw++; } } Plansza[7, ixk] = new Pole(wiersz[3].xmax, plansza_rozm.xmax, wiersz[3].ymin, wiersz[3].ymax, KolorPola.czarne); } ixk++; } return(punkty.Length); }
private void button7_Click(object sender, EventArgs e) { var image = (Image <Gray, Single>)imageBox1.Image; Image <Gray, Byte> image2 = image.Convert <Gray, Byte>(); VectorOfVectorOfPoint con = new VectorOfVectorOfPoint(); Image <Gray, byte> c = new Image <Gray, byte>(image.Width, image.Height); CvInvoke.FindContours(image2, con, c, RetrType.External, ChainApproxMethod.ChainApproxNone); Point[][] con1 = con.ToArrayOfArray(); PointF[][] con2 = Array.ConvertAll <Point[], PointF[]>(con1, new Converter <Point[], PointF[]>(PointToPointF)); int k = 1; for (int i = 0; i < con.Size; i++) { CvInvoke.DrawContours(img, con, i, new MCvScalar(255, 0, 255, 255), 2); RotatedRect rrec = CvInvoke.MinAreaRect(con2[i]); PointF[] pointfs = rrec.GetVertices(); if (verifySize(rrec)) { for (int j = 0; j < pointfs.Length; j++) { CvInvoke.Line(img, new Point((int)pointfs[j].X, (int)pointfs[j].Y), new Point((int)pointfs[(j + 1) % 4].X, (int)pointfs[(j + 1) % 4].Y), new MCvScalar(0, 255, 0, 255), 4); float r = rrec.Size.Width / rrec.Size.Height; float angle = rrec.Angle; SizeF rect_size = rrec.Size; Size rectsize = rect_size.ToSize(); if (r < 1) { angle = 90 + angle; float a = rect_size.Width; rect_size.Width = rect_size.Height; rect_size.Height = a; } if (angle - m_angle < 0 && angle + m_angle > 0) { Mat img_rotated = new Mat(); Mat rotmat = new Mat(); Mat resultMat = new Mat(); CvInvoke.GetRotationMatrix2D(rrec.Center, angle, 1, rotmat); CvInvoke.WarpAffine(img, img_rotated, rotmat, img.Size, Inter.Cubic); CvInvoke.Imshow("img_rotated", img_rotated); PointF recCenterF = rrec.Center; resultMat = showResultMat(img_rotated, rectsize, rrec.Center, k++); } } } } PointF[] PointToPointF(Point[] pf) { PointF[] aaa = new PointF[pf.Length]; int num = 0; foreach (var point in pf) { aaa[num].X = (int)point.X; aaa[num++].Y = (int)point.Y; } return(aaa); } imageBox1.Image = img; //Image<Bgr, byte> a = img; //Image<Gray, byte> b = new Image<Gray, byte>(a.Width, a.Height); //Image<Gray, byte> c = new Image<Gray, byte>(a.Width, a.Height); //Image<Bgr, byte> d = new Image<Bgr, byte>(a.Width, a.Height); //CvInvoke.Canny(a, b, 100, 60); //VectorOfVectorOfPoint con = new VectorOfVectorOfPoint(); //CvInvoke.FindContours(b, con, c, RetrType.External, ChainApproxMethod.ChainApproxNone); //for (int i = 0; i < con.Size; i++) // CvInvoke.DrawContours(d, con, i, new MCvScalar(255, 0, 255, 255), 2); //imageBox1.Image = d; }
private void Application_Idle(object sender, EventArgs e) { Mat a = cap.QueryFrame(); if (a != null) { System.Threading.Thread.Sleep((int)(1000.0 / fps - 5)); imageBox1.Image = a; GC.Collect(); } /* * Image<Bgr, byte> colorImage = new Image<Bgr, byte>(imageBox1.Image.Bitmap); * //取得灰階影像 * Image<Gray, byte> grayImage = new Image<Gray, byte>(colorImage.Bitmap); * imageBox2.Image = grayImage; * * * //二值化的閥值 * Gray thresholdValue = new Gray(55); * //取得二值化影像 * Image<Gray, byte> thresholdImage = grayImage.ThresholdBinary(thresholdValue, new Gray(255)); * //thresholdImage.Save("threshold.bmp"); * imageBox3.Image = thresholdImage;*/ if (a != null) { Image <Bgr, byte> colorImage = new Image <Bgr, byte>(imageBox1.Image.Bitmap); Image <Gray, byte> b = new Image <Gray, byte>(a.Width, a.Height); Image <Gray, byte> c = new Image <Gray, byte>(a.Width, a.Height); Image <Bgr, byte> d = new Image <Bgr, byte>(a.Width, a.Height); Image <Gray, byte> abc = new Image <Gray, byte>(a.Width, a.Height); CvInvoke.Canny(colorImage, b, 100, 60); VectorOfVectorOfPoint con = new VectorOfVectorOfPoint(); CvInvoke.FindContours(b, con, c, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple); Point[][] con1 = con.ToArrayOfArray(); PointF[][] con2 = Array.ConvertAll <Point[], PointF[]>(con1, new Converter <Point[], PointF[]>(PointToPointF)); for (int i = 0; i < con.Size; i++) { PointF[] hull = CvInvoke.ConvexHull(con2[i], true); for (int j = 0; j < hull.Length; j++) { Point p1 = new Point((int)(hull[j].X + 0.5), (int)(hull[j].Y + 0.5)); Point p2; if (j == hull.Length - 1) { p2 = new Point((int)(hull[0].X + 0.5), (int)(hull[0].Y + 0.5)); } else { p2 = new Point((int)(hull[j + 1].X + 0.5), (int)(hull[j + 1].Y + 0.5)); } CvInvoke.Circle(abc, p1, 3, new MCvScalar(0, 255, 255, 255), 6); CvInvoke.Line(abc, p1, p2, new MCvScalar(255, 255, 0, 255), 3); } } for (int i = 0; i < con.Size; i++) { CvInvoke.DrawContours(d, con, i, new MCvScalar(255, 0, 255, 255), 2); } imageBox2.Image = d; imageBox3.Image = abc; } }
private Dictionary <int, KeyValuePair <decimal, decimal> > _FindContoursAndCalculate(Emgu.CV.Image <Bgr, Byte> colorImage, out Emgu.CV.Image <Gray, Byte> processedImage) { int circles = 0; VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint(); Mat hierarchy = new Mat(); /// Detect edges using Threshold Image <Gray, Byte> Img_Source_Gray = colorImage.Convert <Gray, Byte>(); Img_Source_Gray = Img_Source_Gray.SmoothBlur(3, 3); Image <Gray, Byte> threshold_output = Img_Source_Gray.ThresholdBinary(new Gray(90), new Gray(255)); /// Find contours CvInvoke.FindContours(threshold_output, contours, hierarchy, RetrType.Tree, ChainApproxMethod.ChainApproxSimple); /// Approximate contours to polygons + get bounding rects and circles VectorOfVectorOfPoint contours_poly = new VectorOfVectorOfPoint(contours.Size); Point[][] con = contours.ToArrayOfArray(); PointF[][] conf = new PointF[con.GetLength(0)][]; for (int i = 0; i < con.GetLength(0); i++) { conf[i] = new PointF[con[i].Length]; for (int j = 0; j < con[i].Length; j++) { conf[i][j] = new PointF(con[i][j].X, con[i][j].Y); } } for (int i = 0; i < contours.Size; i++) { double a = CvInvoke.ContourArea(contours[i], false); if (a > 30000) { CvInvoke.ApproxPolyDP(contours[i], contours_poly[circles], 3, true); circles++; } } /// Draw polygonal contour + bonding rects + circles Image <Gray, byte> filteredImage = new Image <Gray, byte>(Img_Source_Gray.Width, Img_Source_Gray.Height); for (int i = 0; i < circles; i++) { CvInvoke.DrawContours(filteredImage, contours_poly, i, new MCvScalar(255, 255, 255), -1); } filteredImage = colorImage.Convert <Gray, Byte>().And(filteredImage); Image <Gray, Byte> whiteAreas = new Image <Gray, byte>(filteredImage.Width, filteredImage.Height); List <DetectedCircle> detectedCircles = new List <DetectedCircle>(); for (int i = 0; i < circles; i++) { PointF[] pointfs = Array.ConvertAll(contours_poly[i].ToArray(), input => new PointF(input.X, input.Y)); Rectangle boundingRect = PointCollection.BoundingRectangle(pointfs); DetectedCircle detectedCircle = new DetectedCircle() { contour = contours_poly[i], boundingRect = boundingRect, center = new Point(boundingRect.X + (boundingRect.Width / 2), boundingRect.Y + (boundingRect.Height / 2)) }; detectedCircles.Add(detectedCircle); filteredImage.ROI = boundingRect; int threshold = _ComputeThreshold(filteredImage, detectedCircle); filteredImage.ROI = Rectangle.Empty; Image <Gray, Byte> mask = new Image <Gray, byte>(filteredImage.Width, filteredImage.Height); mask.Draw(boundingRect, new Gray(255), -1); mask = filteredImage.And(mask); /* Extract white are solely based on the Blue channel */ mask = mask.ThresholdBinary(new Gray(threshold), new Gray(255)); whiteAreas = whiteAreas.Or(mask.Convert <Gray, Byte>().ThresholdBinary(new Gray(10), new Gray(255))); CvInvoke.DrawContours(whiteAreas, contours_poly, i, new MCvScalar(255, 255, 255), 3); } detectedCircles = detectedCircles.OrderBy(c => c.center.X).ToList(); processedImage = whiteAreas; return(_ComputeMetrics(whiteAreas, detectedCircles, circles)); }