问题
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