Алгоритм C ++ для заливки двоичного изображения - PullRequest
1 голос
/ 09 мая 2011

Я пытаюсь смоделировать функцию matlab "imfill" для заливки заливки двоичного изображения (2D-матрица из 1 и нулей).

Я хочу указать начальную точку в матрице и заливку какподойдет 4-х подключенная версия imfill.

Это уже существует где-то в мире C ++?Если нет, то какой будет наиболее эффективный способ реализовать это?

Ответы [ 4 ]

4 голосов
/ 09 мая 2011

Если вы хотите выполнять обработку изображений в C ++, вы должны взглянуть на OpenCV (Open Source Computer Vision).

Это отличная кроссплатформенная библиотека для изображений / видеообработка и она имеет то, что вы ищете.Проверьте этот вопрос:

Заполните отверстия в OpenCV

3 голосов
/ 10 мая 2011

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

Когда в прошлом я заполнял простые сетки, я просто использовал очередь STL для хранения списка точек, а затем работал с ними. Очередь начиналась с начальной точки, затем я проверял соседние точки. Если соседние точки необходимо включить в «поток», добавьте их в очередь. Вроде как это:

// using this data structure
struct Point {
  int x;
  int y;
};

// 
void fillGrid(Point orig, byte** grid, int width, int height) {
  std::queue<Point> q;
  q.push(orig);

  // the main flood loop
  while(!q.empty()) {
    Point pnt = q.front();
    q.pop();

    // grab adjacent points
    Point adj[4];
    adj[0].x = pnt.x;   adj[0].y = pnt.y-1;   // up
    adj[1].x = pnt.x+1; adj[1].y = pnt.y;     // right
    adj[2].x = pnt.x;   adj[2].y = pnt.y+1;   // down
    adj[3].x = pnt.x-1; adj[3].y = pnt.y;     // left

    for(int i = 0; i < 4; i++) {
      // don't forget boundaries!
      if(adj[i].x < 0 || adj[i].x >= width ||
         adj[i].y < 0 || adj[i].y >= height)
        continue;

      // if adjacent point meets some criteria, then set
      // its value and include it in the queue
      if(includePoint(adj[i], grid)) {
        setPoint(adj[i], grid);
        q.push(adj[i]);
      }
    }
  }
}
1 голос
/ 09 мая 2011

См. Примеры кода на на этой странице («QuickFill: эффективный алгоритм заливки»)

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

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

Наконец, он предлагает QuickFill, который для меня выглядит как оптимизированный вариант метода линии сканирования.

0 голосов
/ 25 апреля 2015

Библиотека Aforge имеет следующую функцию

AForge.Imaging.Filters.FillHoles(...)

Он делает то же самое, что imfill в Matlab.

...