opencv —— floodFill 漫水填充法 实现证件照换背景
漫水填充: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 漫水填充法 实现证件照换背景的更多相关文章
- HDU - 1241 POJ - 1562 Oil Deposits DFS FloodFill漫水填充法求连通块问题
Oil Deposits The GeoSurvComp geologic survey company is responsible for detecting underground oil de ...
- Opencv之漫水填充效果
下面是opencv的漫水填充效果代码 这篇文章仅限个人的笔记 没有详细的注释 放代码 这是简单的示范 int main()//*******************简单的漫水填充算法实例 { Vide ...
- 【OpenCV】漫水填充
漫水填充:也就是用一定颜色填充联通区域,通过设置可连通像素的上下限以及连通方式来达到不同的填充效果;漫水填充经常被用来标记或分离图像的一部分以便对其进行进一步处理或分析,也可以用来从输入图像获取掩码区 ...
- DFS求连通块(漫水填充法)
G - DFS(floodfill),推荐 Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I6 ...
- PS证件照换背景
综述 博主原创内容. 在PS里,对于抠图,比较有技术含量的便是抠头发丝了,下面为大家带来一个比较详细的抠头发丝的教程. 素材准备 在这里我们用这张图片作为抠图素材,下面让我们一步步来演示抠图的过程,并 ...
- 【OpenCV新手教程之十五】水漫金山:OpenCV漫水填充算法(Floodfill)
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/28261997 作者:毛星云( ...
- OpenCV3编程入门笔记(4)腐蚀、膨胀、开闭运算、漫水填充、金字塔、阈值化、霍夫变换
腐蚀erode.膨胀dilate 腐蚀和膨胀是针对图像中的白色部分(高亮部分)而言的,不是黑色的.除了输入输出图像外,还需传入模板算子element,opencv中有三种可以选择:矩形MORPH_RE ...
- opencv 4 图像处理(漫水填充,图像金字塔与图片尺寸缩放,阈(yu)值化)
漫水填充 实现漫水填充算法:floodFill函数 简单调用范例 #include <opencv2/opencv.hpp> #include <opencv2/imgproc/im ...
- OpenCV漫水填充算法示例代码
#include<cv.h> #include<highgui.h> int main(int argc, char** argv) { IplImage* img = cvL ...
随机推荐
- mysql--->mysql查看数据库操作记录
mysql查看数据库操作记录 MySQL的查询日志记录了所有MySQL数据库请求的信息.无论这些请求是否得到了正确的执行.默认文件名为hostname.log.默认情况下MySQL查询日志是关闭的.生 ...
- mvc jQuery 点击按钮实现导出Excel功能 参数长短不限
var exportSubmit=function(url, obj){ var form = $("<form>"); //定义一个form表单 form.attr( ...
- AcWing 787.归并排序
AcWing 787.归并排序 题目描述 给定你一个长度为n的整数数列. 请你使用归并排序对这个数列按照从小到大进行排序. 并将排好序的数列按顺序输出. 输入格式 输入共两行,第一行包含整数 n. 第 ...
- 三、Linux系统中的文件类型和文件扩展名
.sock文件也是一类特殊的文件,这类文件通常用在网络之间进行数据连接,如:我们可以启动一个程序来监听客户端的要求,客户端可以通过套接字来进行通信: linux中的文件类型 文件类型介绍 Linux系 ...
- 部署 harbor 私有仓库
安装下载依赖包 安装docker-compose 从 docker compose 发布页面下载最新的 docker-compose 二进制文件,本文以1.25.4为例 cd /opt/k8s/wor ...
- Jmeter之安装与环境配置
前言 本次的教程是Jmeter的安装与配置 1.安装JDK并配置好环境变量,在系统变量中添加JAVA_HOME变量 在系统变量path中添加 %JAVA_HOME%\bin 2.打开Jmeter官网: ...
- Java 添加、读取、删除Excel文档属性
在文档属性中,可以设置诸多关于文档的信息,如创建时间.作者.单位.类别.关键词.备注等摘要信息以及一些自定义的文档属性.下面将通过Java程序来演示如何设置,同时对文档内的已有信息,也可以实现读取和删 ...
- 《自拍教程17》Python调用命令
他山之石 何为他山之石,就是借助外界工具,来实现自己想要的功能. 命令行界面软件, 即各种命令,我们也叫命令行工具, 此类工具也是测试人员或者开发人员常用的工具的一种. 测试人员可以借助这类工具,快速 ...
- k8s系列---service
来源 : http://blog.itpub.net/28916011/viewspace-2214745/ service是要通过coreDNS来管理pod的. kube-proxy始终监视着api ...
- [CSS]三大特性之一继承性、层叠性、优先级
<style> div { color: red; font-size: 30px; {#background: #0066ff;#} } </style> <!-- 1 ...