关键词:
今天去交社保,要白底的电子版照片,我目前手头就是一个蓝底的,又不想手动抠图,于是想做一个自动换背景的程序。
先上效果:
具体分三步,第一步是大体的背景转换,把蓝色变为白色:
void colortransfer(cv::Mat image) //蓝背景转白背景,有边缘残留 { int Diff; int num_row = image.rows; int num_col = image.cols; for (int r = 0; r < num_row; r++) { cv::Vec3b *data = image.ptr<cv::Vec3b>(r); for (int c = 0; c < num_col; c++) { Diff = data[c][0] - (data[c][1] + data[c][2]) / 2; //蓝色检测 if (Diff > 60 && data[c][0]>150)//蓝色分量比GR分量的平均值高60且蓝色分量大于150 { data[c][0] = 255; data[c][1] = 255; data[c][2] = 255; } } } }
但是这步出来之后效果不太好,可以看出来有很明显的蓝色边缘,很多蓝底照片因为照的时候和背景过近,导致边缘颜色变化
接下来就是对这些深色的蓝边进行一个处理,这里采用了检测蓝边->中值滤波器的方法:
void Optimization(cv::Mat image) //去边缘残留 { int num_row = image.rows; int num_col = image.cols; for (int i = 1; i < num_row-1; i++) { cv::Vec3b *last_r = image.ptr<cv::Vec3b>(i-1); cv::Vec3b *data = image.ptr<cv::Vec3b>(i); cv::Vec3b *next_r = image.ptr<cv::Vec3b>(i+1); for (int j = 1; j < num_col-1; j++) { if (data[j][0]>90 && data[j][0] - data[j][1]>9 && data[j][0] - data[j][2]>9) { int stat; cv::Vec3b Temp; cv::Vec3b array[9] = { last_r[j - 1], last_r[j], last_r[j + 1], data[j - 1], data[j], data[j + 1], next_r[j - 1], next_r[j], next_r[j + 1] }; do { stat = 0; for (int m = 0; m < 8; m++) { if (array[m][0] + array[m][1] + array[m][2]> array[m + 1][0] + array[m + 1][1] + array[m + 1][2]) { Temp=array[m + 1]; array[m + 1] = array[m]; array[m] = Temp; stat = 1; } } } while (stat == 1); data[j][0] = array[7][0]; data[j][1] = array[7][1]; data[j][2] = array[7][2]; } } } }
中间用了冒泡算法进行排序,结果如下:
边缘基本去除了,但是头发这边显得非常不真实,没有边缘的毛躁感。这里我们检测到头发边缘后,对边缘区域进行一个低通滤波和颜色的加白处理,让边缘有层次感:
void hairilization(cv::Mat image) //毛躁化 { int num_row = image.rows / 3; int num_col = image.cols; for (int i = 2; i < num_row - 2; i=i+5) { cv::Vec3b *last_sec_r = image.ptr<cv::Vec3b>(i - 2); cv::Vec3b *last_r = image.ptr<cv::Vec3b>(i - 1); cv::Vec3b *data = image.ptr<cv::Vec3b>(i); cv::Vec3b *next_r = image.ptr<cv::Vec3b>(i + 1); cv::Vec3b *next_sec_r = image.ptr<cv::Vec3b>(i + 2); for (int j = 2; j < num_col; j = j + 5) { int count = 0;// check how many 255point in this area(boundary) cv::Vec3b array[5][5] = { last_sec_r[j - 2], last_sec_r[j - 1], last_sec_r[j], last_sec_r[j + 1], last_sec_r[j + 2], \ last_r[j - 2], last_r[j - 1], last_r[j], last_r[j + 1], last_r[j + 2],\ data[j - 2], data[j - 1], data[j], data[j + 1], data[j + 2],\ next_r[j - 2], next_r[j - 1], next_r[j], next_r[j + 1], next_r[j + 2], \ next_sec_r[j - 2], next_sec_r[j - 1], next_sec_r[j], next_sec_r[j + 1], next_sec_r[j + 2]}; for (int r = 0; r < 5; r++) { for (int c = 0; c < 5; c++) { if (array[r][c][1] >= 251) count++; } } if (count >= 7 &&count<=18) //说明是头发边缘,开始处理 { last_r[j - 1] = 1 / 9 * (array[0][0] + array[0][1] + array[0][2] + array[1][0] + array[1][1] + array[1][2] + array[2][0] + array[2][1] + array[2][2]) + cv::Vec3b(100, 100, 100); last_r[j] = 1 / 9 * (array[0][1] + array[0][2] + array[0][3] + array[1][1] + array[1][2] + array[1][3] + array[2][1] + array[2][2] + array[2][3]) + cv::Vec3b(80, 80, 80); last_r[j + 1] = 1 / 9 * (array[0][2] + array[0][3] + array[0][4] + array[1][2] + array[1][3] + array[1][4] + array[2][2] + array[2][3] + array[2][4]) + cv::Vec3b(100, 100, 100); data[j - 1] = (1 / 9 * array[1][0] + 1 / 9 * array[1][1] + 1 / 9 * array[1][2] + 1 / 9 * array[2][0] + 1 / 9 * array[2][1] + 1 / 9 * array[2][2] + 1 / 9 * array[3][0] + 1 / 9 * array[3][1] + 1 / 9 * array[3][2]) + cv::Vec3b(80, 80, 80); data[j] = (1 / 9 * array[1][1] + 1 / 9 * array[1][2] + 1 / 9 * array[1][3] + 1 / 9 * array[2][1] + 1 / 9 * array[2][2] + 1 / 9 * array[2][3] + 1 / 9 * array[3][1] + 1 / 9 * array[3][2] + 1 / 9 * array[3][3]) + cv::Vec3b(80, 80, 80); data[j + 1] = (1 / 9 * array[1][2] + 1 / 9 * array[1][3] + 1 / 9 * array[1][4] + 1 / 9 * array[2][2] + 1 / 9 * array[2][3] + 1 / 9 * array[2][4] + 1 / 9 * array[3][2] + 1 / 9 * array[3][3] + 1 / 9 * array[3][4]) + cv::Vec3b(80, 80, 80); data[j - 1] = (1 / 9 * array[2][0] + 1 / 9 * array[2][1] + 1 / 9 * array[2][2] + 1 / 9 * array[3][0] + 1 / 9 * array[3][1] + 1 / 9 * array[3][2] + 1 / 9 * array[4][0] + 1 / 9 * array[4][1] + 1 / 9 * array[4][2]) + cv::Vec3b(100, 100, 100); data[j] = (1 / 9 * array[2][1] + 1 / 9 * array[2][2] + 1 / 9 * array[2][3] + 1 / 9 * array[3][1] + 1 / 9 * array[3][2] + 1 / 9 * array[3][3] + 1 / 9 * array[4][1] + 1 / 9 * array[4][2] + 1 / 9 * array[4][3]) + cv::Vec3b(80, 80, 80); data[j + 1] = (1 / 9 * array[2][2] + 1 / 9 * array[2][3] + 1 / 9 * array[2][4] + 1 / 9 * array[3][2] + 1 / 9 * array[3][3] + 1 / 9 * array[3][4] + 1 / 9 * array[4][2] + 1 / 9 * array[4][3] + 1 / 9 * array[4][4]) + cv::Vec3b(100, 100, 100); } } } }
这部分代码比较长,的所以隐藏了。
结果如下:
相比于:
可以看到头发的边缘上有很大提升,因为均值滤波把边缘的头发变浅,形成了一个层次感,模拟了在白幕照相的效果。
头像/证件照抠图与圣诞背景替换(代码片段)
CVPy抠图系列文章继续。1.头像/证件照抠图之前已经有过《一键智能抠图》、《【CV派】新玩法——AI一键抠图+素描》、《一键动物抠图,毛发毕现——人是不是动物?》、《如何从头训练一个一键抠图模型》几篇文章... 查看详情
如何用美图秀秀更改照片背景颜色
...步:先在右上角那里点击打开,打开需要更换背景颜色的证件照。如图:第二步:然后点击抠图笔。如图:第三步:点击抠图笔后,会出现三种抠图模式。选择自动抠图会方便操作。如图:第四步:这时要用抠图笔在证件照人物... 查看详情
[数字媒体]photoshop基础之图像校正抠图(证件照)和融合
...频制作、动画制作等内容。希望您喜欢~文章目录一.Excel证件照换背景二.PS图像校正三.PS抠图四.PS图像融合五.总结一.Excel证件照换背景大家在找工作或面试过程中,通常会遇到证件照替换背景的问题,下面介绍Excel替换背... 查看详情
[数字媒体]photoshop基础之图像校正抠图(证件照)和融合
...频制作、动画制作等内容。希望您喜欢~文章目录一.Excel证件照换背景二.PS图像校正三.PS抠图四.PS图像融合五.总结一.Excel证件照换背景大家在找工作或面试过程中,通常会遇到证件照替换背景的问题,下面介绍Excel替换背... 查看详情
gimp抠图/证件照背景色
1.选区2.enter确定3.增加alpha通道。图层菜单-->透明-->添加alpha通道。目的是为了选区最终确定后,删除选区之外的部分到透明。4.最终抠取图像。选择菜单-->反转;编辑菜单-->清除。抠取图像成功。文件菜单-->导出为…... 查看详情
ps证件照换背景
综述博主原创内容。在PS里,对于抠图,比较有技术含量的便是抠头发丝了,下面为大家带来一个比较详细的抠头发丝的教程。素材准备在这里我们用这张图片作为抠图素材,下面让我们一步步来演示抠图的过程,并为之更换背... 查看详情
证件照制作如此简单——基于人脸检测与自动人像分割轻松制作个人证件照(c++实现)(代码片段)
...iOS上,性能都是不错的。4.我的开发环境是win10,vs2019,opencv4.5,ncnn,如果要启用GPU加速,所以用到VulkanSDK,实现语言是C++。5.先上效果图,对于背景纯度的要求不高,如果使用场景背景复杂的话,也可以... 查看详情
求问怎么把照片裁剪成证件照?希望可以批量处理的。
...(例如通过邮箱、群等方式),然后再统一处理成规定的证件照格式,这样对于用户来说也是比较方便的,特别是用户群体是不方便使用手机自己操作的群体,例如老年人、采集人、中小学生等。此时我们可以借助这个方法:1... 查看详情
opencv这么简单为啥不学——1.11蓝背景证件照替换白色或红色(代码片段)
OpenCV这么简单为啥不学——1.11、蓝背景证件照替换白色或红色目录OpenCV这么简单为啥不学——1.11、蓝背景证件照替换白色或红色前言蓝背景证件照替换白色蓝背景证件照替换红色总结颜色空间HSV颜色空间前言计算机视觉市场巨... 查看详情
opencv——floodfill漫水填充,证件照换背景(代码片段)
漫水填充:floodFill函数简单来说,漫水填充就是自动选中与种子像素相连的区域,利用指定颜色进行区域颜色填充。Windows画图工具中的油漆桶功能和Photoshop的魔法棒选择工具,都是漫水填充的改进和延伸。//第一个版本intfloodFill... 查看详情
opencv-实现背景分离(可用于更改证件照底色)(代码片段)
作者:Steven版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处实现原理 图像背景分离是常见的图像处理方法之一,属于图像分割范畴。如何较优地提取背景区域,... 查看详情
怎么在手机上把照片背景换颜色
...进行更换即可。 参考技术C我看朋友都是在手机上制作的证件照,非常快全自动,电子照直接下载,纸质可快递,底色自己选。1、支付宝首页或微信搜:照点点。2、点击进入照点点,选择寸照或热门证件。3、对着自己拍或者上... 查看详情
photoshopps证件照照片换底色
photoshop证件照换底色原理大体步骤,选中头像,抠出来,保存为新图层;将原图层填充为目标颜色,新图层覆盖到原图层上,就实现了修改背景色;抠出头像最顶部工具栏,选择-------主体,放... 查看详情
photoshopps证件照照片换底色
photoshop证件照换底色原理大体步骤,选中头像,抠出来,保存为新图层;将原图层填充为目标颜色,新图层覆盖到原图层上,就实现了修改背景色;抠出头像最顶部工具栏,选择-------主体,放... 查看详情
昨晚,我用python帮学妹p证件照自拍,然后发现。。。(代码片段)
人生苦短,我用Python前因后果先上效果准备工作证件照尺寸调整证件照背景调整各种背景颜色图片完整代码结尾最后前因后果事情是这样的晚上我正在聚精会神写代码(打游戏~)突然,收到学妹给我发来的消息还... 查看详情
我有证件照,但没有电子版证件照,现急需电子版证件照,请问如何获取?
...议你这样试试看:1、最佳解决方案可以通过打印机扫描证件,这样才能保证证件的清晰程度。操作步骤:①、首先将证件放在打印机扫描处,摆放端正,盖上盖子。(如图所示)②、在电脑端桌面左下角,点击圆形win图标,在... 查看详情
制作证件照电子档
最近办理了新证件,一直随身携带着感觉又很麻烦,今天突然想到了原来的老办法,制作一个电子档,随时随地可以用。查看了很多网站,竟然没有找到理想的方法,特此记录。一种:有手机,拍照功能强悍,可以就此用手... 查看详情
可换服装的证件照软件免费下载
想必大家都知道,各种标准的证件照制作都是有一定的要求,而在证件照服装上的严格要求就是其中一项,证件照服装都要求是正装。在照片采集时,如果需要用户都是在穿正装的时候拍照,多少会给用户带来一定的不便。而通... 查看详情