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#通過創(chuàng)建Windows服務(wù)啟動程序的方法詳解
這篇文章主要介紹了C#通過創(chuàng)建Windows服務(wù)啟動程序的方法,較為詳細(xì)的分析了C#創(chuàng)建Windows服務(wù)應(yīng)用程序的步驟與相關(guān)注意事項,需要的朋友可以參考下2016-06-06Unity UGUI的ScrollRect滾動視圖組件使用詳解
這篇文章主要為大家介紹了Unity UGUI的ScrollRect滾動視圖組件使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07在C#中根據(jù)HardwareID獲取驅(qū)動程序信息的實現(xiàn)代碼
這篇文章主要介紹了C#中根據(jù)HardwareID獲取驅(qū)動程序信息的實現(xiàn)代碼,需要的朋友可以參考下2016-12-12C#+無unsafe的非托管大數(shù)組示例詳解(large unmanaged array in c# without ‘u
這篇文章主要給大家介紹了關(guān)于C#+無unsafe的非托管大數(shù)組(large unmanaged array in c# without 'unsafe' keyword)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01C#打包部署并把.net framework框架打到安裝包的方法步驟
打包c#程序時,有時需要添加.net framework組件到安裝包,本文就來介紹一下C#打包部署并把.net framework框架打到安裝包的方法步驟,具有一定的參考價值,感興趣的可以了解一下2023-10-10