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
help()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
onMouse(int event,int x,int y,int,void *)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
main(int argc,char ** argv)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