mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
4.5 KiB
167 lines
4.5 KiB
#include "opencv2/imgproc/imgproc.hpp" |
|
#include "opencv2/imgcodecs.hpp" |
|
#include "opencv2/videoio/videoio.hpp" |
|
#include "opencv2/highgui/highgui.hpp" |
|
|
|
#include <iostream> |
|
|
|
using namespace cv; |
|
using namespace std; |
|
|
|
static void help() |
|
{ |
|
cout << "\nThis program demonstrated the floodFill() function\n" |
|
"Call:\n" |
|
"./ffilldemo [image_name -- Default: fruits.jpg]\n" << endl; |
|
|
|
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; |
|
} |
|
|
|
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; |
|
|
|
static void onMouse( int event, int x, int y, int, void* ) |
|
{ |
|
if( event != EVENT_LBUTTONDOWN ) |
|
return; |
|
|
|
Point seed = Point(x,y); |
|
int lo = ffillMode == 0 ? 0 : loDiff; |
|
int up = ffillMode == 0 ? 0 : upDiff; |
|
int flags = connectivity + (newMaskVal << 8) + |
|
(ffillMode == 1 ? FLOODFILL_FIXED_RANGE : 0); |
|
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; |
|
|
|
if( useMask ) |
|
{ |
|
threshold(mask, mask, 1, 128, THRESH_BINARY); |
|
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); |
|
} |
|
|
|
imshow("image", dst); |
|
cout << area << " pixels were repainted\n"; |
|
} |
|
|
|
|
|
int main( int argc, char** argv ) |
|
{ |
|
char* filename = argc >= 2 ? argv[1] : (char*)"fruits.jpg"; |
|
image0 = imread(filename, 1); |
|
|
|
if( image0.empty() ) |
|
{ |
|
cout << "Image empty. Usage: ffilldemo <image_name>\n"; |
|
return 0; |
|
} |
|
help(); |
|
image0.copyTo(image); |
|
cvtColor(image0, gray, COLOR_BGR2GRAY); |
|
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); |
|
|
|
int c = waitKey(0); |
|
if( (c & 255) == 27 ) |
|
{ |
|
cout << "Exiting ...\n"; |
|
break; |
|
} |
|
switch( (char)c ) |
|
{ |
|
case 'c': |
|
if( isColor ) |
|
{ |
|
cout << "Grayscale mode is set\n"; |
|
cvtColor(image0, gray, COLOR_BGR2GRAY); |
|
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); |
|
cvtColor(image, gray, COLOR_BGR2GRAY); |
|
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; |
|
}
|
|
|