Regard
Regard

Reputation: 31

Converting contours found using EMGU.CV

I am new to EMGU.CV and I am struggling a bit. Let me start by giving some background of the project, i am trying to track a users fingers, i.e. calculate the users finger tips, but i am struggling a bit. I have created a set of code which filters the depth information to only a certain range and I generate a Bitmap image, tempBitmap, i then convert this image to a greyscale image using EMGU.CV which can be used by cvCanny. Once this is done i apply dilate filter to the canny image to thicken up the outline of the hand to better improve the chance of generating a successful contour, I then try to get the contours of the hand. Now what i have managed to do is to draw a box around the hand, but i am struggling to find a way to convert the contours generated by FindContours to a set of Points i can use to draw the contour with. the variable depthImage2 is a Bitmap image variable i use to draw on before assinging it to the picturebox variable on my C# form based application. any information or guidance you can provide me with will be greatly appreciated, also if my code isnt correct maybe guiding me in a direction where i can calculate the finger tips. I think i am almost there i am just missing something, so any help of any kind will be appreciated.

Image<Bgr, Byte> currentFrame = new Image<Bgr, Byte>(tempBitmap);

Image<Gray, Byte> grayImage = currentFrame.Convert<Gray, Byte>().PyrDown().PyrUp();
Image<Gray, Byte> cannyImage = new Image<Gray, Byte>(grayImage.Size);
CvInvoke.cvCanny(grayImage, cannyImage, 10, 60, 3);

StructuringElementEx kernel = new StructuringElementEx(
    3, 3, 1, 1, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_ELLIPSE);

CvInvoke.cvDilate(cannyImage, cannyImage, kernel, 1);

IntPtr cont = IntPtr.Zero;

Graphics graphicsBitmap = Graphics.FromImage(depthImage2);

using (MemStorage storage = new MemStorage()) //allocate storage for contour approximation
    for (Contour<Point> contours =
        cannyImage.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,                               
            Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL); 
                contours != null; contours = contours.HNext)
    {                                
        IntPtr seq = CvInvoke.cvConvexHull2(contours, storage.Ptr, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE, 0);
        IntPtr defects = CvInvoke.cvConvexityDefects(contours, seq, storage);
        Seq<Point> tr = contours.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

        Seq<Emgu.CV.Structure.MCvConvexityDefect> te = contours.GetConvexityDefacts(
            storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

        graphicsBitmap.DrawRectangle(
            new Pen(new SolidBrush(Color.Red)), tr.BoundingRectangle);
    }

Upvotes: 3

Views: 5963

Answers (1)

dajuric
dajuric

Reputation: 2507

Contour contours = cannyImage.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE) //to return all points

then:

List<Point[]> convertedContours = new List<Point[]>();
while(cotours!=null)
{
  var contourPoints = contours.ToArray(); //put Seq<Point> to Point[], ToList() is also available ?
  convertedContours.Add(contourpoints);

  contours = contours.HNext;
}

you can draw contour by image Draw functon overload. just find signature that contains parameter Seq<>

....

Upvotes: 1

Related Questions