计算机视觉
图像处理

【OpenCV】使用floodfill()实现PhotoShop魔棒功能

Opencv中看到一个很有意思的函数:floodfill()()

使用给定颜色填充一个联通的区域

  1. C++: int floodFill(InputOutputArray image, Point seedPoint,
  2. Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(),
  3. 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 n";
        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; }  

点击图标改变图像中的连图区域的颜色:

转载注明来源:CV视觉网 » 【OpenCV】使用floodfill()实现PhotoShop魔棒功能

分享到:更多 ()
扫描二维码,给作者 打赏
pay_weixinpay_weixin

请选择你看完该文章的感受:

0不错 0超赞 0无聊 0扯淡 0不解 0路过

评论 6

评论前必须登录!