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

embedded/2024/9/22 17:23:25/

目录

一、前言

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;}

四、作者的碎碎念

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

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


http://www.ppmy.cn/embedded/115148.html

相关文章

第十三章:使用html和css做一个静态登录网页练习

我们在使用浏览器 浏览某些网站的时候 有可能会遇到登录这种网页,这种网页是怎么制作出来的呢? 下面 我就来分享一个简单的 登录页 实现方案! 登录页面的作用: 身份验证:登录页面的核心作用就是验证用户身份。用户输入用户名(或邮箱、手机号)和密码,系统通过验证来判断…

中级蜜蜂饲喂管理一

蜂群的箱外观察 在巢外的活动和现象就能大致推断蜂群内部的情况。通过箱外观察,了解蜂群这项工作随时都可以进行,尤其是在特殊的环境条件下,蜂群不适宜开箱检查时,箱外观察更为常用。 全场蜂群普遍出现外勤工蜂进出巢繁忙,巢门拥挤,归巢的工蜂腹部饱满沉重,夜晚煽风声较…

HarmonyOS开发者基础认证考试试题

文章目录 一、判断题二、单选题三、多选题 因考试只有91分&#xff0c;所以下方答案有部分错误&#xff0c;如果有发现错误&#xff0c;欢迎提出 一、判断题 1. HarmonyOS提供了基础的应用加固安全能力&#xff0c;包括混淆、加密和代码签名能力 正确 2. 用户首选项是关系型数…

【BurpSuite】Cross-site scripting (XSS 学徒部分:1-9)

&#x1f3d8;️个人主页&#xff1a; 点燃银河尽头的篝火(●’◡’●) 如果文章有帮到你的话记得点赞&#x1f44d;收藏&#x1f497;支持一下哦 【BurpSuite】Cross-site scripting (XSS 学徒部分:1-9&#xff09; 实验一 Lab: Reflected XSS into HTML context with nothing…

NCNN 源码(1)-模型加载-数据预处理-模型推理

参考 ncnn 第一个版本的代码。 0 整体流程 demo&#xff1a;squeezenet ncnn 自带的一个经典 demo&#xff1a;squeezenet 的代码: // 网络加载 ncnn::Net squeezenet; squeezenet.load_param("squeezenet_v1.1.param"); squeezenet.load_model("squeezenet_…

6、论文阅读:水下图像增强基准数据集及其他数据集

水下图像增强基准数据集及其他数据集 前言引言贡献现有方法、评估指标和数据集:概述水下增强方法基于补充信息的方法基于非物理模型的方法基于物理模型的方法数据驱动的方法水下图像质量评估完整参考指标没有参考指标水下图像数据集提出基准数据集数据收集参考图像的生成评估与…

连续数组问题

目录 一题目&#xff1a; 二思路&#xff1a; 三代码&#xff1a; 一题目&#xff1a; leetcode链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 二思路&#xff1a; 思路&#xff1a;前缀和&#xff08;第二种&#xff09;化0为-1hash&#xff1a; 这样可以把…

Vue使用代理方式解决跨域问题

1、解决跨域问题 如果 Vue 前端应用请求后端 API 服务器&#xff0c;出现跨域问题&#xff08;CORS&#xff09;&#xff0c;如下图&#xff1a; 解决方法&#xff1a;在 Vue 项目中&#xff0c;打开 vue.config.js 配置文件&#xff0c;在配置文件中使用代理解决跨域问题。 …