使用Emgu和Kinect进行圆检测

时间:2014-06-15 19:29:52

标签: c# geometry shape emgucv

我最近开始用C#编程,用于我的学习。现在我正潜入Kinect的世界,我对所有可能性感到震惊。

目前我尝试开发一种能够检测简单形状的程序。到目前为止,我的程序工作正在检测基本形状,如三角形或矩形。

但现在我偶然发现了检测圆圈的问题。这里看到的教程代码对我的解决方案不起作用。

Stopwatch watch = Stopwatch.StartNew();
double cannyThreshold = 180.0;
double circleAccumulatorThreshold = 120;

CircleF[] circles = gray.HoughCircles(
    new Gray(cannyThreshold),
    new Gray(circleAccumulatorThreshold),
    2.0,  // Resolution of the accumulator used to detect centers of the circles
    20.0, // min distance 
    5,    // min radius
    0     // max radius
    )[0]; // Get the circles from the first channel

watch.Stop();
msgBuilder.Append(String.Format("Hough circles - {0} ms; ", watch.ElapsedMilliseconds));

我找不到原因,我没有得到错误也没有调试帮助我(请记住我是初学者)。我使用帮助器类来确保EMGU与WPF-Image-Toolbox一起工作正常并且如上所述:三角形和矩形起作用。

对于我的代码:我尝试检测某个深度区域的形状。为了我看一个"切片"深度范围并应用以下代码:

if(depthFrame != null)
{   
    depthSlice = depthFrame.SliceDepthImage(minVal, maxVal);
    Image<Bgr, Byte> sliced_img = new Image<Bgr, byte>(depthSlice.ToBitmap());
    Image<Gray, byte> buffer_img = sliced_img.Convert<Gray, byte>();

    List<Triangle2DF> triangleList = new List<Triangle2DF>();
    List<MCvBox2D> boxList = new List<MCvBox2D>();

    double cannyThreshold = 180.0;
    double circleAccumulatorThreshold = 120;

    CircleF[] circles = buffer_img.HoughCircles(
      new Gray(cannyThreshold),
      new Gray(circleAccumulatorThreshold),
      2.0,  // Resolution of the accumulator used to detect centers of the circles
      20.0, // min distance 
      5,    // min radius
      0     // max radius
      )[0]; // Get the circles from the first channel

    using(MemStorage storage = new MemStorage())
    {
        Contour<System.Drawing.Point> blobContours = buffer_img.FindContours(CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, RETR_TYPE.CV_RETR_EXTERNAL, storage);

        for(int i = 0; blobContours != null; blobContours = blobContours.HNext)
        {
           Contour<System.Drawing.Point> currentContours = blobContours.ApproxPoly(blobContours.Perimeter * 0.05, storage);

           if(currentContours.Area > 200)
           {
              if (currentContours.Total == 3)
              {
                 System.Drawing.Point[] pts = currentContours.ToArray();
                 triangleList.Add(new Triangle2DF(pts[0], pts[1], pts[2]));
              }
              else if(currentContours.Total == 4)
              {
                 bool isRect = true;
                 System.Drawing.Point[] pts = currentContours.ToArray();
                 LineSegment2D[] edges = Emgu.CV.PointCollection.PolyLine(pts, true);

                 for (int a = 0; a < edges.Length; a++)
                 {
                     double angle = Math.Abs(
                     edges[(a + 1) % edges.Length].GetExteriorAngleDegree(edges[a]));

                     if (angle < 80 || angle > 100)
                     {
                        isRect = false;
                        break;
                     }
                  }

                  if (isRect) 
                     boxList.Add(currentContours.GetMinAreaRect());
               }
            }

             /*  if(blobContours.Area > 4000) // Generic Blob Detection
              *  {
              *      MCvBox2D contour_rectangle = blobContours.GetMinAreaRect();
              *      sliced_img.Draw(contour_rectangle, new Bgr(0, 255, 0), 4);
              *      blobCount++;
              *  }
              */
     }
}

foreach(Triangle2DF triangle in triangleList)
{
   sliced_img.Draw(triangle, new Bgr(0, 0, 255), 4);
}

foreach (MCvBox2D box in boxList)
{
   sliced_img.Draw(box, new Bgr(0, 255, 0), 4);
}

foreach (CircleF circle in circles)
{
   sliced_img.Draw(circle, new Bgr(255, 0, 0), 8);
   Console.WriteLine(circle.Center);
}

outImg2.Source = ImageHelpers.ToBitmapSource(sliced_img);

我做错了吗?或者我错过了什么? 问候,并提前感谢:)

0 个答案:

没有答案