【Unity萌新學習記錄】百度OCR文字識別引入Unity實現(xiàn)Unity手寫文字識別功能

0.寫在前面
第一次寫教程,如有疏漏或者錯誤的地方,還請指正
本教程將介紹如何使用Unity實現(xiàn)手寫文字識別
本教程使用的Unity編輯器版本:?2020.3.30f1c1
編譯器:?Visual?Studio?2019?Community
測試設備:LEGION?y9000p?2021H?? i7-11800H@2.30GHz
測試環(huán)境:Windows 10 20H2 家庭中文版
?
項目概述
在Unity中實現(xiàn)在Canvas上實現(xiàn)用鼠標手寫
在手寫功能完成后,成功接入百度的手寫文字OCR識別API
最后實現(xiàn)的基本效果是:用戶可以在Canvas上寫字,寫完字后按下空格鍵即可調用百度的手寫文字OCR識別,識別成功后將在Unity控制臺生成Debug信息返回識別結果,支持清空畫布字跡重新書寫。
后續(xù)會進一步優(yōu)化,實現(xiàn)識別結果在屏幕上顯示識別文本結果等功能
1.?Unity在Canvas上手寫文字的實現(xiàn)
1.1準備工作
打開Unity?Hub?新建一個2D項目,根據喜好給項目命名,最好是英文命名。(防止Unity出一些奇怪的問題)
本教程命名為"Handwritten?character?recognition",并關閉版本管理。

1.2畫布的基本設置
建立一個Canvas

選中Canvas,在Inspector面板中
將Canvas的渲染模式改成Screen Space-Camera。

然后選中Main Camera,將其拖到Canvas組件中的Render Mode中去,如下圖。

點擊Game視圖,然后點擊“display1”旁邊的按鈕,我們新建一個分辨率,比如2400x1080。


創(chuàng)建好后我們回到編輯視圖(Scene),在Canvas下右鍵創(chuàng)建一個image。

然后使用Anchor Present工具讓image填充整個Canvas
步驟及效果如下圖。


這樣,畫布的基本的設置就完成了。
?
?
1.3實現(xiàn)在Unity畫布上寫字
?
在Project面板上創(chuàng)建一個文件夾,文件夾命名為“Scripts”。

點擊Scripts文件夾,在Project窗口右鍵創(chuàng)建一個C#腳本,命名為?DrawLinesWithMouse

雙擊打開后,應該會自動打開Visual Studio來編寫腳本。
?
然后編寫以下代碼


然后Ctrl+S保存,之后回到Unity編輯器
在Hierachy(層級面板)中,右鍵創(chuàng)建一個空物體,命名為Draw Manager。


將腳本掛載到Draw Manager中
(直接將腳本拖入Inspector面板或者在DrawManager面板中的Add Component 中搜索 DrawLinesWithMouse,然后確定。

現(xiàn)在運行項目,嘗試在畫布上按住鼠標拖動書寫,應該能畫出紅色的字跡
(如下方GIF所示)

我們再次回到DrawManager中,觀察DrawLinesWithMouse腳本
可以根據個人喜好調節(jié)筆跡的參數(shù)。

比如說將Line Width調成0.1,Line Color 調成純黑色,然后運行項目,效果如圖。

1.4實現(xiàn)“一鍵清除字跡”
?
測試沒有問題后,我們將給負責手寫的腳本,也就是?DrawLinesWithMouse這個腳本升級,也就是添加功能
?
假如我們覺得書寫的比較亂的時候,想一鍵清空畫布上的筆跡
我們可以嘗試修改DrawLinesWithMouse腳本

修改代碼完成后
現(xiàn)在,我們創(chuàng)建一個按鈕
在Hierachy(層級面板)中,右鍵創(chuàng)建一個按鈕,根據項目需要來選擇Button還是Button-TextMeshPro
本教程使用Button-TextMeshPro。

然后會自動彈出TMP Importer,分別點擊“Import TMP Essentials”和“Import TMP Example & Extra”按鈕,然后關閉窗口。

然后將按鈕“Button”重新命名為“ClearButton”
之后點擊Button旁邊的“三角號”,點擊“Text(TMP)”
在Inspector面板中可以修改顯示的文本。

如果要顯示中文的話,需要創(chuàng)建一個TMP字體。
用默認的LiberationSans字體是不支持顯示中文的。
這時候我們需要快捷鍵Win+E?打開資源管理器。
然后在上面的搜索框中將下面的路徑復制到搜索欄上
C:\Windows\Fonts

這里是存放字體的文件夾,挑一個支持中文的字體然后將它拖入到Unity中。
(提示:盡量不要拖入微軟雅黑字體,因為導入的時間非常的長)

這里用蘋方字體來做演示。

然后在Unity中創(chuàng)建一個名為Fonts的文件夾,將要使用的字體文件拖入到該文件夾中,然后選中該字體,Shift+Ctrl+F12來快速創(chuàng)建一個TMP字體。



然后選擇Button下的Text(TMP),在Inspector面板中把生成的字體拖入到Font Asset的位置來更換支持中文顯示的字體。

現(xiàn)在,就可以在文本框里輸入中文了。

當然也可以調節(jié)字體大小,字重,左右對齊,文字居中,根據個人喜好調整。
現(xiàn)在看畫布的按鈕有點小,我們重新選中Button,然后可以按下R鍵(輸入法為英文模式下摁R)進入物體縮放模式,鼠標按住中間的白色方塊然后上下拖動調整合適的大小。

然后把這個按鈕移動到合適的位置(選中Button然后在編輯狀態(tài)下按W)


一切調整完成后,我們就要開始設置這個按鈕了。



此時,運行游戲,用鼠標寫字,寫好之后點擊按鈕,就會清除屏幕上的所有字跡(如下方GIF所示)。

現(xiàn)在,在Unity上用鼠標寫字的基本功能就完成了!
2.?接入百度的手寫文字OCR識別API
(注:由于教程的時效性,一些操作細節(jié),比如百度云的應用創(chuàng)建入口和創(chuàng)建方式可能會和本教程有所差異,如有不同之處,一切以實際為準)
?
2.1 基礎設置
創(chuàng)建Baidu Ai應用
首先點擊這個鏈接,用自己的百度賬號登錄,沒有百度賬號就自己注冊一個
https://login.bce.baidu.com/?redirect=https%3A%2F%2Fconsole.bce.baidu.com%2Fai%2F%3Ffromai%3D1#/ai/ocr/app/list
(如果手機上有使用百度的App產品并且是登錄狀態(tài)也可以使用App的掃碼登錄,比如百度貼吧)

登錄成功后先點擊三道杠圖標,再點擊產品服務,然后找到文字識別

點擊公有云服務,然后點擊應用列表

然后創(chuàng)建應用

應用歸屬:個人
應用描述:文字識別

創(chuàng)建完成后下載SDK



下載好壓縮包后找到下載位置
在你的瀏覽器上按下Ctrl+J快速定位下載內容
(以Chorme瀏覽器為例,基于Chorme內核的瀏覽器應該都可以用此快捷鍵)

選擇一個合適的文件路徑然后用解壓軟件解壓這個壓縮包

解壓完成后會出現(xiàn)這兩個文件夾,我們主要使用netstandard2.0框架,當然具體細節(jié)稍后再說,現(xiàn)在我們先回到Unity

回到Unity
我們要根據PlayerSetting的對應選項選擇對應的SDK
具體步驟是
①? 點擊File菜單。
②? 選擇BuildSettings。
③? 選擇PlayerSettings。
④? 選擇OtherSettings。
⑤選擇APICompatibility選項,根據選項版本選擇對應的SDK
(我們前面說過,選擇netstandard2.0)



然后回到Assets文件夾,創(chuàng)建一個文件夾,命名為Plugins,并打開該文件夾



2.2 編寫腳本及環(huán)境的正確配置(Newtonsoft.Json.dll)

然后編寫腳本如下。

API KEY和Secret Key的查看。

編寫此腳本完成后
此時會發(fā)現(xiàn)腳本會有兩處報錯。

發(fā)生這種情況的原因主要是Newtonsoft.Json.dll配置的問題,我們在百度下載到的SDK中net45自帶的Newtonsoft.Json.dll版本太舊,所以我們需要正確引入最新的Newtonsoft.Json.dll。
?
首先是Visual Studio部分
在“解決方案資源管理器”中,點擊解決方案,然后右鍵
點擊“管理解決方案中的NuGet程序包”。

在NuGet-解決方案中下載并安裝新的Newtonsoft.Json


正確安裝之后,編譯器的兩個報錯就消失了。

雖然編譯器報錯是消失了,可是Unity編輯器重載編輯后的腳本還是會顯示報錯。
別擔心,這不是Unity編輯器的Bug,這還是Newtonsoft.Json.dll的問題。

我們之前在Unity導入了一個百度SDK里面的Newtonsoft.Json.dll,就是它的問題,我們的這個腳本需要更高版本的Newtonsoft.Json.dll,百度提供的這個Newtonsoft.Json.dll版本低,所以Unity會報錯。
因此,我們需要刪除百度提供的舊版本,安裝新版本
在瀏覽器上搜索Newtonsoft官網,通常第一個就是了。

點進去,然后點擊Download。

此時網站會出現(xiàn)一個彈窗,提供下載選擇,我們選擇下載Json NET。

然后跳轉到改項目的GitHub上,點擊Json.130r3.zip
此時瀏覽器會自動下載
(考慮到大部分人上不去GitHub,所以這里留下一個百度網盤下載Json.130r3.zip的鏈接,以供方便下載)
?
鏈接:https://pan.baidu.com/s/1BXB7YKZ_SIIE2rn9h6t_1g?pwd=SZMT
?
提取碼:SZMT
--來自百度網盤超級會員V4的分享

然后解壓下載好的壓縮包

按照圖示的這個路徑找到Newtonsoft.Json.dll(這個是新版的)

然后回到Unity刪除百度舊版的Newtonsoft.Json.dll

將新版的Newtonsoft.Json.dll拖入Unity
?
(注意拖入的文件夾,還有就是Newtonsoft.Json.dll新版舊版不要弄混了?。?/span>

如果以上步驟都正確,此時的情況如上圖,會提醒警告信息,像是
“Assets\Scripts\HandwritingRecognition.cs(105,33): warning CS1701: Assuming assembly reference 'Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' used by 'AipSdk' matches identity 'Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' of 'Newtonsoft.Json', you may need to supply runtime policy”
?
盡管有警告
但此時,它已經不影響項目的正常運行了
?
現(xiàn)在在Hierachy面板上創(chuàng)建一個空物體,命名為OCR Manager,并將腳本掛載到OCR Manager上去

一切都設置好了之后
我們還需要回到百度智能云平臺,目的是領取應用接口免費使用次數(shù)
https://login.bce.baidu.com/?redirect=https%3A%2F%2Fconsole.bce.baidu.com%2Fai%2F%3Ffromai%3D1#/ai/ocr/app/list


免費資源大概10分鐘之內數(shù)據就可以更新了
(注:百度的手寫識別接口僅有500次免費次數(shù))
?
領取免費資源成功之后
現(xiàn)在,可以嘗試運行項目
先用鼠標在畫板上寫字

然后按下空格鍵
之后將會在Unity控制臺(Console)中返回文字識別結果,如下圖


至于為什么控制臺返回的結果是這種格式的,請自行查閱百度官方文檔
https://ai.baidu.com/ai-doc/OCR/Vkibizy8i#%E6%89%8B%E5%86%99%E6%96%87%E5%AD%97%E8%AF%86%E5%88%AB

至此,Unity接入百度API識別手寫文字的基礎框架就已經完成了!
3.?手寫文字識別功能的進一步優(yōu)化
3.1 自定義文字識別區(qū)域
雖然我們成功實現(xiàn)了百度OCR文字識別,但是從剛剛控制臺返回的結果來看,似乎出了一些問題

手寫文字是識別成功了,但是它也將按鈕上的文字也識別并返回結果到控制臺了,這將會干擾最終的識別結果
因此我們要優(yōu)化"HandwritingRecognition"代碼
我們要用代碼控制文字識別的區(qū)域,所以我們要修改代碼
修改如下

然后Ctrl+S 保存,回到Unity
此時發(fā)現(xiàn)OCR Manager中的HandwritingRecognition多了一個ScreenShot Rect

這里解釋一下,screenshotRect的作用是控制截取屏幕的范圍
以屏幕的左下角為起點(0,0)
以上方向和右方向作為正方向延伸
X,Y值控制著起點的初始左邊(默認是0,0)
W即Screen.width,代表當前屏幕的寬度
H即Screen.height,代表當前屏幕的高度
例:new?Rect(100,?100,?500,?500)表示從屏幕上(100,100)的位置開始,截取寬度為500,高度為500的區(qū)域。
?
知道了這些之后,我們就根據調節(jié)screenshotRect中的四個參數(shù)來調節(jié)文字識別區(qū)域的范圍,比如說W:2000,H:1080
(根據項目的實際情況多次嘗試)
通常不建議調節(jié)X,Y值,就默認0,0吧
如下圖

3.2 添加一個文字識別的按鈕
?
假如我們的項目最后將要在移動設備運行(如安卓手機)
而現(xiàn)在觸發(fā)文字識別的方式是按下物理鍵盤上的空格
放到安卓手機上似乎是行不通的
所以我們需要添加一個按鈕,并編寫一個方法,通過按下屏幕上的按鈕來進行文字識別

然后添加一個按鈕(Recognize),其中的文本命名為“開始識別”

然后給新添加的按鈕添加方法


最后的結果如下

3.3 文字識別結果在屏幕上可視化
我們還要在剛才的基礎上在添加一個功能,那就是
這樣用戶就可以看得到到文字的識別結果,達到向用戶反饋信息的目的
那么就繼續(xù)修改代碼




最終結果

3.4 文字識別結果包含特定字符將觸發(fā)事件
?我們繼續(xù)添加功能,當用戶在畫板上手寫文字,然后返回識別結果,當識別結果包含特定的字符時,就會觸發(fā)某個事件
比如說,當識別結果包含"數(shù)字媒體"這四個字時,就顯示隱藏的按鈕“你贏了”
修改代碼如下


然后Ctrl+S保存
回到Unity,進行如下設置



最終效果

現(xiàn)在這個Unity手寫文字識別的框架完成度已經很很高了
利用這個框架可以做一個簡易的看圖寫字小游戲
比如在畫布上放一個蘋果的圖片,要求用戶在畫布上寫出蘋果兩個字
我們需要把公共變量Keyword寫上"蘋果"兩個字
再放上需要隱藏的按鈕(或者是其他的什么游戲元素也可以)
當用戶手寫"蘋果"兩個字并且被成功識別
隱藏的元素就會顯示出來
可以根據自己的創(chuàng)意和想法自行調整
?
?
?
?
?
?
?
?
本教程完
By Arz-神奇的阿零Tianlst?
2023.7.19