C++ algorithm for flood filling a binary image

青春壹個敷衍的年華 提交于 2020-01-15 11:08:29

问题


I am trying to simulate a matlab function "imfill" for flood filling a binary image (2D matrix of 1's and zeros).

I want to specify a starting point in the matrix, and flood fill like a 4 connected version of imfill would do.

Does this already exist out there somewhere in the C++ world? If not, what would be the most efficient way to implement this?


回答1:


If your images are just 2D arrays of 1s and 0s, then I don't think you need an actual graphics library.

When I've filled in simple grids in the past, I just used the STL queue to store a list of points, and then worked through those. The queue would start with the initial point, then I'd test the adjacent points. If the adjacent points need to be included in the 'flood', then add those to the queue. Kind of like this:

// 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]);
      }
    }
  }
}



回答2:


If you want to do image processing in C++, you must take a look into OpenCV (Open Source Computer Vision).

It's a great cross-platform library for image/video processing and it has what you are looking for. Check this question:

Fill the holes in OpenCV




回答3:


See the code examples on this page ('QuickFill: An efficient flood fill algorithm')

In the first few code examples, a pixel is checked whether has the the fill (or border) color and the function calls itself recursively for all four (or eight) neighbouring pixels (actually, I claim that the first few examples are slightly wrong because the first recursive call should rather be a call to a function setting the new pixel instead of calling the function itself again with the very same parameters).

The next few examples describe the a recursive scan line method, which first fills a (horizontal) line as far as possible before going to adjacent lines (the line above and below), thus visiting each pixel less often.

Finally, it proposes QuickFill which to me looks like an optimized variant of the scan line method.




回答4:


Aforge Library has the following function

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

It does the same thing as imfill in Matlab.



来源:https://stackoverflow.com/questions/5941471/c-algorithm-for-flood-filling-a-binary-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!