public static List <VectorOfPoint> GetContours(Image <Gray, Byte> image, ChainApproxMethod apxMethod = ChainApproxMethod.ChainApproxSimple, RetrType retrievalType = RetrType.List, double accuracy = 0.001d, double minimumArea = 10) { List <VectorOfPoint> convertedContours = new List <VectorOfPoint>(); using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint()) { using (Image <Gray, Byte> tempImage = image.Copy()) { CvInvoke.FindContours(tempImage, contours, null, retrievalType, apxMethod); } int count = contours.Size; for (int i = 0; i < count; i++) { using (VectorOfPoint contour = contours[i]) { VectorOfPoint approxContour = new VectorOfPoint(); CvInvoke.ApproxPolyDP(contour, approxContour, accuracy, false); if (CvInvoke.ContourArea(approxContour, false) > minimumArea) { convertedContours.Add(approxContour); } } } } return(convertedContours); }
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); }
public static Tuple <VectorOfVectorOfPoint, Mat> FindContours ( Image <Gray, byte> inImage , RetrType retrType = RetrType.External , ChainApproxMethod chainApproxMethod = ChainApproxMethod.ChainApproxSimple) { var contours = new VectorOfVectorOfPoint(); var hierarchy = new Mat(); CvInvoke.FindContours(inImage, contours, hierarchy, retrType, chainApproxMethod); return(new Tuple <VectorOfVectorOfPoint, Mat>(contours, hierarchy)); }
//Function used to implement the CvInvoke.FindContours method public VectorOfVectorOfPoint FindContours(Image <Gray, byte> image, ChainApproxMethod method = ChainApproxMethod.ChainApproxSimple, RetrType type = RetrType.List) { // Check that all parameters are valid. VectorOfVectorOfPoint result = new VectorOfVectorOfPoint(); if (method == Emgu.CV.CvEnum.ChainApproxMethod.ChainCode) { //throw new ColsaNotImplementedException("Chain Code not implemented, sorry try again later"); } CvInvoke.FindContours(image, result, null, type, method); return(result); }
private void ContouringMethod_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) { int type = (int)ContouringMethod.SelectedValue; switch (type) { case 1: contouringMethod = ChainApproxMethod.ChainApproxSimple; break; case 2: contouringMethod = ChainApproxMethod.ChainApproxTc89Kcos; break; case 3: contouringMethod = ChainApproxMethod.ChainApproxTc89L1; break; } }
public void Update(Mat img, ChainApproxMethod method = ChainApproxMethod.ChainApproxNone) { m_contours.Clear(); Mat grayImg = img; if (img.NumberOfChannels > 1) { grayImg = new Mat(); CvInvoke.CvtColor(img, grayImg, ColorConversion.Bgr2Gray); } // hierachy[0][i] 0я иерархии для i-ого контура // hierachy[0][i][0] - индекс следующего контура на том же уровне // hierachy[0][i][1] - индекс предыдущий контура на том же уровне // hierachy[0][i][2] - Индекс потомка // hierachy[0][i][3] - Индекс родителя using (Mat hierachy = new Mat()) using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint()) { CvInvoke.FindContours(grayImg, contours, hierachy, RetrType.Tree, method); if (contours.Size == 0) { return; } int sz = contours.Size * 4; int[] hierachyArray = new int[sz]; Marshal.Copy(hierachy.DataPointer, hierachyArray, 0, sz); for (int i = 0; i < contours.Size; i++) { if (contours[i].Size > 2) { int parentID = hierachyArray[i * 4 + 3]; CvContourInfo info = new CvContourInfo(i, parentID, contours[i]); // пока не понял логику m_contours.Add(info); } } } }
public List <Contour> Polygons(ChainApproxMethod approximationMethod = ChainApproxMethod.ChainApproxSimple) { List <Contour> output = new List <Contour>(); List <Contour> contours = this.Contours(RetrType.Ccomp, approximationMethod); VectorOfPoint polygon = new VectorOfPoint(); foreach (Contour contour in contours) { if (contour.Hierarchy[2] < 0) { continue; } VectorOfPoint contourVector = new VectorOfPoint(contour.Data); CvInvoke.ApproxPolyDP(contourVector, polygon, CvInvoke.ArcLength(contourVector, true) * 0.05, true); output.Add(new Contour(polygon.ToArray())); } return(output); }
public static List <VectorOfPoint> FindContours(Image <Gray, byte> image, RetrType retrType = RetrType.List, ChainApproxMethod chainApproxMethod = ChainApproxMethod.ChainApproxSimple) { // Contours VectorOfVectorOfPoint contoursDetected = new VectorOfVectorOfPoint(); CvInvoke.FindContours(image, contoursDetected, null, retrType, chainApproxMethod); var contoursArray = new List <VectorOfPoint>(); int count = contoursDetected.Size; for (int i = 0; i < count; i++) { using (VectorOfPoint currContour = contoursDetected[i]) { contoursArray.Add(currContour); } } return(contoursArray); }
public static List<VectorOfPoint> GetContours(Image<Gray, Byte> image, ChainApproxMethod apxMethod = ChainApproxMethod.ChainApproxSimple, RetrType retrievalType = RetrType.List, double accuracy = 0.001d, double minimumArea = 10) { List<VectorOfPoint> convertedContours = new List<VectorOfPoint>(); using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint()) { using (Image<Gray, Byte> tempImage = image.Copy()) { CvInvoke.FindContours(tempImage, contours, null, retrievalType, apxMethod); } int count = contours.Size; for (int i = 0; i < count; i++) { using (VectorOfPoint contour = contours[i]) { VectorOfPoint approxContour = new VectorOfPoint(); CvInvoke.ApproxPolyDP(contour, approxContour, accuracy, false); if (CvInvoke.ContourArea(approxContour, false) > minimumArea) { convertedContours.Add(approxContour); } } } } return convertedContours; }
public static IList <ContourWithMass> DeterminationOfCentromass(Image <Gray, byte> bin, ChainApproxMethod method) { var totalresult = new List <ContourWithMass>(); // лист для хранения ВСЕХ НАЙДЕНЫХ КОНТУРОВ Mat hierarchy = new Mat(); // выделение массива для хранения контуров using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint()) { CvInvoke.FindContours(bin, contours, hierarchy, RetrType.List, method);//поиск контуров { for (int i = 0; i < contours.Size; i++) { using (VectorOfPoint contour = contours[i])// ищем i-тый контур в коллекции всех контуров { ContourWithMass massVar = new ContourWithMass(); var result = new List <Point>(); result.Add(new Point(contour[contour.Size - 1].X, contour[contour.Size - 1].Y)); result.AddRange(contour.ToArray()); massVar.Mass.X = (int)result.Average(_ => _.X); massVar.Mass.Y = (int)result.Average(_ => _.Y); massVar.Contr = result; totalresult.Add(massVar); } } } } List <ContourWithMass> SortedList = totalresult.OrderByDescending(o => o.Mass.X).ToList(); var sortToX = SortDeterminationOfCentromass(SortedList); return(sortToX); }
/// <summary> /// Retrieves contours from the binary image and returns the number of retrieved contours. The pointer firstContour is filled by the function. It will contain pointer to the first most outer contour or IntPtr.Zero if no contours is detected (if the image is completely black). Other contours may be reached from firstContour using h_next and v_next links. The sample in cvDrawContours discussion shows how to use contours for connected component detection. Contours can be also used for shape analysis and object recognition - see squares.c in OpenCV sample directory /// The function modifies the source image content /// </summary> /// <param name="image">The source 8-bit single channel image. Non-zero pixels are treated as 1s, zero pixels remain 0s - that is image treated as binary. To get such a binary image from grayscale, one may use cvThreshold, cvAdaptiveThreshold or cvCanny. The function modifies the source image content</param> /// <param name="hierarchy">Optional output vector, containing information about the image topology.</param> /// <param name="mode">Retrieval mode</param> /// <param name="method">Approximation method (for all the modes, except CV_RETR_RUNS, which uses built-in approximation). </param> /// <returns>Detected contours. Each contour is stored as a vector of points.</returns> /// <remarks> /// http://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours /// C++: void findContours(InputOutputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset=Point()) /// C++: void findContours(InputOutputArray image, OutputArrayOfArrays contours, int mode, int method, Point offset = Point()) /// Python: cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]]) → contours, hierarchy /// C: int cvFindContours(CvArr* image, CvMemStorage* storage, CvSeq** first_contour, int header_size = sizeof(CvContour), int mode = CV_RETR_LIST, int method = CV_CHAIN_APPROX_SIMPLE, CvPoint offset = cvPoint(0, 0)) /// Python: cv.FindContours(image, storage, mode=CV_RETR_LIST, method=CV_CHAIN_APPROX_SIMPLE, offset=(0, 0)) → contours /// </remarks> public static VectorOfVectorOfPoint FindContours(IInputOutputArray src, Emgu.CV.CvEnum.RetrType mode = RetrType.List, ChainApproxMethod method = ChainApproxMethod.ChainApproxSimple) { VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint(); CvInvoke.FindContours(src, contours, null, mode, method); return(contours); }
static object[] FindContours(Bitmap img, [InField(PVal = 25)] float MinContourSize, [InField(PVal = 500)] float MaxContourSize, [InField(PVal = RetrType.List)] RetrType retrType, [InField(PVal = ChainApproxMethod.ChainApproxNone)] ChainApproxMethod cam, [InField(PVal = true)] bool DrawContours, out string time, out BitmapImage drawedCs) { var inp = new Image <Bgr, byte>(img); var onlyCont = new Image <Bgra, byte>(inp.Size); var inpGray = new Image <Gray, byte>(img); var conts = new VectorOfVectorOfPoint(); var now = DateTime.Now; CvInvoke.FindContours(inpGray, conts, null, retrType, cam); time = "Find Time: " + (DateTime.Now - now).TotalMilliseconds; List <VectorOfPoint> contsList = new List <VectorOfPoint>(); var cout = new List <VectorOfPoint>(); for (int i = 0; i < conts.Size; i++) { var con = conts[i]; var area = CvInvoke.ContourArea(con); if (con.Size > 2) { if (area >= MinContourSize && area < MaxContourSize) { contsList.Add(con); cout.Add(new VectorOfPoint(con.ToArray())); } } } now = DateTime.Now; var parts = new List <Bitmap>(); Bitmap[,] outpArr = null; var moments = new List <string>(); double[,] oArr = null; if (DrawContours) { for (int i = 0; i < contsList.Count; i++) { VectorOfPoint contour = contsList[i]; var convex = contour.ToArray();//CvInvoke.ConvexHull(contour.ToArray().Select(x => new PointF(x.X, x.Y)).ToArray()); var pnt = convex.Select(x => new System.Drawing.Point((int)x.X, (int)x.Y)).ToArray(); inp.Draw(pnt, new Bgr(0, 255, 0), 1); onlyCont.Draw(contour.ToArray(), new Bgra(255, 255, 255, 255), 1); } for (int i = 0; i < contsList.Count; i++) { VectorOfPoint contour = contsList[i]; var cx = contour.ToArray().Sum(x => x.X) / contour.Size; var cy = contour.ToArray().Sum(x => x.Y) / contour.Size; System.Drawing.Point center = new System.Drawing.Point(cx, cy); inp.Draw(string.Format("[{0}|{1}|{2}]", i, CvInvoke.ContourArea(contour), contour.Size), center, FontFace.HersheyPlain, 1, new Bgr(0, 0, 255), 1); } for (int i = 0; i < contsList.Count; i++) { VectorOfPoint contour = contsList[i]; var cArray = contour.ToArray(); var left = cArray.Min(x => x.X); var right = cArray.Max(x => x.X); var top = cArray.Min(x => x.Y); var bot = cArray.Max(x => x.Y); var width = right - left; var height = bot - top; int size = 500; Image <Bgr, byte> part = new Image <Bgr, byte>(new System.Drawing.Size(width > size ? width : size, height > size ? height : size)); for (int k = 0; k < cArray.Length; k++) { cArray[k].X -= left; cArray[k].Y -= top; } part.Draw(cArray, new Bgr(Color.White)); part.Draw(string.Format("[num: {0}; area: {1}; size: {2}]", i, CvInvoke.ContourArea(contour), contour.Size), new System.Drawing.Point(0, part.Height - 5), FontFace.HersheyPlain, 1, new Bgr(0, 0, 255), 1); MCvMoments cvmoments = CvInvoke.Moments(contour); var ncmoment = CvInvoke.cvGetNormalizedCentralMoment(ref cvmoments, 0, 0); var cmom = CvInvoke.cvGetCentralMoment(ref cvmoments, 0, 0); var smom = CvInvoke.cvGetSpatialMoment(ref cvmoments, 0, 0); moments.Add(string.Format("CM: {0} || NCM: {1} || SM: {2}", cmom, ncmoment, smom)); parts.Add(new Bitmap(part.Bitmap)); } } time = time + "|| Draw Time: " + (DateTime.Now - now).TotalMilliseconds + " Contours: " + contsList.Count; if (DrawContours) { drawedCs = B2BI(inp.Bitmap); } else { drawedCs = null; } return(new object[] { new Bitmap(inp.Bitmap), new Bitmap(onlyCont.Bitmap), parts.ToArray(), moments.ToArray(), cout.ToArray() }); }