Flood fill

The flood fill operation fills the connected components with a given color. Starting from a seed point, the neighboring pixels are colored with a uniform color. The neighboring pixels can be within a specified range of the current pixel. The flood fill function is int floodFill(InputOutputArray image, Point seedPoint, Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(),int flags=4). The parameters loDiff and upDiff represent the range to check for every neighboring pixel (note that 3-channel difference thresholds can be specified). The parameter newVal is the color to apply to the pixels that are in range. The lower part of the parameter flags contains the pixel's connectivity value to use (4 or 8). The upper part defines the mode of the operation.

Depending on this mode, the flood fill function will color a neighboring pixel in the input image if it is within the specified range (given by loDiff and upDiff) of either the current pixel or if the neighboring pixel is within the specified range of the original seed's value. The function can also be called with a mask image as the second parameter. If specified, the flood-filling operation will not go across non-zero pixels in the mask. Note that the mask should be a single-channel 8-bit image that is 2 pixels wider and 2 pixels taller than the input image.

The upper bit of flags can be 0 or a combination of the following:

  • FLOODFILL_FIXED_RANGE: If set, the difference between the current pixel and seed pixel is considered. Otherwise, the difference between neighbor pixels is considered.
  • FLOODFILL_MASK_ONLY: If set, the function does not change the image (newVal is ignored) but fills the mask.

In OpenCV's flood fill example ([opencv_source_code]/samples/cpp/ffilldemo.cpp), the mask is used only as an output parameter. In our floodFill example, shown as the following code, we will use it as an input parameter in order to constrain the filling. The idea is to use the output of an edge detector as a mask. This should stop the filling process at the edges:

#include "opencv2/opencv.hpp"
#include <iostream>

using namespace std;
using namespace cv;

Mat image, image1, image_orig;
int loDiff = 20, upDiff = 30;
int loCanny=10, upCanny=150;

void onMouse( int event, int x, int y, int, void* )
{
    if( event != CV_EVENT_LBUTTONDOWN ) return;

    Point seed = Point(x,y);
    int flags = 4 + CV_FLOODFILL_FIXED_RANGE;
    int b = (unsigned)theRNG() & 255;
    int g = (unsigned)theRNG() & 255;
    int r = (unsigned)theRNG() & 255;
    Rect ccomp;

    Scalar newVal = Scalar(b, g, r);
    Mat dst = image;

    // flood fill
    floodFill(dst, seed, newVal, &ccomp, Scalar(loDiff, loDiff, loDiff), Scalar(upDiff, upDiff, upDiff), flags);
    imshow("image", dst);

    // Using Canny edges as mask
    Mat mask;
    Canny(image_orig, mask, loCanny, upCanny);
    imshow("Canny edges", mask);
    copyMakeBorder(mask, mask, 1, 1, 1, 1, cv::BORDER_REPLICATE);
    Mat dst1 = image1;
    floodFill(dst1, mask, seed, newVal, &ccomp, Scalar(loDiff, loDiff, loDiff), Scalar(upDiff, upDiff, upDiff), flags);
    imshow("FF with Canny", dst1);

    moveWindow("Canny edges", image.cols,0);
    moveWindow("FF with Canny", 2*image.cols,0);
}

int main(int argc, char *argv[])
{
    // Read original image and clone it to contain results
    image = imread("lena.jpg", CV_LOAD_IMAGE_COLOR );
    image_orig=image.clone();
    image1=image.clone();

    namedWindow( "image", WINDOW_AUTOSIZE );

    imshow("image", image);
    createTrackbar( "lo_diff", "image", &loDiff, 255, 0 );
    createTrackbar( "up_diff", "image", &upDiff, 255, 0 );
    createTrackbar( "lo_Canny", "image", &loCanny, 255, 0 );
    createTrackbar( "up_Canny", "image", &upCanny, 255, 0 );
    setMouseCallback( "image", onMouse, 0 );

    moveWindow("image", 0,0);

    cout << "Press any key to exit...
";
    waitKey(); // Wait for key press
    return 0;
}

The preceding example reads and displays a color image and then creates four trackbars. The first two trackbars control loDiff and upDiffvalues for the floodFill function. The other two trackbars control the lower and upper threshold parameters for the Canny edge detector. In this example, the user can click anywhere on the input image. The click position will be used as a seed point to perform a flood fill operation. Actually, upon each click, two calls are made to the floodFill function. The first one simply fills a region using a random color. The second one uses a mask created from the output of the Canny edge detector. Note that the copyMakeBorder function is necessary to form a 1-pixel wide border around the mask. The following screenshot shows the output of this example:

Flood fill

Output of the floodFill example

Note that the output that uses Canny edges (right) has filled in less pixels than the standard operation (left).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset