Monday, 20 November 2017

Contour Identification of an Image using C# and EmguCV

/// <summary>
   /// Main form to interact with EmguCV for contour processing.
   /// </summary>
   public partial class frmContours : Form
   {
       Emgu.CV.Capture c;
       FindContours processor = new FindContours();
       Bitmap colorImage;

       /// <summary>
       /// Initializes the initial tracker value to th tracker label.
       /// </summary>
       public frmContours()
       {
           InitializeComponent();
           lblThresholdValue.Text = trackbarThreshold.Value.ToString();
       }

       /// <summary>
       /// Updates the threshold label when the tracker changes.
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       private void trackbarThreshold_Scroll(object sender, EventArgs e)
       {
           lblThresholdValue.Text = trackbarThreshold.Value.ToString();
       }

       /// <summary>
       /// Starts the camera capture.
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       private void btnCapture_Click(object sender, EventArgs e)
       {
           if (c == null)
           {
               c = new Emgu.CV.Capture();
           }
           CameraStreamCapture.Enabled = true;

       }

       /// <summary>
       /// Stops the Camera capture.
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       private void btnStopCapture_Click(object sender, EventArgs e)
       {
           CameraStreamCapture.Enabled = false;
           if (c != null)
           {
               c.Dispose();
               c = null;
           }

       }
       /// <summary>
       /// Start capturing from the camera stream.
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       private void CameraStreamCapture_Tick(object sender, EventArgs e)
       {
           colorImage = c.QueryFrame().ToBitmap();
           Bitmap color;
           Bitmap gray;
           processor.IdentifyContours(colorImage, trackbarThreshold.Value, chkBoxInvert.Checked, out gray, out color);
           pictBoxColor.Image = color;
           pictBoxGray.Image = gray;
       }

       /// <summary>
       /// Stop the camera and release resources when the form is closing
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
       private void frmContours_FormClosing(object sender, FormClosingEventArgs e)
       {
           CameraStreamCapture.Enabled = false;
           c = null;
       }
   }

/// <summary>
   /// Class responsible for extracting out the contours of an image.
   /// </summary>
   class FindContours
   {
       /// <summary>
       /// Method used to process the image and set the output result images.
       /// </summary>
       /// <param name="colorImage">Source color image.</param>
       /// <param name="thresholdValue">Value used for thresholding.</param>
       /// <param name="processedGray">Resulting gray image.</param>
       /// <param name="processedColor">Resulting color image.</param>
       public void IdentifyContours(Bitmap colorImage,int thresholdValue,bool invert,out Bitmap processedGray,out Bitmap processedColor)
       {

           #region Conversion To grayscale
           Image<Gray, byte> grayImage = new Image<Gray, byte>(colorImage);
           Image<Bgr, byte> color = new Image<Bgr, byte>(colorImage);
           
           #endregion
           

           #region  Image normalization and inversion (if required)
           grayImage = grayImage.ThresholdBinary(new Gray(thresholdValue), new Gray(255));
           if (invert)
           {
               grayImage._Not();
           } 
           #endregion
           
           #region Extracting the Contours
           using (MemStorage storage = new MemStorage())
           {

               for (Contour<Point> contours = grayImage.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, storage); contours != null; contours = contours.HNext)
               {

                   Contour<Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.015, storage);
                   if (currentContour.BoundingRectangle.Width > 20)
                   {
                       CvInvoke.cvDrawContours(color, contours, new MCvScalar(255), new MCvScalar(255), -1, 2, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, new Point(0, 0));
                       color.Draw(currentContour.BoundingRectangle, new Bgr(0, 255, 0), 1);
                   }
               }

           }
           #endregion
           

           #region Asigning output
           processedColor = color.ToBitmap();
           processedGray = grayImage.ToBitmap();
           #endregion
       }
   }

No comments:

Post a Comment