Unity识别图像主体位置
CoderZ1010 人气:0EasyDL图像分割介绍
创建应用
1.进入百度AI开放平台打开控制台:
2.在左上角打开产品服务列表,找到EasyDL零门槛AI开放平台:
3.打开EasyDL图像:
4.在公有云部署-应用列表中创建一个应用:
5.创建完成后获取到AppID、API Key、Secret Key:
创建模型
1.进入EasyGL图像分割:
2.创建模型:
3.创建数据集:
4.数据导入:
上传图片,图片的数量尽量多些
导入完成后查看并标注:
框选目标所在范围:
添加标签并为框选的目标设置标签:
设置完成后保存当前标注:
5.训练模型:(开始训练后需要等待一定时间)
6.发布模型:
发布完成后,拿到接口地址,来到Unity中,根据接口响应字段说明定义相应数据结构:
using System; [Serializable] public class ImageSegmentationResponse { /// <summary> /// 唯一的log id 用于问题定位 /// </summary> public int log_id; /// <summary> /// 标签数组结果 /// </summary> public ImageSegmentationResult[] results; } [Serializable] public class ImageSegmentationResult { /// <summary> /// 标签名称 /// </summary> public string name; /// <summary> /// 置信度 /// </summary> public string score; /// <summary> /// 位置 /// </summary> public Location location; /// <summary> /// 基于游程编码的字符串,编码内容为和原图宽高相同的布尔数组 /// 若数组值为0,代表原图此位置像素点不属于检测目标,若为1,代表原图此位置像素点属于检测目标 /// </summary> public bool[] mask; } [Serializable] public class Location { /// <summary> /// 目标定位位置的长方形左上顶点的水平坐标 /// </summary> public int left; /// <summary> /// 目标定位位置的长方形左上顶点的垂直坐标 /// </summary> public int top; /// <summary> /// 目标定位位置的长方形的宽度 /// </summary> public int width; /// <summary> /// 目标定位位置的长方形的高度 /// </summary> public int height; }
在任意一个模块下载C#SDK,例如在图像识别中下载,它是包含EasyDL的API内容的:
有了SDK后,放入Unity中的Plugins文件夹中,封装调用函数,只需要将检测图片的字节数据作为参数,其中appID、apiKey、secretKey是在上面创建应用时获取到的,url是发布模型时获取到的:
using System; using UnityEngine; /// <summary> /// 图像分割 /// </summary> public class ImageSegmentation { private const string appID = ""; private const string apiKey = ""; private const string secretKey = ""; private const string url = ""; public static ImageSegmentationResult[] SendRequest(byte[] bytes) { var client = new Baidu.Aip.EasyDL.EasyDL(appID, apiKey, secretKey); try { var response = client.requestImage(url, bytes); Debug.Log(response.ToString()); ImageSegmentationResponse r = JsonUtility.FromJson<ImageSegmentationResponse>(response.ToString()); return r.results; } catch (Exception error) { Debug.LogError(error); } return null; } }
测试图片:
测试代码:
using System.IO; using UnityEngine; public class Example : MonoBehaviour { private void Start() { ImageSegmentation.SendRequest(File.ReadAllBytes(Application.dataPath + "/1.jpg")); } }
返回结果:
拿到了定位数据后,接下来将其区域绘制出来, 响应说明中解释(left,top)构成左上顶点,但是从返回值来看top为16,减去一个高度312的话,左下顶点的坐标已经是负数,这里姑且猜想它构成的是左下顶点:
首先创建一个Image来放置我们的测试图片,Canvas、Image大小也设为测试图片的大小640 * 359:
以下是测试脚本,将其挂载于Image测试:
using System.IO; using UnityEngine; public class Example : MonoBehaviour { private void Start() { var results = ImageSegmentation.SendRequest(File.ReadAllBytes(Application.dataPath + "/测试.jpg")); for (int i = 0; i < results.Length; i++) { var location = results[i].location; LineRenderer line = new GameObject("LineRenderer").AddComponent<LineRenderer>(); line.positionCount = 4; line.loop = true; Vector2 leftTop = new Vector2(location.left, location.top); Vector2 rightTop = new Vector2(location.left + location.width, location.top); Vector2 leftBottom = new Vector2(location.left, location.top + location.height); Vector2 rightBottom = new Vector2(location.left + location.width, location.top + location.height); RectTransformUtility.ScreenPointToWorldPointInRectangle(transform as RectTransform, leftTop, Camera.main, out Vector3 point1); RectTransformUtility.ScreenPointToWorldPointInRectangle(transform as RectTransform, rightTop, Camera.main, out Vector3 point2); RectTransformUtility.ScreenPointToWorldPointInRectangle(transform as RectTransform, rightBottom, Camera.main, out Vector3 point3); RectTransformUtility.ScreenPointToWorldPointInRectangle(transform as RectTransform, leftBottom, Camera.main, out Vector3 point4); line.SetPosition(0, point1); line.SetPosition(1, point2); line.SetPosition(2, point3); line.SetPosition(3, point4); } } }
emmm... 区域大概准确吧,可能测试的模型数据集足够丰富的话检测会更精确。
加载全部内容