若该文为原创文章,未经容许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:http://www.javashuo.com/article/p-wxwjppoc-mo.html
本文章博客地址:http://www.javashuo.com/article/p-mgryrion-nu.html
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么本身研究算法
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...(点击传送门)函数
上一篇:《OpenCV开发笔记(三十二):红胖子8分钟带你深刻了解半阈值化(图文并貌+浅显易懂+程序源码)》ui
下一篇:《OpenCV开发笔记(三十四):红胖子带你傻瓜式编译Qt+openCV3.4.1+opencv_contrib(全网最浅显易懂)》spa
红胖子来也!!!.net
今天来讲说漫水填充,顾名思义,漫水填充就是放水,水漫上去,那么连通的区域不就都有水,就造成了一片漫水的区域,该区域就是要分离的。code
通俗一点:漫水的整个过程,首先要选择一点做为防水点,而后开始放水,放水多少就能向外围扩散多大面积,能够把像素的bgr值想象成高度,谁放的越多,能覆盖的相邻高度差就越大。blog
漫水填充是一种用特定的颜色填充连通区域,经过设置可联通像素的上下限以及联通方式来达到不一样的填充效果的方法。它是在不少图形绘软件中经常使用的填充算法。ci
漫水填充被用来标记或分离图像的一部分,以便对其进行一步处理或分析,也能够用来从输入图像获取掩码区域,掩码会加速处理过程,或只处理掩码指定的像素点,操做的结果老是某个连续的区域。开发
漫水填充的原理简单来讲,就是从一个点开始水漫(放水,像素rgb的差理解为高度差)附近像素点,填充成新的颜色,直到封闭区域内的全部像素点都被填充成新颜色位置。get
漫水填充的实现方法也有多种:4邻域像素填充法、8邻域像素填充法、基于扫描线的填充方法。
(注意:下面的函数不带掩码输入)
CV_EXPORTS_W int floodFill( InputOutputArray image, Point seedPoint, Scalar newVal, CV_OUT Rect* rect=0, Scalar loDiff = Scalar(), Scalar upDiff = Scalar(), int flags = 4 );
(注意:下面的函数带掩码输入)
CV_EXPORTS_W int floodFill( InputOutputArray image, InputOutputArray mask, Point seedPoint, Scalar newVal, CV_OUT Rect* rect=0, Scalar loDiff = Scalar(), Scalar upDiff = Scalar(), int flags = 4 );
void OpenCVManager::testDiffuseFill() { QString fileName1 = "I:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/11.jpg"; cv::Mat srcMat = cv::imread(fileName1.toStdString()); int width = 300; int height = 200; cv::resize(srcMat, srcMat, cv::Size(width, height)); cv::String windowName = _windowTitle.toStdString(); cvui::init(windowName); cv::Mat windowMat = cv::Mat(cv::Size(srcMat.cols * 3, srcMat.rows * 4), srcMat.type()); int x = 100; int y = 100; int b = 255; int g = 0; int r = 0; int loB = 5; int loG = 5; int loR = 5; int upB = 5; int upG = 5; int upR = 5; while(true) { windowMat = cv::Scalar(0, 0, 0); // 原图先copy到左边 cv::Mat leftMat = windowMat(cv::Range(0, srcMat.rows), cv::Range(0, srcMat.cols)); cv::addWeighted(leftMat, 1.0f, srcMat, 1.0f, 0.0f, leftMat); // 选取原图坐标点 cvui::printf(windowMat, width * 1 + 50, 30 + height * 0, "x"); cvui::trackbar(windowMat, width * 1 + 50, 40 + height * 0, 200, &x, 0, width); cvui::printf(windowMat, width * 1 + 50, 90 + height * 0, "y"); cvui::trackbar(windowMat, width * 1 + 50, 100 + height * 0, 200, &y, 0, height); // 修改的新颜色 cvui::printf(windowMat, width * 2 + 50, 0 + height * 0, "b"); cvui::trackbar(windowMat, width * 2 + 50, 10 + height * 0, 200, &b, 0, 255); cvui::printf(windowMat, width * 2 + 50, 60 + height * 0, "g"); cvui::trackbar(windowMat, width * 2 + 50, 70 + height * 0, 200, &g, 0, 255); cvui::printf(windowMat, width * 2 + 50, 120 + height * 0, "r"); cvui::trackbar(windowMat, width * 2 + 50, 130 + height * 0, 200, &r, 0, 255); // 低像素差 cvui::printf(windowMat, width * 1 + 50, 0 + height * 1, "loB"); cvui::trackbar(windowMat, width * 1 + 50, 10 + height * 1, 200, &loB, 0, 255); cvui::printf(windowMat, width * 1 + 50, 60 + height * 1, "loG"); cvui::trackbar(windowMat, width * 1 + 50, 70 + height * 1, 200, &loG, 0, 255); cvui::printf(windowMat, width * 1 + 50, 120 + height * 1, "loR"); cvui::trackbar(windowMat, width * 1 + 50, 130 + height * 1, 200, &loR, 0, 255); // 高像素差 cvui::printf(windowMat, width * 2 + 50, 0 + height * 1, "upB"); cvui::trackbar(windowMat, width * 2 + 50, 10 + height * 1, 200, &upB, 0, 255); cvui::printf(windowMat, width * 2 + 50, 60 + height * 1, "upG"); cvui::trackbar(windowMat, width * 2 + 50, 70 + height * 1, 200, &upG, 0, 255); cvui::printf(windowMat, width * 2 + 50, 120 + height * 1, "upR"); cvui::trackbar(windowMat, width * 2 + 50, 130 + height * 1, 200, &upR, 0, 255); // 标志 cvui::printf(windowMat, width * 0 + 50, 60 + height * 2, "flags: default"); cvui::printf(windowMat, width * 1 + 50, 60 + height * 2, "flags: 4 | FLOODFILL_FIXED_RANGE"); cvui::printf(windowMat, width * 2 + 50, 60 + height * 2, "flags: 8 | FLOODFILL_FIXED_RANGE"); // circle cv::circle(windowMat, cv::Point(x, y), 5, cv::Scalar(0, 0, 255), -1); { cv::Rect rect; cv::Mat tempMat; cv::Mat dstMat; // 填充 tempMat = srcMat.clone(); cv::floodFill(tempMat, cv::Point(x, y), cv::Scalar(b, g, r), &rect, cv::Scalar(loB, loG, loR), cv::Scalar(upB, upG, upR)); dstMat = windowMat(cv::Range(srcMat.rows * 3, srcMat.rows * 4), cv::Range(srcMat.cols * 0, srcMat.cols * 1)); cv::addWeighted(dstMat, 0.0f, tempMat, 1.0f, 0.0f, dstMat); // 填充 tempMat = srcMat.clone(); cv::floodFill(tempMat, cv::Point(x, y), cv::Scalar(b, g, r), &rect, cv::Scalar(loB, loG, loR), cv::Scalar(upB, upG, upR), 4 | cv::FLOODFILL_FIXED_RANGE); dstMat = windowMat(cv::Range(srcMat.rows * 3, srcMat.rows * 4), cv::Range(srcMat.cols * 1, srcMat.cols * 2)); cv::addWeighted(dstMat, 0.0f, tempMat, 1.0f, 0.0f, dstMat); // 填充 tempMat = srcMat.clone(); cv::floodFill(tempMat, cv::Point(x, y), cv::Scalar(b, g, r), &rect, cv::Scalar(loB, loG, loR), cv::Scalar(upB, upG, upR), 8 | cv::FLOODFILL_FIXED_RANGE); dstMat = windowMat(cv::Range(srcMat.rows * 3, srcMat.rows * 4), cv::Range(srcMat.cols * 2, srcMat.cols * 3)); cv::addWeighted(dstMat, 0.0f, tempMat, 1.0f, 0.0f, dstMat); } // 更新 cvui::update(); // 显示 cv::imshow(windowName, windowMat); // esc键退出 if(cv::waitKey(25) == 27) { break; } } }
对应版本号v1.28.0
上一篇:《OpenCV开发笔记(三十二):红胖子8分钟带你深刻了解半阈值化(图文并貌+浅显易懂+程序源码)》
下一篇:《OpenCV开发笔记(三十四):红胖子带你傻瓜式编译Qt+openCV3.4.1+opencv_contrib(全网最浅显易懂)》
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:http://www.javashuo.com/article/p-wxwjppoc-mo.html
本文章博客地址:http://www.javashuo.com/article/p-mgryrion-nu.html