Как определить площадь многоугольника в изображении

Если у меня есть выпуклые вершины многоугольника, то мои вычисления площади на изображении не будут точными по стандартной формуле.

(Для простоты), если у меня есть квадрат 3х3, а вершины (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 к ширине и высоте и получить правильную площадь. Но как насчет неправильных многоугольников на изображении?
Я надеюсь, что вопрос имеет смысл.

1

Решение

Если вы не хотите работать с углами пикселей как вершинами, рассмотрите следующий метод (работает для простых фигур — все выпуклые, некоторые вогнутые):

введите описание изображения здесь

Добавьте дополнительный фальшивый пиксель с правой стороны каждого правого пикселя, с нижней стороны каждого нижнего пикселя, с правой стороны нижнего правого нижнего углового пикселя. Здесь серые пиксели являются исходными, светло-голубые — поддельными.

1

Другие решения

Площадь может быть рассчитана в следующие шаги:

1) выборка пикселей между вершинами

2) сортировка пикселей по координатам х (или координаты у)

3) принимая разницу между минимальной и максимальной координатами (или х) для определенного х (или у) значение и добавление одного к разнице

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;
}
1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector