Unity实现识别图像中主体及其位置

 更新时间:2022年02月21日 09:32:33   作者:CoderZ1010  
EasyDL基于飞桨开源深度学习平台,面向企业AI应用开发者提供零门槛AI开发平台,实现零算法基础定制高精度AI模型。本文将利用Unity和EasyDL实现识别图像中主体及其位置,感兴趣的可以了解一下

EasyDL图像分割介绍

创建应用

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... 区域大概准确吧,可能测试的模型数据集足够丰富的话检测会更精确。

以上就是Unity实现识别图像中主体及其位置的详细内容,更多关于Unity的资料请关注脚本之家其它相关文章!

相关文章

  • C#正方形图片的绘制方法

    C#正方形图片的绘制方法

    这篇文章主要为大家详细介绍了C#正方形图片的绘制方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-10-10
  • C#实现扑克游戏(21点)的示例代码

    C#实现扑克游戏(21点)的示例代码

    21点又名黑杰克,该游戏由2到6个人玩,使用除大小王之外的52张牌,游戏者的目标是使手中的牌的点数之和不超过21点且尽量大。本文将用C#实现这一经典游戏,需要的可以参考一下
    2022-08-08
  • 向一个数组中插入一个1~100的随机数

    向一个数组中插入一个1~100的随机数

    这篇文章主要介绍了如何向一个数组中插入一个1~100的随机数,思路很简单,需要的朋友可以参考下
    2014-07-07
  • c#线程同步使用详解示例

    c#线程同步使用详解示例

    这篇文章主要介绍了c#线程同步使用方法,介绍几种常用的C#进行线程同步的方式,需要的朋友可以参考下
    2014-02-02
  • C#中const用法详解

    C#中const用法详解

    这篇文章主要介绍了C#中const用法,实例分析了C#中const的用法及使用技巧,并对比分析了readonly关键字与const关键字的不同,需要的朋友可以参考下
    2014-11-11
  • c#使用资源文件的示例

    c#使用资源文件的示例

    对于资源文件的使用,说白点就是通过强制类型转换,将资源文件里的数据强行的转换成你需要的,换种方式说,就是你原来存进去什么,就用什么类型拿出来,下面我们学习一下c#使用资源文件的方法
    2014-01-01
  • C#如何动态创建lambda表达式

    C#如何动态创建lambda表达式

    这篇文章主要介绍了C#如何动态创建lambda表达式问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • C# ManualResetEvent使用方法详解

    C# ManualResetEvent使用方法详解

    这篇文章主要为大家详细介绍了ManualResetEvent使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • c#设计模式之单例模式的实现方式

    c#设计模式之单例模式的实现方式

    这篇文章主要给大家介绍了关于c#设计模式之单例模式的实现方式,文中通过示例代码介绍的非常详细,对大家的学习或者使用c#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-11-11
  • 基于WPF实现边缘停靠效果

    基于WPF实现边缘停靠效果

    这篇文章主要为大家信息介绍了如何基于WPF实现边缘停靠效果,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01

最新评论