漫水填充:floodFill 函数

简单来说,漫水填充就是自动选中与种子像素相连的区域,利用指定颜色进行区域颜色填充。Windows 画图工具中的油漆桶功能和 Photoshop 的魔法棒选择工具,都是漫水填充的改进和延伸。

//第一个版本

int floodFill(InputOutputArray image, Point seedPoint, Scalar newVal, Rect* rect = 0, Scalar loDiff = Scalar(), Scalar upDiff = Scalar(), int flags = 4);

//第二个版本,因为 mask 的原因,一般第二个版本效果好

int floodFill(InputOutputArray image, InputOutputArray mask, Point seedPoint, Scalar newVal, Rect* rect = 0, Scalar loDiff = Scalar(), Scalar upDiff = Scalar(), int flags = 4);

  • image,输入输出图像。

  • mask,操作掩膜,应该为单通道,8 位,长和宽上都比输入图像 image 大两个像素点的图像(左右上下各多出一列像素)。需注意的是,漫水填充不会填充掩膜 mask 的非零区域,所以一个边缘检测算子的输出可以用来作为掩膜,以防止填充到边缘。

  • seedPoint,漫水填充算法的起点。

  • newVal,像素点被染色的值,即在重绘区域像素的新值。

  • rect,默认为 0,用于设置 floodFill 函数将要重绘的最小边界矩形区域,即若漫水填充区域 < rect,则不进行填充。

  • loDiff,有默认值 Scalar(),表示当前观察像素值与其邻域像素值或待加入的种子像素值之间的亮度或颜色的最大负差。

  • upDiff ,有默认值 Scalar(),表示当前观察像素值与其邻域像素值或待加入的种子像素值之间的亮度或颜色的最大正差。

  • flags,int 类型操作标识符,默认值为 4,一共 23 位。

    • 低八位(0~7):用于控制算法的连通性,可取 4(默认值)或 8。如果设为 4,表示填充算法只考虑当前像素水平或处置方向的相邻点,如果设为 8,除上述相邻点外,还会包含对角线方向的相邻点。
    • 高八位(16~23):可以为 0,或者以下两种选择标识符的组合。

FLOODFILL_FIXED_RANGE:如果设置为这个标识符,就会考虑当前像素与种子之间的差,否则就考虑当前像素与其邻域像素的差。

FLOODFILL_MASK_ONLY,如果设置为这个标识符,函数不会去填充改变原始图像,而是去填充掩膜图像(只对第二个版本的函数有用)。

    • 中间八位(8~15):用于指定填充掩码图像的值的,如果中间八位的值为 0,则掩码会用 1 来填充。

所有 falg 可以用 “|” 连接起来。例如想用 8 邻域填充,并填充固定像素范围,填充掩码而不是填充原图,以及设置填充值为 38,那么输入的参数为

flags = 8 | FLOODFILL_MASK_ONLY | FLOODFILL_FIXED_RANGE |(38 << 8)

证件照换背景代码示例:

#include<opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main() {
Scalar input_color = Scalar(, , );//背景颜色
//读入图片
Mat src = imread("C:/Users/齐明洋/Desktop/证件照/7.jpg");
imshow("src", src); //边缘检测,生成漫水填充掩膜
Mat canny_img;
int thresh_data = ;
Canny(src, canny_img, thresh_data, thresh_data * , );
imshow("canny_img", canny_img); //掩膜边缘扩充
Mat maskers = Mat(src.rows + , src.cols + , CV_8UC1, Scalar());
Mat tem_roi = maskers(Rect(Point(, ), Point(maskers.cols - , maskers.rows - )));
canny_img.copyTo(tem_roi); //分别从左右两侧进行漫水填充
Mat flood_img = src.clone();
floodFill(flood_img, maskers, Point(, ), Scalar(, , ), , Scalar(, , ), Scalar(, , ));
floodFill(flood_img, maskers, Point(src.cols - , ), Scalar(, , ), , Scalar(, , ), Scalar(, , ));
imshow("flood_img", flood_img); //生成二值图像,处理图像毛边
Mat bin_img;
cvtColor(flood_img, bin_img, COLOR_BGR2GRAY);
threshold(bin_img, bin_img, , , THRESH_BINARY);
medianBlur(bin_img, bin_img, );//消除椒盐噪声
blur(bin_img, bin_img, Size(, ));//使边缘像素呈梯度分布
imshow("bin_img", bin_img); //边界处理
Mat dst = Mat(src.rows, src.cols, src.type(), input_color);
for (int i = ; i < src.rows; i++) {
for (int j = ; j < src.cols; j++) {
int tem_color = bin_img.at<uchar>(i, j);
if (tem_color == ) {//目标像素
dst.at<Vec3b>(i, j) = src.at<Vec3b>(i, j);
}
else if (tem_color != ) {//边缘像素
double alpha = tem_color / 255.0 - 0.25;//原始颜色占比
double beta = - alpha;//新背景颜色占比
int b = saturate_cast<uchar>(input_color[] * beta + src.at<Vec3b>(i, j)[] * alpha);
int g = saturate_cast <uchar>(input_color[] * beta + src.at<Vec3b>(i, j)[] * alpha);
int r = saturate_cast <uchar>(input_color[] * beta + src.at<Vec3b>(i, j)[] * alpha); dst.at<Vec3b>(i, j)[] = b;
dst.at<Vec3b>(i, j)[] = g;
dst.at<Vec3b>(i, j)[] = r;
}
}
}
imshow("dst", dst);
waitKey();
}

效果演示:

(这个方法并不完美,但是确实是我结合现阶段所掌握的知识,做出的最优解决方案了,加油加油!)

借鉴博客:https://www.cnblogs.com/little-monkey/p/7598529.html

opencv —— floodFill 漫水填充法 实现证件照换背景的更多相关文章

  1. HDU - 1241 POJ - 1562 Oil Deposits DFS FloodFill漫水填充法求连通块问题

    Oil Deposits The GeoSurvComp geologic survey company is responsible for detecting underground oil de ...

  2. Opencv之漫水填充效果

    下面是opencv的漫水填充效果代码 这篇文章仅限个人的笔记 没有详细的注释 放代码 这是简单的示范 int main()//*******************简单的漫水填充算法实例 { Vide ...

  3. 【OpenCV】漫水填充

    漫水填充:也就是用一定颜色填充联通区域,通过设置可连通像素的上下限以及连通方式来达到不同的填充效果;漫水填充经常被用来标记或分离图像的一部分以便对其进行进一步处理或分析,也可以用来从输入图像获取掩码区 ...

  4. DFS求连通块(漫水填充法)

    G - DFS(floodfill),推荐 Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I6 ...

  5. PS证件照换背景

    综述 博主原创内容. 在PS里,对于抠图,比较有技术含量的便是抠头发丝了,下面为大家带来一个比较详细的抠头发丝的教程. 素材准备 在这里我们用这张图片作为抠图素材,下面让我们一步步来演示抠图的过程,并 ...

  6. 【OpenCV新手教程之十五】水漫金山:OpenCV漫水填充算法(Floodfill)

    本系列文章由@浅墨_毛星云 出品,转载请注明出处.    文章链接: http://blog.csdn.net/poem_qianmo/article/details/28261997 作者:毛星云( ...

  7. OpenCV3编程入门笔记(4)腐蚀、膨胀、开闭运算、漫水填充、金字塔、阈值化、霍夫变换

    腐蚀erode.膨胀dilate 腐蚀和膨胀是针对图像中的白色部分(高亮部分)而言的,不是黑色的.除了输入输出图像外,还需传入模板算子element,opencv中有三种可以选择:矩形MORPH_RE ...

  8. opencv 4 图像处理(漫水填充,图像金字塔与图片尺寸缩放,阈(yu)值化)

    漫水填充 实现漫水填充算法:floodFill函数 简单调用范例 #include <opencv2/opencv.hpp> #include <opencv2/imgproc/im ...

  9. OpenCV漫水填充算法示例代码

    #include<cv.h> #include<highgui.h> int main(int argc, char** argv) { IplImage* img = cvL ...

随机推荐

  1. 什么是LakeHouse?

    1. 引入 在Databricks的过去几年中,我们看到了一种新的数据管理范式,该范式出现在许多客户和案例中:LakeHouse.在这篇文章中,我们将描述这种新范式及其相对于先前方案的优势. 数据仓库 ...

  2. android开发实战-记账本APP(一)

    记账本开发流程: 对于一个记账本的初步开发而言,我实现的功能有: ①实现一个记账本的页面 ②可以添加数据并更新到页面中 ③可以将数据信息以图表的形式展现 (一)首先,制作一个记账本的页面. ①在系统自 ...

  3. HTML 中清除浮动

    html中如何清除浮动   在html中,浮动可以说是比较常用的.在页面的布局中他有着很大的作用,但是浮动中存在的问题也是比较多的.现在我们简单说一下怎么去除浮动 首先我们先简单的看一下浮动: 首先我 ...

  4. GC原理---垃圾收集算法

    垃圾收集算法 Mark-Sweep(标记-清除算法) 标记清除算法分为两个阶段,标记阶段和清除阶段.标记阶段任务是标记出所有需要回收的对象,清除阶段就是清除被标记对象的空间. 优缺点:实现简单,容易产 ...

  5. win10搭建本地服务器(IIS)

    若想外网也可以访问使用NATAPP:https://natapp.cn/article/natapp_newbie 参考文章: https://segmentfault.com/a/119000001 ...

  6. spring5.0源码项目搭建

    一.准备相应环境以及下载spring项目 Ps:此处只讲解安装gradle 1.JDK安装 2.Idea安装 3.gradle安装 Gradle下载路径:https://services.gradle ...

  7. VS Code 1.42 发布!2020 年首个大更新

    近日(北京时间 2020 年 2 月 7 日),微软发布了 Visual Studio Code 1.42 版本,这也是 2020 年 VS Code 首次大更新.让我们来看看有哪些主要的更新. 支持 ...

  8. 06讲案例篇:系统的CPU使用率很高,但为啥却找不到高CPU的应用

    小结 碰到常规问题无法解释的 CPU 使用率情况时,首先要想到有可能是短时应用导致的问题,比如有可能是下面这两种情况. 第一,应用里直接调用了其他二进制程序,这些程序通常运行时间比较短,通过 top ...

  9. VirtualBox 安装ghost版windows XP

    昨天尝试在VirtualBox中安装深度技术的GhostXP SP3 V8.02版本的系统,可是安装过程中出现了问题,无法安装,错误提示如下图: 昨天搞了一会,没有结果,今天对于这个无法安装的问题耿耿 ...

  10. js笔记(1)--第一天记录

    刚刚接触JavaScript这门语言不久,所以希望每一次都记一点东西下来,巩固下知识. 首先,写了一个demo,是来计算两个数字的和的,如果直接把 v1=text1.value,和 v2=text2. ...