Java + openCV更换证件照背景色

最近在小红书上看到很多更换证件照背景色的需求,联想到以前自己也更换过证件照背景色而且还是付费的,碰巧最近在看一本书《Java+OpenCV高效入门》,于是查找资料,找到了通过技术解决这个需求的办法。
先看效果图(图片来自网络,如有侵权,请联系我删除):
在这里插入图片描述

在这里插入图片描述下面直接上代码,只需要一个函数就可以了:

/*** 算法实现步骤:* 1、加载原图像* 2、制作kmeans输入参数所需要的数据(kmeans的输入数据类型是CV_32F,所以不能直接使用原始图像的数据,因为原始图像的数据类型为CV_8UC1)* 3、使用kmeans算法实现图像分类,并得到分类标签* 4、创建遮罩:通过分类标签,将背景部分的颜色标记位0,将前景(人物)像素值标记位255* 5、先对mask执行形态学操作去除干扰的白点,在使用高斯模糊平滑前景和背景之前的过度* 6、创建一个3通道的目标输出结果Mat,然后将目标背景填充到背景区域,将前景部分填充到前景区域。* 7、输出图像* ps:算法的核心步骤其实就是找到mask,当mask找到之后就可以使用分类标签将背景和前景替换成为自己想要的像素。* 参考:https://www.cnblogs.com/tony-yang-flutter/p/16153446.html* @param photoPath  本地图片路径* @param rgbEnd  目标背景色* @return*/@Overridepublic Mat changePhotoBackgroundColor(String photoPath, double[] rgbBeg, double[] rgbEnd) {Mat src = Imgcodecs.imread(photoPath);//制作kmeans需要的数据int width = src.cols();int height = src.rows();int dims = src.channels();int sampleCount = width*height;//总共的像素点Mat points = new Mat(sampleCount, dims, CvType.CV_32F,new Scalar(10));int index = 0;for(int row = 0;row<height;row++){for(int col = 0;col<width;col++){index = row * width + col;double[] bgr = src.get(row, col);points.put(index,0, bgr[0]);points.put(index,1, bgr[1]);points.put(index,2, bgr[2]);}}int numCluster = 4;//多少个分类Mat labels = new Mat();//分类标签Mat centers = new Mat();//中心点TermCriteria criteria = new TermCriteria(TermCriteria.EPS + TermCriteria.COUNT, 10, 0.1);kmeans(points,numCluster,labels,criteria,3,KMEANS_PP_CENTERS,centers);//创建遮罩Mat mask = Mat.zeros(src.size(),CvType.CV_8UC1);//找到背景像素的像素点位置index = src.rows() * 2 + 2;//找到像素点位置在labels中所对应的标签,找到这个标签以后就可以根据这个标签来判断前景和背景double[] cIndex = labels.get(index,0);for(int row=0;row<height;row++){for(int col=0;col<width;col++){index = row*width+col;double[] label = labels.get(index, 0);if(label[0] == cIndex[0]){//背景mask.put(row, col, 0);}else{//前景mask.put(row, col, 255);}}}//使用形态学腐蚀操作取出遮罩中的可能干扰正常结果的白点Mat kernel = getStructuringElement(MORPH_RECT,new Size(3,3),new Point(-1,-1));erode(mask,mask,kernel);//使用高斯模糊平滑边缘像素GaussianBlur(mask,mask,new Size(3,3),0,0);//执行图像像素融合,执行最终的背景替换,定义背景颜色double[] bgColor = new double[3];bgColor[0] = rgbEnd[2];bgColor[1] = rgbEnd[1];bgColor[2] = rgbEnd[0];//定义一个空的彩色图片Mat result = Mat.zeros(src.size(),CvType.CV_8UC3);//下面是背景融合的代码double w = 0.0;double b = 0, g = 0, r = 0;double b1 = 0, g1 = 0, r1 = 0;double b2 = 0, g2 = 0, r2 = 0;for(int row = 0;row<height;row++){for(int col=0;col<width;col++){double[] pix = mask.get(row,col);//获取像素值if(pix[0] == 255){//前景result.put(row, col, src.get(row,col));}else if(pix[0] == 0){//背景result.put(row, col, bgColor);}else{//需要像素融合的部分w = pix[0] / 255.0;//权重b1 = src.get(row,col)[0];g1 = src.get(row,col)[1];r1 = src.get(row,col)[2];b2 = bgColor[0];g2 = bgColor[1];r2 = bgColor[2];b = b1*w+b2*(1.0-w);g = g1*w+g2*(1.0-w);r = r1*w+r2*(1.0-w);result.put(row, col, b, g, r);}}}return result;}

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

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

相关文章

62 权限提升-烂土豆dll劫持引号路径服务权限

目录 演示案例:Win2012-烂士豆配合令牌窃取提权-Web权限Win2012-DLL劫持提权应用配合MSF-Web权限Win2012-不安全的服务权限配合MSF-本地权限Win2012-不带引号服务路径配合MSF-Web&#xff0c;本地权限补充说明: dll劫持提权及AlwaysInstallElevated等说明关于Windows相关知识点…

yo!这里是异常相关介绍

目录 前言 异常的概念 异常的抛出与捕获 捕获过程 重新抛出 规范 异常体系 自定义 标准库 异常的优缺点 后记 前言 对于程序运行时发生的错误&#xff0c;比如内存错误、除0错误等类型&#xff0c;你会如何处理&#xff1f;是使用assert终止程序或是使用exit返回错误…

Linux系统---僵尸进程、孤儿进程

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 键盘敲烂&#xff0c;年薪百万&#xff01; 有了上一篇博客的学习&#xff0c;我们已经简单了解了进程的基础知识&#xff0c;今天我们再来学习两个特殊的进程&#xff0c;僵尸进程和孤儿进程。 …

7000字详解 动态代理(JDK动态代理 CGLIB动态代理)与静态代理

代理模式 1. 代理模式 概念2. 静态代理3. 动态代理3.1.JDK动态代理3.2.CGLIB动态代理3.3. JDK动态代理和CGLIB动态代理区别 4.静态代理和动态代理区别5.篇末 1. 代理模式 概念 代理模式是一种设计模式。 使用代理对象来替代真实对象&#xff0c;用代理对象去访问目标对象。这样…

虚拟化逻辑架构: LBR 网桥基础管理

目录 一、理论 1.Linux Bridge 二、实验 1.LBR 网桥管理 三、问题 1.Linux虚拟交换机如何增删 一、理论 1.Linux Bridge Linux Bridge&#xff08;网桥&#xff09;是用纯软件实现的虚拟交换机&#xff0c;有着和物理交换机相同的功能&#xff0c;例如二层交换&#…

百面深度学习-自然语言处理

自然语言处理 神经机器翻译模型经历了哪些主要的结构变化&#xff1f;分别解决了哪些问题&#xff1f; 神经机器翻译&#xff08;Neural Machine Translation, NMT&#xff09;是一种使用深度学习技术来实现自动翻译的方法。自从提出以来&#xff0c;NMT模型经历了几个重要的…

HTTP协议发展

HTTP 1.0 -> HTTP 1.1 -> HTTP 2.0 -> HTTP 3.0 (QUIC) 每一代HTTP解决了什么问题&#xff1f; 下图说明了主要功能。 HTTP 1.0 于 1996 年最终确定并完整记录。对同一服务器的每个请求都需要单独的 TCP 连接。 HTTP 1.1 于 1997 年发布。TCP 连接可以保持打开状态…

openGauss学习笔记-132 openGauss 数据库运维-查看openGauss状态

文章目录 openGauss学习笔记-132 openGauss 数据库运维-查看openGauss状态132.1 背景信息132.2 前提条件132.3 操作步骤132.4 参数说明132.5 示例 openGauss学习笔记-132 openGauss 数据库运维-查看openGauss状态 132.1 背景信息 openGauss支持查看整个openGauss的状态&#…

如何在Linux系统安装Nginx并启动

Nginx的介绍 Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器。其特点是占有内存少&#xff0c;并发能力强&#xff0c;事实上nginx的并发能力在同类型的网页服务器中表现较好。官网&#xff1a;nginx newsNginx的下载 前往…

docker基础学习笔记

文章目录 Docker简介Linux下安装DockerDocker常用命令Docker网络Docker存储docker-composedockerfile制作镜像私有仓库镜像导入导出参考 Docker简介 定义&#xff1a;Docker是一个开源的应用容器引擎优势&#xff1a; 一键部署&#xff0c;开箱即用&#xff1a;容器使用基于im…

Qt5.15.2静态编译 VS2017 with static OpenSSL

几年前编译过一次Qt静态库:VS2015编译Qt5.7.0生成支持XP的静态库,再次编译,毫无压力。 一.环境 系统:Windows 10 专业版 64位 编译器:visual studio 2017 第三方工具:perl,ruby和python python用最新的3.x.x版本也是可以的 这三个工具都需要添加到环境变量,安装时勾选…

057-第三代软件开发-文件监视器

第三代软件开发-文件监视器 文章目录 第三代软件开发-文件监视器项目介绍文件监视器实现原理关于 QFileSystemWatcher实现代码 关键字&#xff1a; Qt、 Qml、 关键字3、 关键字4、 关键字5 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&…

人工智能时代的内容写作

内容不再只是王道&#xff0c;正如俗话所说&#xff1a;它是一种流动的货币&#xff0c;推动了巨大的在线信息和影响力经济。 每个品牌都是一个故事&#xff0c;通过其服务和商品讲述自己。尽管如此&#xff0c;大多数客户还是会通过您的在线内容最了解您。 但随着我们进入人…

每日一题:LeetCode-LCR 143.子结构判断

每日一题系列&#xff08;day 05&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50e…

汇编:关于栈的知识

1.入栈和出栈指令 2. SS与SP 3. 入栈与出栈 3.1 执行push ax ↑↑ 3.2 执行pop ax ↓↓ 3.3 栈顶超界的问题 4. 寄存器赋值 基于8086CPU编程时&#xff0c;可以将一段内存当作栈来使用。一个栈段最大可以设为64KB&#xff08;0-FFFFH&#xff09;。 1.入栈和出栈指令…

C语言——函数

导读 &#xff1a; 这篇文章主要讲解一下C语言函数的一些基本知识。 前言&#xff1a;函数的概念 C语言中的函数又常常被称为子程序&#xff0c;是用来完成某项特定的工作的一段代码。就像我们生活中的模块化建造技术&#xff0c;类比模块化建房子的过程&#xff1a;整个程序…

高校大学校园后勤移动报修系统 微信小程序uniapp+vue

本文主要是针对线下校园后勤移动报修传统管理方式中管理不便与效率低的缺点&#xff0c;将电子商务和计算机技术结合起来&#xff0c;开发出管理便捷&#xff0c;效率高的基于app的大学校园后勤移动报修app。该系统、操作简单、界面友好、易于管理和维护&#xff1b;而且对后勤…

Python中类的定义和使用细讲

文章目录 前言一、定义类二、创建类的实例三、创建 _ _ init _ _() 方法四、创建类的成员并访问1. 创建实例方法并访问2. 创建数据成员并访问 五、访问限制 前言 在 Python 中&#xff0c;类表示具有相同属性和方法的对象的集合。在使用类时&#xff0c;需要先定义类&#xff0…

Android安卓设置跳转默认应用商店为Google Play 链接跳转到谷歌商店临时解决方法

手机链接默认不跳转 Google Play 因为大部分安卓厂商系统都根据了自己的需求进行了修改,就成为了系统级导流,想要彻底解除可刷写国际版等原生系统即可恢复 解决方法 使用冻结软件(例如 爱玩机手机助手(root)等应用)对 应用商城 进行临时冻结,如需保证正常使用解除冻结状态即可…

清分系统对账

流程1的问题&#xff1a; 1、通道一天的数据会有多少&#xff0c;有二三十万条交易数据吗&#xff1f; 2、如果数据过大都存到一个Map里面去&#xff0c;机器不得挂了 步骤1总结&#xff1a; 1、通过channelNo获取通道T的数据&#xff0c;因为通道是一天一个文件给过来。在转…