demo运行效果
源码:
#include "opencv2/imgproc.hpp" #include "opencv2/imgcodecs.hpp" #include "opencv2/videoio.hpp" #include "opencv2/highgui.hpp" #includeusing namespace cv; using namespace std; //漫水填充 static void help(char** argv) { cout << "nThis program demonstrated the floodFill() functionn" "Call:n" << argv[0] << " [image_name -- Default: fruits.jpg]n" << endl; cout << "Hot keys: n" "tESC - quit the programn" "tc - switch color/grayscale moden" "tm - switch mask moden" "tr - restore the original imagen" "ts - use null-range floodfilln" "tf - use gradient floodfill with fixed(absolute) rangen" "tg - use gradient floodfill with floating(relative) rangen" "t4 - use 4-connectivity moden" "t8 - use 8-connectivity moden" << 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);// ffillMode ???? newMaskVal ???? ???? connectivity ???? ???? 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 repaintedn"; } int main(int argc, char** argv) { cv::CommandLineParser parser(argc, argv, "{help h | | show help message}{@image|fruits.jpg| input image}" ); if (parser.has("help")) { parser.printMessage(); return 0; } string filename = parser.get ("@image"); image0 = imread(samples::findFile(filename), 1);//源图像 if (image0.empty()) { cout << "Image emptyn"; parser.printMessage(); return 0; } help(argv); 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);//源图像的备份或者灰度图 char c = (char)waitKey(0); if (c == 27) { cout << "Exiting ...n"; break; } switch (c) { case 'c': if (isColor)//切换彩色、灰度图。重置 { cout << "Grayscale mode is setn"; cvtColor(image0, gray, COLOR_BGR2GRAY); mask = Scalar::all(0); isColor = false; } else { cout << "Color mode is setn"; 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 restoredn"; image0.copyTo(image);//重置image cvtColor(image, gray, COLOR_BGR2GRAY);//重置gray mask = Scalar::all(0); break; case 's'://简单漫水填充 cout << "Simple floodfill mode is setn";//1个像素的填充 ffillMode = 0; break; case 'f'://固定范围漫水填充 cout << "Fixed Range floodfill mode is setn"; ffillMode = 1; break; case 'g'://梯度 填充 cout << "Gradient (floating range) floodfill mode is setn"; ffillMode = 2; break; case '4'://连通性4 cout << "4-connectivity mode is setn"; connectivity = 4; break; case '8'://连通性8 cout << "8-connectivity mode is setn"; connectivity = 8; break; } } return 0; }
笔记-漫水填充函数:floodFill
CV_EXPORTS_W int floodFill( InputOutputArray image, InputOutputArray mask,
Point seedPoint, Scalar newVal, CV_OUT Rect* rect=0,
Scalar loDiff = Scalar(), Scalar upDiff = Scalar(),
int flags = 4 );



