Unity實現(xiàn)識別圖像中主體及其位置
EasyDL圖像分割介紹

創(chuàng)建應(yīng)用
1.進入百度AI開放平臺打開控制臺:

2.在左上角打開產(chǎn)品服務(wù)列表,找到EasyDL零門檻AI開放平臺:

3.打開EasyDL圖像:

4.在公有云部署-應(yīng)用列表中創(chuàng)建一個應(yīng)用:

5.創(chuàng)建完成后獲取到AppID、API Key、Secret Key:

創(chuàng)建模型
1.進入EasyGL圖像分割:

2.創(chuàng)建模型:


3.創(chuàng)建數(shù)據(jù)集:


4.數(shù)據(jù)導(dǎo)入:

上傳圖片,圖片的數(shù)量盡量多些

導(dǎo)入完成后查看并標(biāo)注:

框選目標(biāo)所在范圍:

添加標(biāo)簽并為框選的目標(biāo)設(shè)置標(biāo)簽:

設(shè)置完成后保存當(dāng)前標(biāo)注:

5.訓(xùn)練模型:(開始訓(xùn)練后需要等待一定時間)

6.發(fā)布模型:

發(fā)布完成后,拿到接口地址,來到Unity中,根據(jù)接口響應(yīng)字段說明定義相應(yīng)數(shù)據(jù)結(jié)構(gòu):

using System;
[Serializable]
public class ImageSegmentationResponse
{
/// <summary>
/// 唯一的log id 用于問題定位
/// </summary>
public int log_id;
/// <summary>
/// 標(biāo)簽數(shù)組結(jié)果
/// </summary>
public ImageSegmentationResult[] results;
}
[Serializable]
public class ImageSegmentationResult
{
/// <summary>
/// 標(biāo)簽名稱
/// </summary>
public string name;
/// <summary>
/// 置信度
/// </summary>
public string score;
/// <summary>
/// 位置
/// </summary>
public Location location;
/// <summary>
/// 基于游程編碼的字符串,編碼內(nèi)容為和原圖寬高相同的布爾數(shù)組
/// 若數(shù)組值為0,代表原圖此位置像素點不屬于檢測目標(biāo),若為1,代表原圖此位置像素點屬于檢測目標(biāo)
/// </summary>
public bool[] mask;
}
[Serializable]
public class Location
{
/// <summary>
/// 目標(biāo)定位位置的長方形左上頂點的水平坐標(biāo)
/// </summary>
public int left;
/// <summary>
/// 目標(biāo)定位位置的長方形左上頂點的垂直坐標(biāo)
/// </summary>
public int top;
/// <summary>
/// 目標(biāo)定位位置的長方形的寬度
/// </summary>
public int width;
/// <summary>
/// 目標(biāo)定位位置的長方形的高度
/// </summary>
public int height;
}在任意一個模塊下載C#SDK,例如在圖像識別中下載,它是包含EasyDL的API內(nèi)容的:

有了SDK后,放入Unity中的Plugins文件夾中,封裝調(diào)用函數(shù),只需要將檢測圖片的字節(jié)數(shù)據(jù)作為參數(shù),其中appID、apiKey、secretKey是在上面創(chuàng)建應(yīng)用時獲取到的,url是發(fā)布模型時獲取到的:
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"));
}
}
返回結(jié)果:

拿到了定位數(shù)據(jù)后,接下來將其區(qū)域繪制出來, 響應(yīng)說明中解釋(left,top)構(gòu)成左上頂點,但是從返回值來看top為16,減去一個高度312的話,左下頂點的坐標(biāo)已經(jīng)是負(fù)數(shù),這里姑且猜想它構(gòu)成的是左下頂點:

首先創(chuàng)建一個Image來放置我們的測試圖片,Canvas、Image大小也設(shè)為測試圖片的大小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... 區(qū)域大概準(zhǔn)確吧,可能測試的模型數(shù)據(jù)集足夠豐富的話檢測會更精確。
以上就是Unity實現(xiàn)識別圖像中主體及其位置的詳細(xì)內(nèi)容,更多關(guān)于Unity的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#如何動態(tài)創(chuàng)建lambda表達(dá)式
這篇文章主要介紹了C#如何動態(tài)創(chuàng)建lambda表達(dá)式問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02

