opencv2 floodFill函数详解

来源:互联网 发布:淘宝衣服店铺介绍 编辑:程序博客网 时间:2024/06/05 02:41
首先看函数原型:

int floodFill(InputOutputArray image, InputOutputArray mask, Point seedPoint,Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4 );


InputOutputArray这个接口类,第一说明输入是它输出也是它;第二,说明InputArray这个接口类可以是Mat、Mat_<T>、Mat_<T, m, n>、vector<T>、vector<vector<T>>、vector<Mat>。


seedPoint意思在于给定图像中的一点,该算法的起始点。


newVal是从起始点出发,对满足生长条件的点全部赋予一个新的颜色。而该生长条件由两个参数去确定,即loDiff(lower brightness/color difference)与upDiff。当前像素点与待比较像素点的负差和正差的最大值。


显然后4个参数都有默认值。

最后值的探究的参数就剩下mask和flags这两个参数。


mask顾名思义是掩膜,数字图像处理中的掩膜概念借鉴与PCB制版的过程,其作用是:在硅片上选定的区域中对一个不透明的图形模板遮盖,继而下面的腐蚀或扩散将只影响选定的区域以外的区域。那么图像处理中的意义也就在与此,对于掩膜中的非0像素,不予以处理。一般而言,这里的掩膜的大小要比原图像的长宽各大2个像素点的距离。


flags是一个int的参数,其值由3部分组成。
低8位用于控制算法的连通性,可取4 (4为缺省值) 或者 8。如果设为4,表示填充算法只考虑当前像素水平方向和垂直方向的相邻点;如果设为 8,除上述相邻点外,还会包含对角线方向的相邻点。
高8位部分(16~23位)可以为0 或者如下两种选项标识符的组合:
FLOODFILL_FIXED_RANGE - 如果设置为这个标识符的话,就会考虑当前像素与种子像素之间的差,否则就考虑当前像素与其相邻像素的差。也就是说,这个范围是浮动的。

FLOODFILL_MASK_ONLY - 如果设置为这个标识符的话,函数不会去填充改变原始图像 (也就是忽略第三个参数newVal),而是去填充掩模图像(mask)。这个标识符只对第二个版本的floodFill有用,因第一个版本里面压根就没有mask参数。

中间八位部分,上面关于高八位FLOODFILL_MASK_ONLY标识符中已经说的很明显,需要输入符合要求的掩码。Floodfill的flags参数的中间八位的值就是用于指定填充掩码图像的值的。但如果flags中间八位的值为0,则掩码会用1来填充。
而所有flags可以用or操作符连接起来,即“|”。例如,如果想用8邻域填充,并填充固定像素值范围,填充掩码而不是填充源图像,以及设填充值为38,那么输入的参数是这样:
flags=8 | FLOODFILL_MASK_ONLY | FLOODFILL_FIXED_RANGE | (38<<8)


下面看一段来自于对meanshift进行超像素分割后的代码:

//This colors the segmentations   static void floodFillPostprocess(Mat& img, const Scalar& colorDiff = Scalar::all(1)){    CV_Assert(!img.empty());    RNG rng = theRNG();    Mat mask(img.rows + 2, img.cols + 2, CV_8UC1, Scalar::all(0));    for (int y = 0; y < img.rows; y++)    {        for (int x = 0; x < img.cols; x++)        {            if (mask.at<uchar>(y + 1, x + 1) == 0)            {                Scalar newVal(rng(256), rng(256), rng(256));                floodFill(img, mask, Point(x, y), newVal, 0, colorDiff, colorDiff);            }        }    }}int main(int argc, uchar* argv[]){......pyrMeanShiftFiltering(src, dst, spatialRad, colorRad, maxPryLevel);floodFillPostprocess(src_light_channel, Scalar::all(2));......}



代码解析:

1.Mat& img说明是对src_light_channel的引用,如果这儿没有&,那么当执行算法后,src_light_channel的值并不会改变。

2.scalar::all(0)是所有的元素都设置为0。再比如Mat src_light_channel(src.rows, src.cols, CV_8UC3, Scalar::all(0));这个定义中,用此语句来让所有的像素值初始化为0。可是这个语句的大小是什么呢?是一个值吗?或者长宽是多少?详见http://lib.csdn.net/article/opencv/24028。


文章参考网址:
http://blog.csdn.net/poem_qianmo/article/details/28261997 【OpenCV入门教程之十五】水漫金山:OpenCV漫水填充算法(Floodfill)
http://blog.csdn.net/yang_xian521/article/details/7755101 OpenCV学习笔记(五十六)——InputArray和OutputArray的那些事core
http://blog.csdn.net/jinxiaonian11/article/details/53467437 图像处理中掩膜(mask)的意义
http://blog.csdn.net/gdfsg/article/details/50975422 学习OpenCV2——MeanShift之图形分割
原创粉丝点击