Найти самый большой многоугольник, как он завершен - PullRequest
2 голосов
/ 09 января 2012

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

У меня есть небольшое (максимум 50x50 пикселей) растровое изображение размером 1 бит / пиксель (черно-белое изображение).
За один раз добавляется только один пиксель.
Найдите самый большой (по площади) полигон, который использует черные пиксели в качестве краев.

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

Желаемое поведение

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

Ответы [ 3 ]

1 голос
/ 09 января 2012

Похоже, вам нужен какой-то алгоритм заливки , см. Связанные вопросы StackOverflow:

Алгоритмы заливки

Вы можетеиспользуйте заливку как способ выполнения сегментации, то есть разделите изображение на отдельные «объекты», состоящие из соединенных пикселей.Заливка заливки также даст вам количество пикселей в каждом объекте, позволяющее найти самый большой.См. Также страницу Википедии по сегментации, в частности метод выращивания регионов:

http://en.wikipedia.org/wiki/Segmentation_(image_processing)#Region-growing_methods

0 голосов
/ 14 января 2012

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

У меня нет доступа к тому, как я это сделал прямо сейчас, но это общая идея.

Каждый пиксель хранится в виде экземпляра SomePixelType.
Существует стек пикселей, который называется visitPixels.Пиксель считается возможным ребром многоугольника, если:

  • Он имеет от 2 до 7 (оба включительно) черных соседних пикселей.
  • Он отсутствует в коллекции посещенных пикселей.

SomePixelType имеет метод с именем GetNextPixel.

Когда вызывается GetNextPixel, он ищет соседние пиксели (начиная прямо вверх и по часовой стрелке) для возможного ребра многоугольника и возвращает его.Повторный вызов продолжит поиск с последнего матча.Как только все соседние пиксели будут проверены, он вернет ноль.

Когда пиксель установлен, этот метод будет вызван.

public Stack<SomePixelType> GetPolygonEdges(SomePixelType justSetPixel)
{
    visitedPixels.Clear();

    if(!justSetPixel.IsPossiblePolygon)
        return null; // Not a possible edge. No closed polygon could of been completed.

    visitedPixels.Push(justSetPixel);

    SomePixelType currentPixel = justSetPixel;
    while(visitedPixels.Count > 0)
    {
        currentPixel  = currentPixel.GetNextPixel();
        if(currentPixel == null) // No possible neighbouring polygon edges.
        {
            currentPixel = visitedPixels.Pop(); // Backtrack
            continue;
        }
        if(currentPixel == justSetPixel)
            return visitedPixels;

        visitedPixels.Push(currentPixel);
    }
    return null; // Not closed.
}

С этого момента его довольно легко заполнить. Каквопрос был о поиске многоугольника, на этом я остановлюсь.

0 голосов
/ 09 января 2012

Имейте в виду, что вам нужно убедиться, что полигон "замкнут".Должен быть алгоритм под названием «змея», который поможет вам, но я слышал об этом 14 лет назад, лучше поискать ...

...