OpenCV学习笔记(九): 漫水填充:floodFill()
定义:
漫水填充法是一种用特定的颜色填充联通区域(自动选中了和种子点相连的区域,接着将该区域替换成指定的颜色)通过设置可连通像素的上下限以及连通方式来达到不同的填充效果的方法。
使用:
1)经常被用来标记或分离图像的一部分,以便对其进行进一步处理或分析。
2)从输入图像获取掩码区域(掩码会加速处理过程,或只处理掩码指定的像素点,操作的结果总是某个连续的区域)
算子:
int floodFill(
InputOutputArray image, // 1.输入/输出图像
InputOutputArray mask, // 2.这是第二个版本的floodFill独享的参数,表示操作掩模(它应该为单通道、8位、长和宽上都比输入图像 image 大两个像素点的图像)
Point seedPoint, // 3.漫水填充算法的起始点
Scalar newVal, // 4.在重绘区域像素点被染色的新值
Rect* rect=0, // 5.一个可选的参数,将要重绘区域的最小边界矩形区域
Scalar loDiff=Scalar(), // 6.loDiff 负差最大值(当前像素与领域像素或种子像素颜色或亮度的)
Scalar upDiff=Scalar(), // 7.upDiff 正差最大值(当前像素与领域像素或种子像素颜色或亮度的)
int flags=4 // 8.操作标志符
)
// PS:
1、漫水填充不会填充掩膜mask的非零像素区域。例如,一个边缘检测算子的输出可以用来作为掩膜,以防止填充到边缘。同样的,也可以在多次的函数调用中使用同一个掩膜,以保证填充的区域不会重叠。另外需要注意的是,
掩膜mask会比需填充的图像大,所以 mask 中与输入图像(x,y)像素点相对应的点的坐标为(x+1,y+1)。
2、
1)低八位(第0~7位)用于控制算法的连通性,可取4 (4为缺省值) 或者 8。
如果设为4,表示填充算法只考虑当前像素水平方向和垂直方向的相邻点;
如果设为 8,除上述相邻点外,还会包含对角线方向的相邻点。
2)高八位部分(16~23位)可以为0 或者如下两种选项标识符的组合:
FLOODFILL_FIXED_RANGE - 如果设置为这个标识符的话,就会考虑当前像素与种子像素之间的差,
否则就考虑当前像素与其相邻像素的差。也就是说,这个范围是浮动的。
FLOODFILL_MASK_ONLY - 如果设置为这个标识符的话,函数不会去填充改变原始图像 (也就是忽略第三个参数newVal),
而是去填充掩模图像(mask)。
3)中间八位部分,上面关于高八位FLOODFILL_MASK_ONLY标识符中已经说的很明显,需要输入符合要求的掩码。Floodfill的flags参数的中间八位的值就是用于指定填充掩码图像的值的。但如果flags中间八位的值为0,则掩码会用1来填充。
//如果想用8邻域填充,并填充固定像素值范围,填充掩码而不是填充源图像,以及设填充值为38
flags=8 | FLOODFILL_MASK_ONLY | FLOODFILL_FIXED_RANGE | (38<<8)
示例代码:
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Mat g_srcImage, g_dstImage, g_grayImage, g_maskImage; //定义原始图、目标图、灰度图、掩模图
int g_nFillMode = 1; //漫水填充的模式
int g_nLowDifference = 20, g_nUpDifference = 20; //负差最大值、正差最大值
int g_nConnectivity = 4; //表示floodFill函数标识符低八位的连通值
bool g_bIsColor = true; //是否为彩色图的标识
bool g_bUseMask = false; //是否显示掩膜窗口的标识
int g_nNewMaskVal = 255; //新的重新绘制的像素值
int main()
{
//显示帮助文字
ShowHelpText();
// 1、载入原图
g_srcImage = imread("F:/C++/2. OPENCV 3.1.0/TEST/2.jpg", 1);
if( !g_srcImage.da