今天做了一个项目总结,本来很快能结束的,结果因为这两个函数不理解耽误了很长时间,以此记录一下。
add函数:
C++: void add(InputArray src1, InputArray src2, OutputArray dst, InputArray mask=noArray(), int dtype=-1)
这是新版的函数之前以为这个函数不能同C版本的兼容一直找格式转换的问题,结果其实根本不用转换,只能怪我没有好好看api文档,c的如下
C: void cvAdd(const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL)
C: void cvAddS(const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL)
以为不能兼容,后来发现c++版本的全部都做到了,相当于把两个函数合并了。 在来看看怎么用: src1:输入数组1 src2:输入数组2 dst:输出数组 mask:掩模矩阵(具体往下看) 先看看文档
如果src1和src2都是相同大小的矩阵和通道数,那么在掩模不是0的位置两个矩阵相加 例如 src1: 1 2 3 4 5 src2: 1 1 1 1 1 dst: 0 0 0 0 0(注意这里要初值) mask: 1 1 0 0 0
按照公式: mask(0)=1,src1(0)=1,src2(0)=1; dst(0)=src1(0)+src2(0); ...... 结果: dst就是:2 3 3 0 0 用for循环重复计算了:(这是用add()函数计算的,不是我拿公式算的)
saturate()这个函数没有找到什么意思,但是我感觉应该就是计算出来的值如果小于图像类型(注意是图像类型)的最小值就取最小值,大于图像类型最大值就取最大值。
同理第二个就好理解了: 当src1是矩阵,src2是标量的时候: 比如: src1: 1 2 3 4 5 src2: 1 mask: 1 1 0 0 0 dst: 0 0 0 0 0
按公式来看: mask(0)=1,src1(0)=1,src2=1; dst(0)=src(0)+src2; ........... (如果src1是3通道的图像,那么src2应该是一个3通道图像的像素值例如Scalar(100,0,255); 每个通道值都是单独相加的.)
结果应该是:dst:2 3 0 0 0
下满来看Floodfill函数 在OpenCV中,漫水填充是填充算法中最通用的方法。且在OpenCV 2.X中,使用C++重写过的FloodFill函数有两个版本。一个不带掩膜mask的版本,和一个带mask的版本。这个掩膜mask,就是用于进一步控制哪些区域将被填充颜色(比如说当对同一图像进行多次填充时)。这两个版本的FloodFill,都必须在图像中选择一个种子点,然后把临近区域所有相似点填充上同样的颜色,不同的是,不一定将所有的邻近像素点都染上同一颜色,漫水填充操作的结果总是某个连续的区域。当邻近像素点位于给定的范围(从loDiff到upDiff)内或在原始seedPoint像素值范围内时,FloodFill函数就会为这个点涂上颜色。 第一个参数,InputOutputArray类型的image, 输入/输出1通道或3通道,8位或浮点图像,具体参数由之后的参数具体指明。 第二个参数, InputOutputArray类型的mask,这是第二个版本的floodFill独享的参数,表示操作掩模,。它应该为单通道、8位、长和宽上都比输入图像 image 大两个像素点的图像。第二个版本的floodFill需要使用以及更新掩膜,所以这个mask参数我们一定要将其准备好并填在此处。需要注意的是,漫水填充不会填充掩膜mask的非零像素区域。例如,一个边缘检测算子的输出可以用来作为掩膜,以防止填充到边缘。同样的,也可以在多次的函数调用中使用同一个掩膜,以保证填充的区域不会重叠。另外需要注意的是,掩膜mask会比需填充的图像大,所以 mask 中与输入图像(x,y)像素点相对应的点的坐标为(x+1,y+1)。 第三个参数,Point类型的seedPoint,漫水填充算法的起始点。 第四个参数,Scalar类型的newVal,像素点被染色的值,即在重绘区域像素的新值。 第五个参数,Rect*类型的rect,有默认值0,一个可选的参数,用于设置floodFill函数将要重绘区域的最小边界矩形区域。 第六个参数,Scalar类型的loDiff,有默认值Scalar( ),表示当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的亮度或颜色之负差(lower brightness/color difference)的最大值。 第七个参数,Scalar类型的upDiff,有默认值Scalar( ),表示当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的亮度或颜色之正差(lower brightness/color difference)的最大值。第八个参数,int类型的flags,操作标志符,此参数包含三个部分,比较复杂,我们一起详细看看。
低八位 (第0~7位)用于控制算法的连通性,可取4 (4为缺省值) 或者 8。如果设为4,表示填充算法只考虑当前像素水平方向和垂直方向的相邻点;如果设为 8,除上述相邻点外,还会包含对角线方向的相邻点。 高八位 部分(16~23位)可以为0 或者如下两种选项标识符的组合:
FLOODFILL_FIXED_RANGE - 如果设置为这个标识符的话,就会考虑当前像素与种子像素之间的差,否则就考虑当前像素与其相邻像素的差。也就是说,这个范围是浮动的。FLOODFILL_MASK_ONLY - 如果设置为这个标识符的话,函数不会去填充改变原始图像 (也就是忽略第三个参数newVal), 而是去填充掩模图像(mask)。
注意这里:FLOODFILL_MASK_ONLY标志是用来填充掩模图像,今天就是因为这个搞了好半天,一直没注意! 中间八位部分,上面关于高八位FLOODFILL_MASK_ONLY标识符中已经说的很明显,需要输入符合要求的掩码。Floodfill的flags参数的中间八位的值就是用于指定填充掩码图像的值的。但如果flags中间八位的值为0,则掩码会用1来填充。