简单网站建设合同,贵州省高层建筑信息平台,用深度liunx做网站,成都到西安高铁票价OpenCV学习笔记#xff08;九#xff09;#xff1a; 漫水填充#xff1a;floodFill()
定义#xff1a; 漫水填充法是一种用特定的颜色填充联通区域#xff08;自动选中了和种子点相连的区域#xff0c;接着将该区域替换成指定的颜色#xff09;通过设置可连通像素的上…OpenCV学习笔记九 漫水填充floodFill()
定义 漫水填充法是一种用特定的颜色填充联通区域自动选中了和种子点相连的区域接着将该区域替换成指定的颜色通过设置可连通像素的上下限以及连通方式来达到不同的填充效果的方法。 使用 1经常被用来标记或分离图像的一部分以便对其进行进一步处理或分析。 2从输入图像获取掩码区域掩码会加速处理过程或只处理掩码指定的像素点,操作的结果总是某个连续的区域 算子
int floodFill(
InputOutputArray image, // 1.输入/输出图像
InputOutputArray mask, // 2.这是第二个版本的floodFill独享的参数表示操作掩模(它应该为单通道、8位、长和宽上都比输入图像 image 大两个像素点的图像)
Point seedPoint, // 3.漫水填充算法的起始点
Scalar newVal, // 4.在重绘区域像素点被染色的新值
Rect* rect0, // 5.一个可选的参数将要重绘区域的最小边界矩形区域
Scalar loDiffScalar(), // 6.loDiff 负差最大值当前像素与领域像素或种子像素颜色或亮度的
Scalar upDiffScalar(), // 7.upDiff 正差最大值当前像素与领域像素或种子像素颜色或亮度的
int flags4 // 8.操作标志符
)// PS: 1、漫水填充不会填充掩膜mask的非零像素区域。例如一个边缘检测算子的输出可以用来作为掩膜以防止填充到边缘。同样的也可以在多次的函数调用中使用同一个掩膜以保证填充的区域不会重叠。另外需要注意的是 掩膜mask会比需填充的图像大所以 mask 中与输入图像(x,y)像素点相对应的点的坐标为(x1,y1)。 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
flags8 | FLOODFILL_MASK_ONLY | FLOODFILL_FIXED_RANGE | 388示例代码
#include opencv2/opencv.hppusing 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.data ){printf(读取图片image0错误~ \n);return false;}// 2、拷贝源图到目标图g_srcImage.copyTo(g_dstImage);// 3、转换三通道的image0到灰度图cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);// 4、利用image0的尺寸来初始化掩膜maskg_maskImage.create(g_srcImage.rows2, g_srcImage.cols2, CV_8UC1);// 5、创建TrackbarnamedWindow( 效果图,WINDOW_AUTOSIZE );createTrackbar( 负差最大值, 效果图, g_nLowDifference, 255, 0 ); // 无滑动条事件只改变滑动条值0~255createTrackbar( 正差最大值 ,效果图, g_nUpDifference, 255, 0 ); // 无滑动条事件只改变滑动条值0~255// 6、鼠标回调函数鼠标点击便触发// 将mask所有元素设置为0(背景设为黑色)g_maskImage Scalar::all(0); setMouseCallback( 效果图, onMouse, 0 );// 7、循环轮询按键while(1){//先显示效果图imshow(效果图, g_bIsColor ? g_dstImage : g_grayImage);//获取键盘按键int c waitKey(0);//判断ESC是否按下若按下便退出if( (c 255) 27 ){cout 程序退出...........\n;break;}//根据按键的不同进行各种操作switch( (char)c ){//如果键盘“1”被按下效果图在在灰度图彩色图之间互换case 1:if( g_bIsColor )//若原来为彩色转为灰度图并且将掩膜mask所有元素设置为0{cout 键盘“1”被按下切换彩色/灰度模式当前操作为将【彩色模式】切换为【灰度模式】\n;cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY);g_maskImage Scalar::all(0); //将mask所有元素设置为0g_bIsColor false; //将标识符置为false表示当前图像不为彩色而是灰度}else//若原来为灰度图便将原来的彩图image0再次拷贝给image并且将掩膜mask所有元素设置为0{cout 键盘“1”被按下切换彩色/灰度模式当前操作为将【彩色模式】切换为【灰度模式】\n;g_srcImage.copyTo(g_dstImage);g_maskImage Scalar::all(0);g_bIsColor true; //将标识符置为true表示当前图像模式为彩色}break;//如果键盘按键“2”被按下显示/隐藏掩膜窗口case 2:if( g_bUseMask ){destroyWindow( mask );g_bUseMask false;}else{namedWindow( mask, 0 );//g_maskImage Scalar::all(0); // 清空置零imshow(mask, g_maskImage);g_bUseMask true;}break;//如果键盘按键“3”被按下恢复原始图像case 3:cout 按键“3”被按下恢复原始图像\n;g_srcImage.copyTo(g_dstImage);cvtColor(g_dstImage, g_grayImage, COLOR_BGR2GRAY);g_maskImage Scalar::all(0);break;// 改变”漫水填充“操作标识// 1、如果键盘按键“4”被按下使用空范围的漫水填充case 4:cout 按键“4”被按下使用空范围的漫水填充\n;g_nFillMode 0;break;// 2、如果键盘按键“5”被按下使用渐变、固定范围的漫水填充case 5:cout 按键“5”被按下使用渐变、固定范围的漫水填充\n;g_nFillMode 1;break;// 3、如果键盘按键“6”被按下使用渐变、浮动范围的漫水填充case 6:cout 按键“6”被按下使用渐变、浮动范围的漫水填充\n;g_nFillMode 2;break;// 4、如果键盘按键“7”被按下操作标志符的低八位使用4位的连接模式case 7:cout 按键“7”被按下操作标志符的低八位使用4位的连接模式\n;g_nConnectivity 4;break;// 5、如果键盘按键“8”被按下操作标志符的低八位使用8位的连接模式case 8:cout 按键“8”被按下操作标志符的低八位使用8位的连接模式\n;g_nConnectivity 8;break;}}
}输出一些帮助信息
static void ShowHelpText()
{printf(\n\n\t漫水填充示例程序~);printf(\n\n\t根据鼠标选取的点搜索图像中与之颜色相近的点并用不同颜色标注。);printf(\n\n\t按键操作说明: \n\n\t\t鼠标点击图中区域- 进行漫水填充操作\n\t\t键盘按键【ESC】- 退出程序\n\t\t键盘按键【1】- 切换彩色图/灰度图模式\n\t\t键盘按键【2】- 显示/隐藏掩膜窗口\n\t\t键盘按键【3】- 恢复原始图像\n\t\t键盘按键【4】- 使用空范围的漫水填充\n\t\t键盘按键【5】- 使用渐变、固定范围的漫水填充\n\t\t键盘按键【6】- 使用渐变、浮动范围的漫水填充\n\t\t键盘按键【7】- 操作标志符的低八位使用4位的连接模式\n\t\t键盘按键【8】- 操作标志符的低八位使用8位的连接模式\n\n);
}鼠标消息onMouse回调
static void onMouse(int event, int x, int y, int, void*)
{if (event ! EVENT_LBUTTONDOWN)return;// 1、调用floodFill函数之前的参数准备部分Point seed Point(x, y); // 鼠标点击获取起始点位置int LowDifference g_nFillMode 0 ? 0 : g_nLowDifference; //空范围的漫水填充此值设为0否则设为全局的g_nLowDifferenceint UpDifference g_nFillMode 0 ? 0 : g_nUpDifference; //空范围的漫水填充此值设为0否则设为全局的g_nUpDifference// 1.1、floodFill()函数第八个参数值flags低八位中八位高八位int flags g_nConnectivity (g_nNewMaskVal 8) (g_nFillMode 1 ? FLOODFILL_FIXED_RANGE : 0); // FLOODFILL_FIXED_RANGE// 1.2、随机生成bgr值int b (unsigned)theRNG() 255;//随机返回一个0~255之间的值int g (unsigned)theRNG() 255;//随机返回一个0~255之间的值int r (unsigned)theRNG() 255;//随机返回一个0~255之间的值Rect ccomp;//定义重绘区域的最小边界矩形区域// 1.3、在重绘区域像素的新值若是彩色图模式取Scalar(b, g, r)若是灰度图模式取Scalar(r*0.299 g*0.587 b*0.114)Scalar newVal g_bIsColor ? Scalar(b, g, r) : Scalar(r*0.299 g*0.587 b*0.114);Mat dst g_bIsColor ? g_dstImage : g_grayImage;//目标图的赋值// 2、正式调用floodFill函数threshold(g_maskImage, g_maskImage, 1, 128, THRESH_BINARY);// 带掩码输出的 floodFill()int area floodFill(dst, g_maskImage, seed, newVal, ccomp, Scalar(LowDifference, LowDifference, LowDifference),Scalar(UpDifference, UpDifference, UpDifference), flags);// 3、关闭或显示掩码窗口if (g_bUseMask){imshow(mask, g_maskImage);}
// else
// {
// // 不带掩码输出的 floodFill()
// area floodFill(dst, seed, newVal, ccomp, Scalar(LowDifference, LowDifference, LowDifference),
// Scalar(UpDifference, UpDifference, UpDifference), flags);
// }imshow(效果图, dst);cout area 个像素被重绘\n;
}结果