【问题标题】:Calculate pixels within a polygon计算多边形内的像素
【发布时间】:2010-05-05 08:47:53
【问题描述】:

在学校的作业中,我们是否需要做一些图像识别,我们必须为机器人找到路径。

到目前为止,我们已经能够找到图像中的所有多边形,但是现在我们需要生成一个像素图,以便稍后用于 astar 算法。我们已经找到了一种方法,如下所示,但问题是它非常慢,因为我们遍历每个像素并测试它是否在多边形内。所以我的问题是,有没有一种方法可以更快地生成这个像素图?

我们有一个多边形坐标列表

private List<IntPoint> hull;

调用getMap函数获取像素图

public Point[] getMap()
{
    List<Point> points = new List<Point>();
    lock (hull)
    {
        Rectangle rect = getRectangle();
        for (int x = rect.X; x <= rect.X + rect.Width; x++)
        {
            for (int y = rect.Y; y <= rect.Y + rect.Height; y++)
            {
                if (inPoly(x, y))
                    points.Add(new Point(x, y));
            }
        }
    }
    return points.ToArray();
}

Get Rectangle 用于限制搜索,因此我们不必遍历整个图像

public Rectangle getRectangle()
{
    int x = -1, y = -1, width = -1, height = -1;
    foreach (IntPoint item in hull)
    {
        if (item.X < x || x == -1)
            x = item.X;
        if (item.Y < y || y == -1)
            y = item.Y;


        if (item.X > width || width == -1)
            width = item.X;
        if (item.Y > height || height == -1)
            height = item.Y;


    }
    return new Rectangle(x, y, width-x, height-y);
}

这就是我们检查像素是否在多边形内的方式

public bool inPoly(int x, int y)
{
    int i, j = hull.Count - 1;
    bool oddNodes = false;

    for (i = 0; i < hull.Count; i++)
    {
        if (hull[i].Y < y && hull[j].Y >= y
        || hull[j].Y < y && hull[i].Y >= y)
        {
            try
            {
                if (hull[i].X + (y - hull[i].X) / (hull[j].X - hull[i].X) * (hull[j].X - hull[i].X) < x)
                {
                    oddNodes = !oddNodes;
                }
            }
            catch (DivideByZeroException e)
            {
                if (0 < x)
                {
                    oddNodes = !oddNodes;
                }
            }
        }
        j = i;
    }
    return oddNodes;
}

【问题讨论】:

    标签: c# polygon pixel point-in-polygon


    【解决方案1】:

    有一些关于多边形命中测试的有趣讨论 here,但在我看来,如果使用多边形填充可能会更好。

    【讨论】:

      【解决方案2】:

      您可能想要寻找Plygon Triangulation 算法。

      另外,请注意,捕获异常比检查正确的条件要耗时得多。所以我建议您将现有代码转换为:

         public bool inPoly(int x, int y)
          {
              int i, j = hull.Count - 1;
              var oddNodes = false;
      
              for (i = 0; i < hull.Count; i++)
              {
                  if (hull[i].Y < y && hull[j].Y >= y
                      || hull[j].Y < y && hull[i].Y >= y)
                  {
                      var delta = (hull[j].X - hull[i].X);
                      if (delta == 0)
                      {
                          if (0 < x) oddNodes = !oddNodes;
                      }
                      else if (hull[i].X + (y - hull[i].X) / delta * delta < x)
                      {
                          oddNodes = !oddNodes;
                      }
      
                  }
                  j = i;
              }
              return oddNodes;
          }
      

      【讨论】:

      • 感谢您的回答。它是否适用于所有多边形形状?
      猜你喜欢
      • 1970-01-01
      • 2013-07-02
      • 1970-01-01
      • 1970-01-01
      • 2015-09-06
      • 2018-02-15
      • 1970-01-01
      • 1970-01-01
      • 2020-01-24
      相关资源
      最近更新 更多