Home | History | Annotate | Download | only in cpp
      1 #include "opencv2/imgproc/imgproc.hpp"
      2 #include "opencv2/imgcodecs.hpp"
      3 #include "opencv2/videoio/videoio.hpp"
      4 #include "opencv2/highgui/highgui.hpp"
      5 
      6 #include <iostream>
      7 
      8 using namespace cv;
      9 using namespace std;
     10 
     11 static void help()
     12 {
     13     cout << "\nThis program demonstrated the floodFill() function\n"
     14             "Call:\n"
     15             "./ffilldemo [image_name -- Default: ../data/fruits.jpg]\n" << endl;
     16 
     17     cout << "Hot keys: \n"
     18             "\tESC - quit the program\n"
     19             "\tc - switch color/grayscale mode\n"
     20             "\tm - switch mask mode\n"
     21             "\tr - restore the original image\n"
     22             "\ts - use null-range floodfill\n"
     23             "\tf - use gradient floodfill with fixed(absolute) range\n"
     24             "\tg - use gradient floodfill with floating(relative) range\n"
     25             "\t4 - use 4-connectivity mode\n"
     26             "\t8 - use 8-connectivity mode\n" << endl;
     27 }
     28 
     29 Mat image0, image, gray, mask;
     30 int ffillMode = 1;
     31 int loDiff = 20, upDiff = 20;
     32 int connectivity = 4;
     33 int isColor = true;
     34 bool useMask = false;
     35 int newMaskVal = 255;
     36 
     37 static void onMouse( int event, int x, int y, int, void* )
     38 {
     39     if( event != EVENT_LBUTTONDOWN )
     40         return;
     41 
     42     Point seed = Point(x,y);
     43     int lo = ffillMode == 0 ? 0 : loDiff;
     44     int up = ffillMode == 0 ? 0 : upDiff;
     45     int flags = connectivity + (newMaskVal << 8) +
     46                 (ffillMode == 1 ? FLOODFILL_FIXED_RANGE : 0);
     47     int b = (unsigned)theRNG() & 255;
     48     int g = (unsigned)theRNG() & 255;
     49     int r = (unsigned)theRNG() & 255;
     50     Rect ccomp;
     51 
     52     Scalar newVal = isColor ? Scalar(b, g, r) : Scalar(r*0.299 + g*0.587 + b*0.114);
     53     Mat dst = isColor ? image : gray;
     54     int area;
     55 
     56     if( useMask )
     57     {
     58         threshold(mask, mask, 1, 128, THRESH_BINARY);
     59         area = floodFill(dst, mask, seed, newVal, &ccomp, Scalar(lo, lo, lo),
     60                   Scalar(up, up, up), flags);
     61         imshow( "mask", mask );
     62     }
     63     else
     64     {
     65         area = floodFill(dst, seed, newVal, &ccomp, Scalar(lo, lo, lo),
     66                   Scalar(up, up, up), flags);
     67     }
     68 
     69     imshow("image", dst);
     70     cout << area << " pixels were repainted\n";
     71 }
     72 
     73 
     74 int main( int argc, char** argv )
     75 {
     76     char* filename = argc >= 2 ? argv[1] : (char*)"../data/fruits.jpg";
     77     image0 = imread(filename, 1);
     78 
     79     if( image0.empty() )
     80     {
     81         cout << "Image empty. Usage: ffilldemo <image_name>\n";
     82         return 0;
     83     }
     84     help();
     85     image0.copyTo(image);
     86     cvtColor(image0, gray, COLOR_BGR2GRAY);
     87     mask.create(image0.rows+2, image0.cols+2, CV_8UC1);
     88 
     89     namedWindow( "image", 0 );
     90     createTrackbar( "lo_diff", "image", &loDiff, 255, 0 );
     91     createTrackbar( "up_diff", "image", &upDiff, 255, 0 );
     92 
     93     setMouseCallback( "image", onMouse, 0 );
     94 
     95     for(;;)
     96     {
     97         imshow("image", isColor ? image : gray);
     98 
     99         int c = waitKey(0);
    100         if( (c & 255) == 27 )
    101         {
    102             cout << "Exiting ...\n";
    103             break;
    104         }
    105         switch( (char)c )
    106         {
    107         case 'c':
    108             if( isColor )
    109             {
    110                 cout << "Grayscale mode is set\n";
    111                 cvtColor(image0, gray, COLOR_BGR2GRAY);
    112                 mask = Scalar::all(0);
    113                 isColor = false;
    114             }
    115             else
    116             {
    117                 cout << "Color mode is set\n";
    118                 image0.copyTo(image);
    119                 mask = Scalar::all(0);
    120                 isColor = true;
    121             }
    122             break;
    123         case 'm':
    124             if( useMask )
    125             {
    126                 destroyWindow( "mask" );
    127                 useMask = false;
    128             }
    129             else
    130             {
    131                 namedWindow( "mask", 0 );
    132                 mask = Scalar::all(0);
    133                 imshow("mask", mask);
    134                 useMask = true;
    135             }
    136             break;
    137         case 'r':
    138             cout << "Original image is restored\n";
    139             image0.copyTo(image);
    140             cvtColor(image, gray, COLOR_BGR2GRAY);
    141             mask = Scalar::all(0);
    142             break;
    143         case 's':
    144             cout << "Simple floodfill mode is set\n";
    145             ffillMode = 0;
    146             break;
    147         case 'f':
    148             cout << "Fixed Range floodfill mode is set\n";
    149             ffillMode = 1;
    150             break;
    151         case 'g':
    152             cout << "Gradient (floating range) floodfill mode is set\n";
    153             ffillMode = 2;
    154             break;
    155         case '4':
    156             cout << "4-connectivity mode is set\n";
    157             connectivity = 4;
    158             break;
    159         case '8':
    160             cout << "8-connectivity mode is set\n";
    161             connectivity = 8;
    162             break;
    163         }
    164     }
    165 
    166     return 0;
    167 }
    168