ffilldemo.cpp 4.73 KB
Newer Older
1
#include "opencv2/imgproc.hpp"
2
#include "opencv2/imgcodecs.hpp"
3 4
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
5 6 7 8 9 10

#include <iostream>

using namespace cv;
using namespace std;

11
static void help()
Gary Bradski's avatar
Gary Bradski committed
12 13
{
    cout << "\nThis program demonstrated the floodFill() function\n"
14
            "Call:\n"
Dmitriy Anisimov's avatar
Dmitriy Anisimov committed
15
            "./ffilldemo [image_name -- Default: ../data/fruits.jpg]\n" << endl;
Gary Bradski's avatar
Gary Bradski committed
16

17 18 19 20 21 22 23 24 25 26
    cout << "Hot keys: \n"
            "\tESC - quit the program\n"
            "\tc - switch color/grayscale mode\n"
            "\tm - switch mask mode\n"
            "\tr - restore the original image\n"
            "\ts - use null-range floodfill\n"
            "\tf - use gradient floodfill with fixed(absolute) range\n"
            "\tg - use gradient floodfill with floating(relative) range\n"
            "\t4 - use 4-connectivity mode\n"
            "\t8 - use 8-connectivity mode\n" << endl;
Gary Bradski's avatar
Gary Bradski committed
27 28
}

29 30 31 32 33 34 35 36
Mat image0, image, gray, mask;
int ffillMode = 1;
int loDiff = 20, upDiff = 20;
int connectivity = 4;
int isColor = true;
bool useMask = false;
int newMaskVal = 255;

37
static void onMouse( int event, int x, int y, int, void* )
38
{
39
    if( event != EVENT_LBUTTONDOWN )
40 41 42 43 44 45
        return;

    Point seed = Point(x,y);
    int lo = ffillMode == 0 ? 0 : loDiff;
    int up = ffillMode == 0 ? 0 : upDiff;
    int flags = connectivity + (newMaskVal << 8) +
46
                (ffillMode == 1 ? FLOODFILL_FIXED_RANGE : 0);
47 48 49 50 51 52 53 54
    int b = (unsigned)theRNG() & 255;
    int g = (unsigned)theRNG() & 255;
    int r = (unsigned)theRNG() & 255;
    Rect ccomp;

    Scalar newVal = isColor ? Scalar(b, g, r) : Scalar(r*0.299 + g*0.587 + b*0.114);
    Mat dst = isColor ? image : gray;
    int area;
55

56 57
    if( useMask )
    {
58
        threshold(mask, mask, 1, 128, THRESH_BINARY);
59 60 61 62 63 64 65 66 67
        area = floodFill(dst, mask, seed, newVal, &ccomp, Scalar(lo, lo, lo),
                  Scalar(up, up, up), flags);
        imshow( "mask", mask );
    }
    else
    {
        area = floodFill(dst, seed, newVal, &ccomp, Scalar(lo, lo, lo),
                  Scalar(up, up, up), flags);
    }
68

69 70 71 72 73 74 75
    imshow("image", dst);
    cout << area << " pixels were repainted\n";
}


int main( int argc, char** argv )
{
ValeryTyumen's avatar
ValeryTyumen committed
76 77 78 79 80 81 82 83 84
    cv::CommandLineParser parser (argc, argv,
        "{help h | | show help message}{@image|../data/fruits.jpg| input image}"
    );
    if (parser.has("help"))
    {
        parser.printMessage();
        return 0;
    }
    string filename = parser.get<string>("@image");
85
    image0 = imread(filename, 1);
86

87 88
    if( image0.empty() )
    {
ValeryTyumen's avatar
ValeryTyumen committed
89 90
        cout << "Image empty\n";
        parser.printMessage();
91 92
        return 0;
    }
Gary Bradski's avatar
Gary Bradski committed
93
    help();
94
    image0.copyTo(image);
95
    cvtColor(image0, gray, COLOR_BGR2GRAY);
96 97 98 99 100 101 102 103 104 105 106 107
    mask.create(image0.rows+2, image0.cols+2, CV_8UC1);

    namedWindow( "image", 0 );
    createTrackbar( "lo_diff", "image", &loDiff, 255, 0 );
    createTrackbar( "up_diff", "image", &upDiff, 255, 0 );

    setMouseCallback( "image", onMouse, 0 );

    for(;;)
    {
        imshow("image", isColor ? image : gray);

108 109
        char c = (char)waitKey(0);
        if( c == 27 )
110 111
        {
            cout << "Exiting ...\n";
112 113
            break;
        }
114
        switch( c )
115
        {
116 117 118 119
        case 'c':
            if( isColor )
            {
                cout << "Grayscale mode is set\n";
120
                cvtColor(image0, gray, COLOR_BGR2GRAY);
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
                mask = Scalar::all(0);
                isColor = false;
            }
            else
            {
                cout << "Color mode is set\n";
                image0.copyTo(image);
                mask = Scalar::all(0);
                isColor = true;
            }
            break;
        case 'm':
            if( useMask )
            {
                destroyWindow( "mask" );
                useMask = false;
            }
            else
            {
                namedWindow( "mask", 0 );
                mask = Scalar::all(0);
                imshow("mask", mask);
                useMask = true;
            }
            break;
        case 'r':
            cout << "Original image is restored\n";
            image0.copyTo(image);
149
            cvtColor(image, gray, COLOR_BGR2GRAY);
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
            mask = Scalar::all(0);
            break;
        case 's':
            cout << "Simple floodfill mode is set\n";
            ffillMode = 0;
            break;
        case 'f':
            cout << "Fixed Range floodfill mode is set\n";
            ffillMode = 1;
            break;
        case 'g':
            cout << "Gradient (floating range) floodfill mode is set\n";
            ffillMode = 2;
            break;
        case '4':
            cout << "4-connectivity mode is set\n";
            connectivity = 4;
            break;
        case '8':
            cout << "8-connectivity mode is set\n";
            connectivity = 8;
            break;
        }
    }

    return 0;
}