2014-11-27 4 views
1

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

(Для simiplicity), если я с 3x3 квадрат, а вершины (1,1) (1,3) (3,3) (3,1)

enter image description here

полигоном область метод расчета изображен здесь

enter image description here

и разделив суммирование 2 мы получаем Area.

Таким образом, для данных 3 х 3 выше, мы получим площадь в 4 вместо 9.

enter image description here

Это происходит потому, что вершины не являются точками, но пикселей.

это соответствующий код. Координаты являются циклическими.

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

+0

обычный вопрос : что вы пробовали? Я предлагаю вам показать какой-то код, который терпит неудачу, и дать понять, где он терпит неудачу. – davidhigh

+0

Я добавил код. –

+0

Я понимаю ваш предполагаемый алгоритм вовсе.Самое главное: как именно вы собираетесь рассчитать площадь общих полигонов? Далее: как картина связана с этим? Как вы преобразовали изображение в код? – davidhigh

ответ

1

Область может быть вычислена в следующих стадий:

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

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

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

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

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

enter image description here

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

+0

Я получу правильный ответ, если знаю, какие все пиксели подделать. Те, которые вы затенены, не дают мне правильного ответа, который равен 5 для этого изображения. –

Смежные вопросы