【OpenCV】使用floodfill()实现PhotoShop魔棒功能
使用给定颜色填充一个联通的区域
C++: int floodFill(InputOutputArray image, Point seedPoint,
Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(),
Scalar upDiff=Scalar(), int flags=4 )
一个简单的例子:
#include “opencv2/imgproc/imgproc.hpp”
#include “opencv2/highgui/highgui.hpp”
#include
using namespace cv;
using namespace std;
//floodfill()
//Fills a connected component with the given color.
static void help()
{
cout << "nThis program demonstrated the floodFill() functionn"
“Call:n”
“./ffilldemo [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 != CV_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 ? CV_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, CV_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( )
{
char* filename=”0.png”;
image0 = imread(filename, 1);
if( image0.empty() )
{
cout << "Image empty. Usage: ffilldemo
return 0;
}
help();
image0.copyTo(image);
cvtColor(image0, gray, CV_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 setn";
cvtColor(image0, gray, CV_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);
cvtColor(image, gray, CV_BGR2GRAY);
mask = Scalar::all(0);
break;
case ‘s’:
cout << "Simple floodfill mode is setn";
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’:
cout << "4-connectivity mode is setn";
connectivity = 4;
break;
case ‘8’:
cout << "8-connectivity mode is setn";
connectivity = 8;
break;
}
}
return 0;
}
点击图标改变图像中的连图区域的颜色:
————————————–分割线 ————————————–
Ubuntu Linux下安装OpenCV2.4.1所需包 http://www.linuxidc.com/Linux/2012-08/68184.htm
Ubuntu 12.04 安装 OpenCV2.4.2 http://www.linuxidc.com/Linux/2012-09/70158.htm
CentOS下OpenCV无法读取视频文件 http://www.linuxidc.com/Linux/2011-07/39295.htm
Ubuntu 12.04下安装OpenCV 2.4.5总结 http://www.linuxidc.com/Linux/2013-06/86704.htm
Ubuntu 10.04中安装OpenCv2.1九步曲 http://www.linuxidc.com/Linux/2010-09/28678.htm
基于QT和OpenCV的人脸识别系统 http://www.linuxidc.com/Linux/2011-11/47806.htm
[翻译]Ubuntu 14.04, 13.10 下安装 OpenCV 2.4.9 http://www.linuxidc.com/Linux/2014-12/110045.htm
————————————–分割线 ————————————–