1. 引言
最近在微軟Learn平台學習Azure認知服務相關的內容,看到了一個有關“使用自定義視覺對瀕危鳥類進行分類”的專題,該專題的主要內容就是使用 Azure Custom Vision創建一個模型來標識鳥類物種。學習完以后,覺得內容挺有意思,英語不好的同志不要覺得有壓力,這個專題學習模塊的所有內容已經漢化。但是有個問題就是,學習完以后,你會發現,該項目是在PC上使用現有的照片來進行識別,這樣的操作並不是十分方便。目前,隨着物聯網設備的普及,使用樹莓派作為IoT終端、結合攝像頭捕捉實時圖像,再與Azure Custom Vision進行交互,獲得識別結果,這樣的方式或許部署起來更加輕巧方便。好的,下面我們就一起來把這個想法實現出來,我整體測算了一下,應該能夠在1個小時內搞定。另外,本文使用微軟Learn平台的沙盒作為資源,所有的Azure資源使用都是免費的。
2. 硬件准備
樹莓派主機、電源、顯示器(非必須,可以通過VNC遠程查看)、USB攝像頭或樹莓派專用攝像頭。我這里用的是樹莓派4(2G)和Microsoft LifeCam HD3000攝像頭。
3. 軟件資源
需要一個微軟賬號,可以通過outlook注冊一個,在資源搭建過程中使用的Azure資源是以沙盒的形式免費提供的,這個沙盒的使用有時間限制,一般是4個小時的有效期,每個賬戶每天可以申請10個沙盒。具體的過程可以參考上面提供的這個文檔中的第三步:構建模型。
4. 創建自定義視覺 API 資源
我們將在 Azure 認知服務自定義視覺中創建 API 資源。
1. 在 Azure 門戶中,選擇“Create a resource”。
2. 搜索“custom vision”。 在自定義視覺的搜索結果中,選擇“create”。
3. 在“基本”選項卡上,輸入或選擇所需的值:
- 選擇 Azure 訂閱:默認就是Concierge Subscription,
- Option里面記得選擇Both,就是Training和Prediction都要。
- 創建資源組:默認可選的就是learn-***(后面是一串ID號),
- 名字:自己想一個就行。
- 位置:選就近的,沒有China,就選了Japan East。
- Pricing Tier:選F0就夠了。
圖1:創建Custom Vision項目
5. 下載鳥類的圖片數據集
數據是創建機器學習模型所需的首要內容。 我們可以使用來自康奈爾實驗室的 NABirds 數據集的子集來訓練模型。下載包含數據集的 zip 文件,該資源大家可以去Github上下載:資源鏈接。下載以后,打開可以發現里面有16中鳥類的圖片,每一種大概120圖片左右。
圖2:數據集資源
6. 上傳數據集
目前,我們有兩種方法來上傳圖片數據,一種是使用Custom Vision的門戶,還有一種是使用Custom Vision的SDK。相對來說,使用門戶上傳更直觀一些。我們這里就使用門戶的方式上傳。具體步驟如下:
在自定義視覺門戶中創建項目:轉到 https://www.customvision.ai/projects 並登錄。如果在同一瀏覽器中,使用之前登陸Azure門戶的賬號就好。
選擇“新建項目”。在“創建新項目”中:
- 在“名稱”中,輸入所選的項目名稱。
- 在“描述”中,輸入模型的短描述。
- 在“資源組”中,選擇在 Azure 門戶中創建的資源組。
- 在“項目類型”中,選擇“分類”。
- 在“分類類型”中,選擇“多類(每圖像一個標記)”。
- 在“域”中,選擇“常規”。
選擇“創建項目”。如下圖3所示。
圖3:創建Custom Vision項目
在自定義視覺項目中,選擇“添加圖像”,在“打開”中,轉到從數據集 zip 文件中提取圖像文件的 birds-photo 文件夾。打開鳥類物種文件夾。選擇 Ctrl + A 來選擇物種文件夾中的所有圖像,然后選擇“打開”。
圖4:上傳圖片數據集
在“圖像上傳”中,在“我的標記”中添加說明以表明照片中顯示的鳥類物種,如鴿子。
圖5:標記數據集
選擇“上傳文件”。繼續上傳其他鳥類的圖片,直到完成上傳。注意,至少要上傳兩種以上的Tag的圖片,不然后面就沒法訓練。
7. 訓練模型
我們已在自定義視覺中創建了數據集。現在,可以對模型進行訓練了。可以使用 SDK 來訓練模型,但我們將使用自定義視覺門戶來訓練模型。在自定義視覺門戶中,選擇“鳥類分類”項目。在頂部菜單欄中,選擇“訓練”。在“選擇訓練類型”中,選擇“快速訓練”,然后選擇“訓練”。
圖6:訓練數據集
在訓練過程中,“迭代”窗格將顯示在左側。 窗格中的“正在訓練...” 通知指示正在進行訓練。 訓練完成時,將顯示有關如何為正在訓練的迭代執行模型的信息。有關訓練迭代的詳細信息,可通過稱為“精度”、“撤回(Recall)”和“平均精度 (AP)”的指標來顯示。為整個模型和每個類(標記)顯示這些指標。 如圖7所示。
圖7:數據集訓練結果
接下來,我們將詳細了解這些指標。自定義視覺在測試模型時顯示三個指標。 這些指標是可幫助你了解模型執行情況的指示器。 這些指示器不會指示模型的真實性或准確性。指示器只會告訴你模型在你所提供數據上的執行情況。模型在已知數據上的執行情況可以讓你了解模型在新數據上的執行情況。為整個模型和每個類提供以下指標:
- precision :如果模型預測標記,則此指標表示預測正確標記的可能性有多大。
- recall:對於模型應正確預測的標記,此指標表示模型正確預測的標記的百分比。
- average precision:通過計算在不同閾值上的精准率和召回率來度量模型性能。
在測試自定義視覺模型時,將在迭代測試結果中看到每個指標的數值。
8. 測試模型
根據自定義視覺提供的指標,我們的模型性能令人滿意。 接下來測試模型,看看它處理未見過的數據時性能如何。 我們可以從網上搜索一張鳥類圖像。
- 在 Web 瀏覽器中,搜索你訓練該模型識別的其中一個鳥類物種的圖像。 復制圖像的 URL。
- 在自定義視覺門戶中,選擇“鳥類分類”項目。
- 在頂部菜單欄中,選擇“快速測試”。
- 在“快速測試”中,將 URL 粘貼到“圖像 URL”,然后按 Enter 測試模型的准確性。 預測將顯示在窗口中。
自定義視覺分析圖像以測試模型的准確性並顯示結果,如圖8所示。
圖8:測試結果
9. 部署模型
在自定義視覺門戶的頂部菜單欄中,選擇“性能”。選擇“發布”。在“發布模型”中,選擇“預測資源”,然后選擇自定義視覺項目的預測名稱。 選擇“發布”。如下圖9所示。
圖9:發布模型
在發布模型后,模型操作在自定義視覺門戶中進行更改。選擇“預測 URL”選項卡。在“如何使用預測 API”的“如果你有一個圖像 URL”下的文本框中,復制並保存該值,然后選擇“獲取”。
圖10:模型URL
在設置頁面,我們可以獲得后續所需要的Key、EndPiont和Project ID,如下圖所示。
圖11:項目設置頁面
10. 樹莓派應用構建
樹莓派中,我們要使用到custom vision的python SDK,所以我們要使用pip工具安裝以下庫:
1 pip3 install azure-cognitiveservices-vision-customvision 2 pip3 install msrest
由於我們在項目中使用了USB攝像頭,以及后續的圖片顯示,所以需要安裝fswebcam和matplotlib,命令如下:
1 sudo apt-get install python3-matplotlib 2 sudo apt-get install fswebcam
好了,下面我們可以用樹莓派自帶的Thonny工具新建一個Python文件,將代碼拷貝到編輯器中,保存為customvisionclassify.py。
1 import os 2 from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient 3 from msrest.authentication import ApiKeyCredentials 4 from PIL import ImageDraw 5 from PIL import Image 6 import matplotlib.pyplot as plt 7 8 # capture the image with USB webcamera 9 a=os.system("fswebcam --no-banner -r 1280x720 capture.jpg") 10 print(a) 11 credentials = ApiKeyCredentials(in_headers={"Prediction-key": "9b7a001f9d3e4cf38a2124f86******"}) 12 predictor = CustomVisionPredictionClient("https://birdcustomvisiondemo.cognitiveservices.azure.com/", credentials) 13 projectID = "c597ccfe-7e32-4777-b773-*******" 14 publish_iteration_name="Iteration1" 15 with open("capture.jpg", mode="rb") as captured_image: 16 results = predictor.classify_image(projectID, publish_iteration_name, captured_image) 17 # Display the results. 18 for prediction in results.predictions: 19 print("\t" + prediction.tag_name + ": {0:.2f}%".format(prediction.probability * 100)) 20
這里,使用你自己創建的Key、projectID和Iteration來替換我上面的,就可以了。
上面這總共加起來就是20行代碼,先用USB攝像頭捕捉圖像,然后調用CustomVisionPredictionClient進行圖片識別,對其中的鳥類進行分類,最后將得到的結果打印在調試窗口。點擊運行,如果你的攝像頭捕捉到了鳥類,例如鴿子什么的,就可以得到結果了。
圖12:分類結果頁面
當然,有的同學要問了,如果我想識別鳥類在圖片中的什么位置,然后給他標記出來呢?這樣的話,光是分類就不夠了,我們需要新建一個Object Detection類的項目了,具體方式就是在新建項目的時候,選擇Object Detection,而不是Classification。之后的步驟也差不多,就是上傳圖片,加Tag,然后訓練,訓練完成以后,部署模型。唯一的區別就在於,在Object Detection項目中,我們需要對上傳的圖片進行標注,就是要將對象在圖片中出現的位置進行標注,如下圖13所示。
圖13:Tag標記頁面
另外,在樹莓派上的代碼也有所不同,因為之前是分類,現在我們是要做檢測,具體代碼如下。
1 import os 2 from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient 3 from msrest.authentication import ApiKeyCredentials 4 from PIL import ImageDraw 5 from PIL import Image 6 import matplotlib.pyplot as plt 7 8 # capture the image with USB webcamera 9 a=os.system("fswebcam --no-banner -r 1280x720 capture.jpg") 10 print(a) 11 12 credentials = ApiKeyCredentials(in_headers={"Prediction-key": "****"}) 13 predictor = CustomVisionPredictionClient("https://birdcustomvisiontest.cognitiveservices.azure.com/", credentials) 14 projectID = "27dd8141-93c6-***-***-*******" 15 publish_iteration_name="Iteration*" 16 17 with open("capture.jpg", mode="rb") as captured_image: 18 results = predictor.detect_image(projectID, publish_iteration_name, captured_image) 19 20 # Display the results. 21 for prediction in results.predictions: 22 # print("\t" + prediction.tag_name + ": {0:.2f}%".format(prediction.probability * 100)) 23 if prediction.probability>0.9: 24 print("\t" + prediction.tag_name + ": {0:.2f}%".format(prediction.probability * 100)) 25 bbox = prediction.bounding_box 26 im = Image.open("capture.jpg") 27 draw = ImageDraw.Draw(im) 28 draw.rectangle([int(bbox.left * 1280), int(bbox.top * 720), int((bbox.left + bbox.width) * 1280), int((bbox.top + bbox.height) * 720)],outline='red',width=5) 29 im.save("detect.jpg") 30 31 de=Image.open("detect.jpg") 32 plt.figure("Result") 33 plt.imshow(de) 34 plt.show() 35
執行的結果如下圖14所示,圖中我們可以看到,返回的結果里面,將識別的鳥類用紅色框進行了標注。
圖14:鳥類識別結果頁面
如果使用了LCD電容屏來做顯示器,那么,我們執行的結果如下圖15所示。
圖15:樹莓派硬件整體圖
參考鏈接:
1. Microsoft Learn:使用自定義視覺對瀕危鳥類進行分類
2. Azure資源:Azure 門戶
3. 圖片數據集的Github鏈接:資源鏈接
4. Custom Vision 門戶:https://www.customvision.ai/projects