public static List <Contour <Point> > DetectContours(this Image <Gray, double> img, Emgu.CV.CvEnum.RETR_TYPE mode = Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, Emgu.CV.CvEnum.CHAIN_APPROX_METHOD method = Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE) { List <Contour <Point> > contoursDetected = new List <Contour <Point> >(); Contour <Point> firstContourDetected = img.FindContours(method, mode); Contour <Point> currContour = firstContourDetected; while (true) { contoursDetected.Add(currContour); currContour = currContour.HNext; if (currContour == null) { break; } } return(contoursDetected); //CvInvoke.FindContours(img, contoursDetected, null, mode, method); //List<VectorOfPoint> 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; }
private void ProcessFrame(Image <Bgr, byte> frame) { Image <Gray, byte> preprocessed = m_preprocessor.Preprocess(frame); Image <Bgr, byte> imageToDraw; if (m_showMode == ShowMode.Source) { imageToDraw = frame; } else // if (m_showMode == ShowMode.Preprocessed) { imageToDraw = preprocessed.Convert <Bgr, byte>(); } Emgu.CV.CvEnum.RETR_TYPE retrType = m_retriveOnlyExternalContours ? Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL : Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST; OCVContour ocvContours = preprocessed.FindContours( Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, retrType); // NOTE: To improove recognition system I can use whole groups of contours as individual glyph // In this case is necessary to check relative parameters, such as including or relative positioning //OCVContour ocvContours = preprocessed.FindContours( // Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE, // Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST); List <OCVContour> ocvFilteredContours = m_filter.Filter(ocvContours); // thread-safe access to m_lastFindedContours lock (m_sync) { m_lastFindedContours = new List <ContourAndMatchInfo>(); OpenCVContourConverter.ConvertMany( ocvFilteredContours, m_targetLen, (ocvContour, converted) => { lock (m_lastFindedContours) { m_lastFindedContours.Add(new ContourAndMatchInfo() { OCVContour = ocvContour, Contour = converted }); } }); if (m_showContours) { DrawContours(imageToDraw, ocvFilteredContours); } m_matcher.GetMatches( m_lastFindedContours, fullContourInfo => fullContourInfo.Contour, (cmInfo, match) => cmInfo.Match = match); foreach (ContourAndMatchInfo fcInfo in m_lastFindedContours) { if (fcInfo.Match == null) { continue; } Rectangle boundRect = fcInfo.OCVContour.BoundingRectangle; Graphics g = Graphics.FromImage(imageToDraw.Bitmap); if (m_showBounding) { g.DrawRectangle(Pens.Green, boundRect); } string text = fcInfo.Match.FamiliarContour.Description; if (m_showAngle) { text += string.Format(", {0:F0}°", fcInfo.Match.MaxNSP.ArgumentDegrees()); } if (m_showAccuracy) { text += string.Format(", {0:P1}", fcInfo.Match.MaxNSP.AbsoluteValue()); } g.DrawString(text, m_font, System.Drawing.Brushes.Red, new PointF(boundRect.Left, boundRect.Top - 13)); } } // Update UI Invoke(() => { StatTextBlock.Text = string.Format("{0}/{1} (recognized/finded)", m_lastFindedContours.Count(cInfo => cInfo.Match != null), ocvFilteredContours.Count); FPSTextBlock.Text = string.Format("{0:F1} FPS", m_fps); BitmapSource source = imageToDraw.ToBitmapSource(); if (m_capture != null || m_captureFromImage != false) { ImagePresenter.Source = source; } }); }