当前位置: 首页 > news >正文

Unity 百度AI实现无绿幕拍照抠像功能(详解版)

目录

一、前言

1.抠像效果

2.去哪找百度ai抠图

3.基础流程跳过 

二、获取AccessToken

1.什么是Token

2.为什么要获取Token

3.如何获取token

4.解析json

5.完整代码

三、抠像

1.准备地址

2.建立链接,和基本配置

3.图片格式转换

4.开始上传

5.获取回复

6.解析json

7.纯净代码

四、作者的碎碎念


一、前言

1.抠像效果

抠像效果一般,边缘还是会生硬,然后用羽化来过渡。(如图1所示)

图1 抠像

这是网上找的图,侵权删。

2.去哪找百度ai抠图

在百度,这个功能叫人像分割,链接如下。

人像分割技术_人像分割算法_人像分割-百度AI开放平台

3.基础流程跳过 

接下来注册账号之类的,咱就跳过了哈。

过程:
1.注册百度的账号

2.实名认证

3.领百度送的,对应功能的使用次数(我测试的时候送1w次,有效期一年)。

4.创建应用(这个不需要你有做好的程序,只需要走一下流程就行),这里走流程的意义就是,百度有很多功能,你需要什么功能选一下,然后我们给你一个账户和密码,这样你才能调用这些功能。

5.你就获得了一组账户和密码(如图2所示)

图2 账号和密码

api Key和Secret Key

api Key:api的英文是Application Programming Interface,应用程序编程接口的缩写,到这里就是我们获取了可以用来实现人像分割这个功能的用户名。

Secret Key:就是秘钥,上面用户名的密码。

上面两个Key,只要你自己不去更新,一般是不会改变的

但是,如果你的调用行为百度觉得很奇怪,也会暂时给你封了。

备注:百度ai有很多功能,假如百度ai是一个手机,手机里面装了很多个app,但是你登录每一个app都需要不同的用户名和密码。

这里就是,我们通过百度这个总的账号,去选择了自己想要的功能,然后百度给你生成一个用户名和密码,你通过这个可以使用你选好的功能。

二、获取AccessToken

1.什么是Token

不知道大家去过东北澡堂子没有,进去的时候,会被发一个手牌。(如图3所示)

图3 手牌

然后你只要带着这个手牌,就可以在澡堂子里吃饭,消费等,最后出来的时候,带着手牌去结账就行了。不同的手牌会有不同的权限,比如普通宾客,贵宾,vip,超级vip什么的。手牌上面还会有号码,号码就类似身份证号一样,大家都不一样,用来识别。

弄这个手牌的目的大致有两种:

1.澡堂子里有很多水,一直带着手机很麻烦,但不带手机,又会不知道你是哪一个宾客。

2.手机不能直观的看出来你是哪种宾客,但是牌子可以。

Token和这个手牌基本是一样的,你先把自己的账号和密码上交,根据你购买的套餐,会给你一串序列号,在一定的时间内,你只要提交序列号就可以用你购买的功能,百度也知道是哪个账号购买的。

2.为什么要获取Token

我们可以直接用账号和密码访问,我们也能使用token访问,但是,因为是用互联网传递消息,如果用账号和密码,那你每一次提出请求都要提供账户和密码,这样不是很安全,黑客一拦截一个准,所以,换成token,就减少了提交用户和密码的次数,就安全很多。

可以简单这么理解一下,至于细致的,大家可以自行百度,但总之,有这么一个流程。

3.如何获取token

这个可以在百度的官方文档中找到。在百度,这部分官方的名称叫做鉴权认证机制。

https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjhhu

想看官方的可以看官方的,或者看我的也可以。

获取token需要三个东西:

1.往哪个网站发请求

(上面的官方链接里有写,往https://aip.baidubce.com/oauth/2.0/token?发请求)

2.用户名(前言里获取过)

3.密码(前言里获取过)

在代码里,我们可以先把他们写出来。

我们的目的是获取token,我们可以再建一个字符串用来接token。(如图4所示)

图4 常用字符
 void Start(){GetToken();}public void GetToken(){//声明一个客户端,就是自己HttpClient client = new HttpClient();//建立一个字典,把我们需要的信息都放进去//但是建立字典的类型是KeyValuePair,因为我们后面要传递数据List<KeyValuePair<String, String>> paraList = new List<KeyValuePair<string, string>>();paraList.Add(new KeyValuePair<string, string>("client_id", client_id));paraList.Add(new KeyValuePair<string, string>("client_secret", client_secret));paraList.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));//这里本来要放httpContent,但是这个方法可以把//接受网络的回复                                               //keyValuePair转换成httpContentHttpResponseMessage response = client.PostAsync(token_url, new FormUrlEncodedContent(paraList)).Result;//最后接受回复,转换成stringstring resultJson = response.Content.ReadAsStringAsync().Result;//打印一下stringDebug.Log(resultJson);}

打印结果为:

图5 打印结果

你会得到一大堆数据,其中有一个部分是access_token,我们要的就是这部分,这部分就是token。

4.解析json

得到数据后,这个数据是json格式的数据,如果你会解析json数据,就可以自己解决了。

如果解决不了,你也可以采用string的手法直接弄出来。

up很懒,用了一个叫LitJson.dll,里面直接有解析的方法。

        //先读取json格式的文本JsonReader json = new JsonReader(resultJson);//把上面读取的文本转换成可以直接调用的数据格式JsonData jsonData = JsonMapper.ToObject<JsonData>(json);//直接获取名称是access_token后面的数据        jsonData["access_token"].ToString();
5.完整代码
using System;
using System.Collections.Generic;
using System.Net.Http;
using LitJson;
using UnityEngine;public class GetAccessToken : MonoBehaviour
{//网址string token_url = "https://aip.baidubce.com/oauth/2.0/token?";//用户名string client_id = "填自己的id";//密码string client_secret = "填自己的密码";//tokenpublic string token;void Start(){token = GetToken();Debug.Log("获得token:" + token);}public string GetToken(){HttpClient client = new HttpClient();List<KeyValuePair<String, String>> paraList = new List<KeyValuePair<string, string>>();paraList.Add(new KeyValuePair<string, string>("client_id", client_id));paraList.Add(new KeyValuePair<string, string>("client_secret", client_secret));paraList.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));HttpResponseMessage response = client.PostAsync(token_url, new FormUrlEncodedContent(paraList)).Result;string resultJson = response.Content.ReadAsStringAsync().Result;//Debug.Log(resultJson);JsonReader json = new JsonReader(resultJson);JsonData jsonData = JsonMapper.ToObject<JsonData>(json);return jsonData["access_token"].ToString();}
}

三、抠像

官方文档:https://ai.baidu.com/ai-doc/BODY/Fk3cpyxua

可以自己去研究,也可以往下看我的。

首先从官方那里拿到网址:

然后准备一下中途要用的方法(这些方法均不是重点,都不讲了)

方法1:图片从Texture转换到Texture2D

    //Texture转Texture2Dprivate Texture2D TextureToTexture2D(Texture texture){width = texture.width;height = texture.height;Texture2D texture2D = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, false);RenderTexture currentRT = RenderTexture.active;RenderTexture renderTexture = RenderTexture.GetTemporary(texture.width, texture.height, 32);Graphics.Blit(texture, renderTexture);RenderTexture.active = renderTexture;texture2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);texture2D.Apply();RenderTexture.active = currentRT;RenderTexture.ReleaseTemporary(renderTexture);return texture2D;}

方法2:图片从Texture2D转换为Base64

    //texture2D转base64public string TextureToBase64(Texture2D texture2D){byte[] bytes;bytes = texture2D.EncodeToPNG();return Convert.ToBase64String(bytes);}

方法3:Base64转texture2D

    //base转texture2Dpublic Texture2D Base64ToTexture2d(string base64){byte[] bytes = Convert.FromBase64String(base64);Texture2D tex = new Texture2D(width, height, TextureFormat.RGBA32, false);tex.LoadImage(bytes);return tex;}
1.准备地址

在前面给出地址的基础上,加上我们前面获取的token

//host地址
string host = "https://aip.baidubce.com/rest/2.0/image-classify/v1/body_seg?“+”access_token=" + token;
2.建立链接,和基本配置
//设置编码格式是默认
Encoding encoding = Encoding.Default;
//发送请求到前面配好的网址
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(host);
//这是前面要求的
request.Method = "post";
//一直保持链接
request.KeepAlive = true;
3.图片格式转换

这里假设我们有一个RawImage,名字叫photo,最后转换成buffer

//获取图片并转换成texture2D
Texture2D texture2D = TextureToTexture2D(photo.texture);
//再转换成base64
string base64 = TextureToBase64(texture2D);
//转换成url格式
string str = "image=" + HttpUtility.UrlEncode(base64);
//转换成byte格式
byte[] buffer = encoding.GetBytes(str);
4.开始上传
//获取长度
request.ContentLength = buffer.Length;
//发送请求
request.GetRequestStream().Write(buffer, 0, buffer.Length);
5.获取回复
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
string result = reader.ReadToEnd();
Debug.Log("人像分割:" + result);
6.解析json
JsonReader jr = new JsonReader(result);
JsonData data = JsonMapper.ToObject<JsonData>(jr);//拿到的扣好的数据
string picData = data["foreground"].ToString();
Texture2D tex = Base64ToTexture2d(picData);
7.纯净代码
 IEnumerator IBody_seg(){string host = "https://aip.baidubce.com/rest/2.0/image-classify/v1/body_seg?“+”access_token=" + token;Encoding encoding = Encoding.Default;HttpWebRequest request = (HttpWebRequest)WebRequest.Create(host);request.Method = "post";request.KeepAlive = true;yield return null;Texture2D texture2D = TextureToTexture2D(photo.texture);string base64 = TextureToBase64(texture2D);string str = "image=" + HttpUtility.UrlEncode(base64);byte[] buffer = encoding.GetBytes(str);request.ContentLength = buffer.Length;request.GetRequestStream().Write(buffer, 0, buffer.Length);yield return null;HttpWebResponse response = (HttpWebResponse)request.GetResponse();StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);string result = reader.ReadToEnd();Debug.Log("人像分割:" + result);yield return null;JsonReader jr = new JsonReader(result);JsonData data = JsonMapper.ToObject<JsonData>(jr);string picData = data["foreground"].ToString();Texture2D tex = Base64ToTexture2d(picData);//如果你有个image,可以使用图片pic.sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0, 0));pic2.sprite = pic.sprite;}

四、作者的碎碎念

如果有什么疑问,可以在评论区发出来讨论一下,我看见了会回复。

照片是直接在网上找的,侵权立删。

相关文章:

Unity 百度AI实现无绿幕拍照抠像功能(详解版)

目录 一、前言 1.抠像效果 2.去哪找百度ai抠图 3.基础流程跳过 二、获取AccessToken 1.什么是Token 2.为什么要获取Token 3.如何获取token 4.解析json 5.完整代码 三、抠像 1.准备地址 2.建立链接&#xff0c;和基本配置 3.图片格式转换 4.开始上传 5.获取回复…...

MySQL_表的基本操作

课 程 推 荐我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448;入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448;虚 拟 环 境 搭 建 &#xff1a;&#x1…...

【网站架构部署与优化】源码编译安装LAMP

文章目录 LAMP架构概述各组件的主要作用构建LAMP平台的安装顺序 编译安装Apache httpd服务指南1. 准备工作1.1 关闭防火墙并传输软件包1.2 安装环境依赖包 2. 配置软件模块2.1 解压软件包2.2 移动apr组件包2.3 配置httpd 3. 编译及安装4. 优化配置4.1 配置文件路径4.2 添加http…...

【Linux】Linux的基本指令(1)

A clown is always a clown.&#x1f493;&#x1f493;&#x1f493; 目录 ✨说在前面 &#x1f34b;知识点一&#xff1a;Linux的背景 •&#x1f330;1.Unix发展的历史 •&#x1f330;2.Linux发展历史 •&#x1f330;3.企业应用现状 •&#x1f330;4.发行版本 &…...

Python安装虚拟环境Conda

这里写自定义目录标题 Conda介绍Conda下载与安装下载地址安装检查是否安装成功Conda中的几个重要目录 envs、pkgspkgs文件夹envs文件夹 Conda 使用教学查看 Conda 自带库配置下载源设置下载时显示通道地址创建Conda 环境查看Conda 环境克隆环境Conda 环境导出环境配置从配置文件…...

基于STM32设计的烘干车间远程控制系统(腾讯云IOT)(228)

文章目录 一、前言1.1 项目介绍【1】项目背景【2】设计实现的功能【3】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】ESP8266工作模式配置1.3 项目开发背景【1】选题的意义【2】可行性分析【3】参考文献【4】项目背景【5】摘要1.4 开发工具的选择【1】设备端开发【2】上…...

Nginx泛域名 解析的匹配前缀绑定或转发到子目录

网站的目录结构为&#xff1a; # tree /home/wwwroot/landui.com /home/wwwroot/landui.com ├── bbs │ └── index.html └── www └── index.html 2 directories, 2 files /home/wwwroot/landui.com为nginx的安装目录下默认的存放源代码的路径。 bbs为论坛…...

黑神话悟空mac可以玩吗

黑神话悟空mac上能不能玩对于苹果玩家来说很重要&#xff0c;那么黑神话悟空mac可以玩吗&#xff1f;目前是玩不了了&#xff0c;没有针对ios系统的版本&#xff0c;只能之后在云平台上找找了&#xff0c;大家可以再观望下看看。 黑神话悟空mac可以玩吗 ‌使用CrossOver‌&…...

Nuxt Kit 中的插件:创建与使用

title: Nuxt Kit 中的插件:创建与使用 date: 2024/9/19 updated: 2024/9/19 author: cmdragon excerpt: 摘要:本文介绍了在 Nuxt 3 框架中使用 Nuxt Kit 创建和管理插件的方法,包括使用addPlugin注册插件、创建插件文件、在Vue组件中使用插件,以及使用addPluginTemplate…...

C++(虚构造与虚析构/类型信息运算符/强制类型转换)

一、虚构造与虚析构 1、构造函数能否是虚函数&#xff0c;为什么&#xff1f; 对象有创建过程&#xff1a; 1、给对象分配内存 2、根据继承表顺序调用父类构造 3、根据成员对象的的定义顺序调用成员对象的构造函数 4、执行对象自己的构造函数 如果父类的构造函数函数设计…...

python毕业设计基于django+vue医院社区医疗挂号预约综合管理系统7918h-pycharm-flask

目录 技术栈和环境说明预期达到的目标具体实现截图系统设计Python技术介绍django框架介绍flask框架介绍解决的思路性能/安全/负载方面可行性分析论证python-flask核心代码部分展示python-django核心代码部分展示操作可行性技术路线感恩大学老师和同学详细视频演示源码获取 技术…...

tidb 集群搭建

官网的搭建文档&#xff1a;使用 TiUP 部署 TiDB 集群 | TiDB 文档中心 我本地使用三台 centos7.9 服务器搭建&#xff0c;要保证三台服务器之间是可以互相通信的&#xff1b; 搭建集群的命令在其中一台服务器上执行即可&#xff1b; 1、安装tiup&#xff1a; curl --proto …...

SpringBoot开发——Spring Boot Controller 最佳实践

文章目录 1、RESTful接口地址的定义规则2、设计通用控制器基类3、统一的返回对象设计4、统一的异常处理5、实际案例: 订单控制器 (OrderController)结论 随着微服务架构的普及&#xff0c;RESTful API已经成为现代Web服务的标准设计模式。Spring Boot为开发者提供了强大的工具来…...

使用Ubuntu耳机输出正弦波信号

最近有一个项目想使用喇叭发出一个标准的正弦波测试信号&#xff0c;故记录下操作过程 sudo apt install libasound2-dev 否则有可能会报错&#xff1a; alsaaudio.c:28:10: fatal error: alsa/asoundlib.h: No such file or directory 安装pyalsaaudio&#xff1a; pip …...

Python编程 - 协程

前言 上篇文章主要讲述了python的进程&#xff0c;进程池和进程与线程对比等知识&#xff0c;接下来这篇文章再唠唠python的协程&#xff0c;让我们继续往下看&#xff01; 一、协程的使用 python 中的协程是一种用于处理并发任务的高效工具&#xff0c;它依赖于 asyncio 库以…...

如何在没有备份的情况下恢复 Mac 上丢失的数据

Mac 是您数字世界的中心。它上面可能保存着照片和视频等回忆&#xff0c;以及您不再联系的朋友和家人发来的旧电子邮件。您可能花了数小时导入整个 CD 收藏。您还可能保存着重要文档&#xff0c;例如演示文稿和工作文件、家庭账户或学校或大学的作业。 如果由于某种原因您丢失…...

SpringBoot:解析excel

解析Excel文件&#xff0c;可以使用Apache POI库 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version> </dependency> 上代码&#xff1a; /*** <b>Functio…...

Tomcat窗口运行修改窗口标题显示项目日期时间

1、修改配置文件catalina.bat文件 在Tomcat路径 bin文件夹下 set TITLETomcat.xxx.Server [%DATE% %TIME%] 显示&#xff1a;Tomcat.xxx,Server [2024/09.18 周三 12:01:30]...

8-----手机机型维修工具助手 功能较全 涵盖解锁 刷机 修复等选项 维修推荐

上图是一款功能较全的维修加密狗。目前可以无限制 任何人使用。看图片可以了解其中涵盖刷机 解锁 修复分区 查看短接图 安装驱动 修复基带等等选项。而且其中有针对各个机型型号的对应功能操作。以及一些rec5.0相关的操作选项。 通过此博文了解 ★★★★★此工具涵盖的一些…...

集群聊天服务器项目【C++】(四)cmake介绍和简单使用

我们上次用shell命令和vscode编译链接muduo库服务端代码&#xff0c;本章节实现编写CMakeLists.txt来编译项目。本次简单介绍CMake&#xff0c;并用Cmake编译上次的muduo服务器代码。 1.为什么使用cmake 我们在编译项目时&#xff0c;如果编写Makefile的话&#xff0c;常常会…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...