【问题标题】:How to determine the area of a polygon in an Image如何确定图像中多边形的面积
【发布时间】:2015-01-25 21:42:01
【问题描述】:

如果我有一个凸多边形顶点,那么我在图像中的面积计算不是按照标准公式计算的。

(为了简单起见)如果我有 3x3 正方形,并且顶点是 (1,1) (1,3) (3,3) (3,1)

这里描述的多边形面积计算方法

将总和除以 2 得到面积。

所以对于上面的 3 x 3 数据,我们将得到面积为 4 而不是 9。

这是因为顶点不是点而是一个像素。

这是对应的代码。坐标是循环的。

int X[] = { 1, 1, 3, 3, 1};
int Y[] = { 1, 3, 3, 1, 1};
double Sum1 = 0;
double Sum2 = 0;
int numElements = 5;

    for (int k = 0; k < numElements-1; k++)
    {
        Sum1 += X[k] * Y[k + 1];
        Sum2 += Y[k] * X[k + 1];
    }

    double area = std::abs((double)(Sum1 - Sum2))/2;

对于正方形,我们可以对宽度和高度进行 +1 并获得正确的面积。但是图像中的不规则多边形呢? 我希望这个问题有意义。

【问题讨论】:

  • 常见问题:您尝试了什么?我建议你展示一些失败的代码,并猜测它失败的地方。
  • 我已经添加了代码。
  • 我完全不理解你假设的算法。最重要的是:您打算如何计算一般多边形的面积?进一步:图片与此有什么关系?你是怎么把图片转成代码的?
  • 您似乎对多边形表示感到困惑。提到的方法适用于由顶点坐标定义的多边形。但是您想通过瓦片集定义多边形并使用相同的公式...如果您找到多边形角的坐标并应用此方法,您将得到正确的结果。
  • 请注意,要获得具有倾斜边缘的图形的精确像素区域,您必须定义边框上的每个像素,因为不同的绘制方法可能会产生不同的结果

标签: c++ math image-processing polygon area


【解决方案1】:

面积可以按以下步骤计算:

1) 获取顶点之间的像素

2) 按x坐标(或y坐标)对像素进行排序

3) 取特定 x (或 y) 值的最小和最大 y 坐标 (或 x) 之间的差值,并将差值加一

4) 总差相加

注意:该区域可能会有所不同(如果多边形中有倾斜的边缘)取决于所选的线条绘制方法

int compare(const void * a, const void * b)
{
  return (((Point*)a)->x() - ((Point*)b)->x());
}


double CalculateConvexHullArea(vector<int> ConvexHullX, vector<int> ConvexHullY)
{
    float Sum1 = 0;
    float Sum2 = 0;
    std::vector<Point> FillPoints;


        for (int k = 0; k < ConvexHullX.size() - 1; k++)
        {
            drawLine(ConvexHullX[k], ConvexHullX[k+1], ConvexHullY[k], ConvexHullY[k+1], FillPoints);
        }

        //sorting coordinates
        qsort(FillPoints.data(), FillPoints.size(), sizeof(Point), compare);

        double area = 0;
        int startY = FillPoints[0].y(), endY = FillPoints[0].y();
        int currX = FillPoints[0].x();


        // traversing x and summing up diff of min and max Y
        for (int cnt = 0; cnt < FillPoints.size(); cnt++)
        {
            if (FillPoints[cnt].x() == currX)
            {
                startY = startY > FillPoints[cnt].y() ? FillPoints[cnt].y() : startY;
                endY = endY < FillPoints[cnt].y() ? FillPoints[cnt].y() : endY;
            }
            else
            {
                int diffY = endY - startY + 1;
                area += diffY;
                currX = FillPoints[cnt].x();
                startY = endY = FillPoints[cnt].y();
            }
        }

        return area + endY - startY + 1;
}

【讨论】:

    【解决方案2】:

    如果您不想将像素角用作顶点,请考虑下一种方法(适用于简单图形 - 所有凸形,一些凹形):

    在每个右边框像素的右侧、每个下边框像素的底部、右下角像素的右下角添加额外的假像素。这里的灰色像素是初始的浅蓝色像素 - 假的。

    【讨论】:

    • 如果我知道要伪造哪些像素,我会得到正确答案。你有阴影的那些不会给我正确的答案,这个图像是 5。
    猜你喜欢
    • 2013-11-22
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2012-04-07
    • 1970-01-01
    • 1970-01-01
    • 2020-01-24
    相关资源
    最近更新 更多