【opencv】示例-ffilldemo 使用floodFill()函数进行区域泛洪填充

2bd72e70ac1ebbc906dc1870875d3ca6.png

127182a9ea2f22ff85bad28b601ebf2b.png

image

798ffb1cc12d1979ab753c9a2f9e29b2.png

mask

222086218d6c6973d7837793e311bbc9.png

mask

d5bac1f77a9da77d4f9cb3197a204081.png

#include "opencv2/imgproc.hpp" // 包含OpenCV图像处理头文件
#include "opencv2/imgcodecs.hpp" // 包含OpenCV图像编码头文件
#include "opencv2/videoio.hpp" // 包含OpenCV视频IO头文件
#include "opencv2/highgui.hpp" // 包含OpenCV高层GUI头文件#include <iostream> // 包含标准输入输出流库using namespace cv; // 使用命名空间cv,避免每次调用OpenCV函数时都要写cv::
using namespace std; // 使用命名空间std,避免每次使用标准库时都要写std::// 帮助函数,输出程序用法信息
static void help(char** argv)
{// 输出程序的使用说明cout << "\nThis program demonstrated the floodFill() function\n""Call:\n"<<  argv[0]<<  " [image_name -- Default: fruits.jpg]\n" << endl;// 输出热键信息cout << "Hot keys: \n""\tESC - quit the program\n" // ESC键退出程序"\tc - switch color/grayscale mode\n" // c键切换颜色/灰度模式"\tm - switch mask mode\n" // m键切换掩膜模式"\tr - restore the original image\n" // r键恢复原始图像"\ts - use null-range floodfill\n" // s键使用零范围泛洪填充(Simple floodfill)"\tf - use gradient floodfill with fixed(absolute) range\n" // f键使用固定范围渐变泛洪填充(Fixed Range floodfill)"\tg - use gradient floodfill with floating(relative) range\n" // g键使用浮动范围渐变泛洪填充(Gradient floodfill)"\t4 - use 4-connectivity mode\n" // 4键使用4连通模式"\t8 - use 8-connectivity mode\n" << endl; // 8键使用8连通模式
}// 定义全局变量
Mat image0, image, gray, mask; // 原图像、当前图像、灰度图和掩膜图
int ffillMode = 1; // 泛洪填充模式,默认为1
int loDiff = 20, upDiff = 20; // 泛洪填充的下差和上差
int connectivity = 4; // 连接模式,默认为4连通
int isColor = true; // 表示是否为彩色模式
bool useMask = false; // 表示是否使用掩膜
int newMaskVal = 255; // 新掩膜值// 鼠标回调函数
static void onMouse( int event, int x, int y, int, void* )
{if( event != EVENT_LBUTTONDOWN ) // 如果事件不是左键按下,则直接返回return;Point seed = Point(x,y); // 构建种子点int lo = ffillMode == 0 ? 0 : loDiff; // 根据ffillMode确定下差int up = ffillMode == 0 ? 0 : upDiff; // 根据ffillMode确定上差// 构建标志信息,包含连接模式、新掩膜值、以及填充模式int flags = connectivity + (newMaskVal << 8) +(ffillMode == 1 ? 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, 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 repainted\n"; // 输出重绘像素数
}// 程序主函数
int main( int argc, char** argv )
{// 解析命令行参数cv::CommandLineParser parser (argc, argv,"{help h | | show help message}{@image|fruits.jpg| input image}");if (parser.has("help")) // 如果带有help参数,则显示帮助信息{parser.printMessage();return 0;}// 获取命令行指定的图像文件名称,如果没有指定则为默认值string filename = parser.get<string>("@image");// 加载图像image0 = imread(samples::findFile(filename), 1);if( image0.empty() ) // 如果图像为空,则输出提示信息并返回{cout << "Image empty\n";parser.printMessage();return 0;}help(argv); // 显示程序使用说明image0.copyTo(image); // 将原图像拷贝到当前图像cvtColor(image0, gray, COLOR_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); // 显示图像char c = (char)waitKey(0); // 获取一个按键if( c == 27 ) // 如果按键是ESC,则退出程序{cout << "Exiting ...\n";break;}// 根据按键进行不同的操作switch( c ){case 'c': // 切换颜色模式if( isColor ){cout << "Grayscale mode is set\n";cvtColor(image0, gray, COLOR_BGR2GRAY); // 转换为灰度图像mask = Scalar::all(0); // 重置掩膜isColor = false;}else{cout << "Color mode is set\n";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 restored\n";image0.copyTo(image); // 拷贝原图到当前图像cvtColor(image, gray, COLOR_BGR2GRAY); // 转换为灰度图mask = Scalar::all(0); // 重置掩膜break;case 's': // 设置为简单泛洪填充模式cout << "Simple floodfill mode is set\n";ffillMode = 0;break;case 'f': // 设置为固定范围渐变泛洪填充模式cout << "Fixed Range floodfill mode is set\n";ffillMode = 1;break;case 'g': // 设置为浮动范围渐变泛洪填充模式cout << "Gradient (floating range) floodfill mode is set\n";ffillMode = 2;break;case '4':// 当用户按下'4'键时,输出提示信息并设置连通性为4(4连通)cout << "4-connectivity mode is set\n";connectivity = 4; // 设置连通性变量为4,意味着接下来floodFill操作将使用4连通区域break; // 跳出switchcase '8':// 当用户按下'8'键时,输出提示信息并设置连通性为8(8连通)cout << "8-connectivity mode is set\n";connectivity = 8; // 设置连通性变量为8,意味着接下来floodFill操作将使用8连通区域break; // 跳出switch}}return 0; // 程序结束,返回0值
}
int area = floodFill(dst, mask, seed, newVal, &ccomp, 
Scalar(lo, lo, lo), Scalar(up, up, up), flags);

c453d0fdd262dc1b6e63ee99673f60d2.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/620109.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MO-MFEA--多目标多任务优化

MO-MFEA–多目标多任务优化 title&#xff1a; Multiobjective Multifactorial Optimization in Evolutionary Multitasking author&#xff1a; Abhishek Gupta, Yew-Soon Ong, Liang Feng, and Kay Chen Tan. journal&#xff1a; IEEE TRANSACTIONS ON CYBERNETICS (TCYB…

C ++ 和 C语言的优缺点分别是什么?

C语言&#xff0c;它简直就是编程世界的一块磐石。简洁、直接&#xff0c;让人一眼就能明白它想干嘛。它的运行速度快&#xff0c;接近硬件操作&#xff0c;特别适合那些需要直接与硬件打交道的场景。但就是因为这种接近硬件的特性&#xff0c;C语言在抽象层次上就显得有点捉襟…

项目设计方案:市交通视频监控平台项目设计方案(五)-完稿

目录 1 前言 1.1 目的 1.2 适用范围 1.3 术语表 2 现状分析 2.1 业务现状 2.2 组织机构现状 2.3 存在的问题 2.4 项目成果预期 3 系统建设原则 4 项目需求 4.1 项目需求 4.1.1 业务需求主要分为三部分&#xff1a; 4.1.2 技术需求主要分为四部分&#xff1a; 4.2…

华为防火墙配置双机热备

一、组网需求 公司A基于确保内部网络安全性的考虑&#xff0c;在内外网络之间部署了防火墙。由于防火墙设备是所有信息流都必须通过的单一节点&#xff0c;故一旦防火墙设备出现故障所有信息流都会中断。为了增强网络的可靠性&#xff0c;保证当防火墙设备出现故障时不中断网络…

怎样关闭谷歌浏览器自动更新,亲测ok

步骤一 在服务中禁用Google更新 步骤二 Chrome更新是利用Update文件夹里的升级程序来升级的&#xff0c;需要要删除里面的文件&#xff0c;再让Chrome没法在Update文件夹里继续自动生成更新程序。所以还要清空Update文件夹并设置权限&#xff0c;让Chrome没有权限修改这个文件…

linux 自定义命令/别名

参考资料 Linux(Ubuntu)自定义命令的使用Linux/Ubuntu系统自定义Shell命令Ubuntu/Linux 操作系统 自定义命令 目录 一. 为路径取别名二. 修改.profile文件2.1 .profile简介2.2 需求2.3 修改.profile文件 三. 创建软链接 一. 为路径取别名 ⏹需求&#xff1a;有一个work文件夹…

CRMEB 开源/标准版商城系统客服配置教程

管理后台/设置/系统设置/商城配置/客服端配置 有系统客服/拨打电话/跳转链接可选&#xff0c;系统客服为系统自带的客服系统&#xff0c;拨打电话为用户点击联系客服为拨打客服电话的方式&#xff0c;跳转链接为可以跳转自己开发的客服系统或者第三方的客服系统或者企业微信的…

为什么拥有C语言基础的人,依然学不会C++?

拥有C语言基础的人在学习C时可能会遇到挑战&#xff0c;原因主要有以下几点&#xff1a; 思维方式转变&#xff1a; C语言是一种面向过程的语言&#xff0c;注重函数和过程调用&#xff0c;以及直接操作内存。 C则引入了面向对象编程&#xff08;OOP&#xff09;的概念&#x…

使用 Python 实现复制粘贴的功能

pandas 里面有一个 pd.read_clipboard 函数&#xff0c;可以根据你复制的内容生成DataFrame。是的&#xff0c;就是我们平时选中&#xff0c;然后 CtrlC 时拷贝的内容。所以比较神奇&#xff0c;那么 pandas 到底是怎么做到的&#xff0c;它是怎么读出我们使用 Ctrl C 复制的内…

nodejs解析url参数

需要引入 url 模块&#xff1b; var http require(http); var url require(url);http.createServer(function (req, res) {res.writeHead(200, {Content-Type: text/plain});// 解析 url 参数var params url.parse(req.url, true).query;res.write("name: " par…

CST电磁仿真的点/线/面设置操作【入门基础】

选择点/线/面 通过Pick功能选择点/线/面的方法 Modeling > Picks > Picks > Pick Points, Edges or Faces Pick是在模型上或任意空间中选择Point、Edge、Face的功能。利用Pick功能可以轻松获取模型的位置、尺寸等信息&#xff0c;也可以在执行Modeling和Result Han…