利用 TinyML 和 OpenMV 開始使用機器視覺 – 第 1 篇
機器學習和 tinyML 有潛力能為嵌入式系統工程師解決許多應用問題。偵測影像中的物件並進行辨識是個相當獨特的難題,更難以從頭開始編寫這類程式。碰巧的是,偵測和辨識物件是 tinyML 的完美應用。但要開始使用 tinyML 和機器視覺 (MV) 則較複雜。在接下來的幾篇文章中,我們將探討如何利用 OpenMV 相機開始使用機器視覺。
OpenMV Cam H7 簡介
假設您對使用微控制器在低功耗應用中達到機器視覺感興趣。在此前提下,您要不就是客製化設計相機模組,不然就是已經找到市售款式。從頭開始打造模組雖然很有趣,但成本高昂且耗時。有個有趣的市售解決方案是 OpenMV Cam。
OpenMV Cam 是一個類似 Arduino 的小型開發板,其中含有開發人員要開始使用 MV 所需的各項要素。首先,務必瞭解市面上有多種不同的硬體版本。最新版本是 OpenMV Cam H7 (圖 1)。Cam H7 是以 STMicroelectronics 的 STM32H743VI 微控制器為基礎,並採用 Arm Cortex-M7 架構,時脈速度為 480 MHz。此零件還具有 1 MB 的 SRAM 和 2 MB 的快閃記憶體。在使用機器視覺和學習應用程式時,擁有充足的可用記憶體絕對是好事。Cam H7 採用 MT9M114 相機模組,能以 40 fps 的速度及 8 位元灰階擷取 640 x 320 的影像,或以 40 至 80 fps 的速度擷取 320 x 240 QVGA 影像。相機模組可以依據應用需求進行更改。
圖 1:OpenMV Cam H7 模組擁有開啟機器視覺設計所需的各項要素。(圖片來源:OpenMV)
OpenMV 開發環境
OpenMV 整合式開發環境 (IDE) 如圖 2 所示,是開發人員與 Cam H7 交動的方式。此 IDE 能讓開發人員針對會在模組上運行的 Python 指令碼進行編輯。Cam H7 採用 MicroPython,這是屬於 C Python 的一部份,專門針對在微控制器架構系統上運行而設計。開發人員接著就可以連接 Cam H7、將指令碼載入到裝置上,然後運行應用程式。IDE 還可用來取得 Cam H7 訊框緩衝區影像的即時訊號。
圖 2:OpenMV 開發環境含有開發人員對 Cam H7 編程與互動所需的一切要素,如文字編輯器、終端機和影像擷取顯示器。(圖片來源:OpenMV)
想要開始將此模組用於機器視覺,且最終進行機器學習的開發人員不需要想得太遠。OpenMV IDE 含有範例指令碼,涵蓋讓系統進入低功耗模式,一路到物件和臉部的偵測等等。還有將模組與外部開發板 (如 Wi-Fi、慣性測量單元 (IMU) 和其他選項) 介接的範例。
偵測影像中的圓圈
OpenMV IDE 含有一個 HelloWorld 指令碼,能讓開發人員連接到相機並拍攝畫面送到訊框緩衝區。在本篇文章主題下,有個有趣的範例值得一看,就是偵測影像中的某個東西,例如圓圈。
如果您打開 OpenMV IDE 並按兩下 File->Examples->Feature-Detection->find_circles.py (參見圖 3),就會出現一個指令碼可執行上述動作。測試這個指令碼非常容易;首先,你要拿一張紙或一張便利貼,畫一個圓圈 (請不要評判我的繪畫能力,很糟的!)接下來,在 IDE 的左下角,您會看到一個連接按鈕。按一下按鈕,就可連接 Cam H7。接下來,按一下連接按鈕正下方的綠色播放按鈕。最後,將 Cam H7 對準您繪製的圓圈,然後監測 OpenMV IDE 中的訊框緩衝區。
圖 3:導覽 openMV IDE 中的 find_circles.py 範例指令碼。(圖片來源:Beningo Embedded Group)
您應該會注意到,訊框緩衝器中會有繪製的紅色圓圈,會覆蓋您畫的圓圈,如圖 4 所示。請注意,即便我的藝術能力不足,Cam H7 仍可偵測到擷取影像中有個類似圓圈的東西。圓圈是我們在此系列部落格文章中第一個偵測的東西,但不是最後一個!讓我們看一下範例指令碼,瞭解其作用。
圖 4:find_circles.py 範例指令碼會將紅色圓圈加到訊框緩衝區中,將偵測到圓圈的時刻突顯出來。(圖片來源:Beningo Embedded Group)
分析 find_circles.py 範例
OpenMV IDE 提供用來偵測圓圈的指令碼相當直覺。首先,此指令碼會導入所需的 Python 函式庫,並且將相機感測器和時脈初始化,如清單 1 所示。
複製import sensor, image, time
sensor.reset()
sensor.set_pixformat(sensor.RGB565) # grayscale is faster
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 2000)
clock = time.clock()
清單 1:初始化相機感測器的範例程式碼。(程式碼來源:OpenMV)
接下來,就會進入應用程式運行的無限迴圈,就像在任何標準嵌入式應用程式中一樣。最後,就會來到一個神奇時刻:偵測到東西了。花點時間查看清單 2。
複製while(True):
clock.tick()
img = sensor.snapshot().lens_corr(1.8)
for c in img.find_circles(threshold = 2000, x_margin = 10, y_margin = 10, r_margin = 10,
r_min = 2, r_max = 100, r_step = 2):
img.draw_circle(c.x(), c.y(), c.r(), color = (255, 0, 0))
print(c)
print("FPS %f" % clock.fps())
清單 2:讀取相機感測器並在影像中搜尋圓圈的範例程式碼。(程式碼來源:OpenMV)
清單 2 中的程式碼會從拍攝快照影像開始。接著會使用 OpenMV 函式庫中附的一個方法 (名為 find_circles),在影像中搜尋圓圈。您可以閱覽實際原始程式碼範例中的註解,進一步瞭解參數詳情。但我們最感興趣的是 r_min、r_max 和 r_step 參數。r_min 參數可指定能偵測到的最小圓圈半徑。r_max 參數則可設定最大值。此範例程式可以看見介於 2 至 100 像素之間的圓圈。
偵測到圓圈時,會使用 draw_circle 方法搭配圓圈的 x、y 和半徑值,在偵測到的圓圈上畫一個圓。您會發現,顏色是用 R、G 和 B 表示法指定,在此範例中則是繪製一個紅色圓圈。
結論
開發人員可加以運用機器視覺和 TinyML,並應用在幾乎無限的使用案例中。本篇文章介紹了 OpenMV Cam H7 和 OpenMV IDE,讓您瞭解並開始偵測圓圈。然而,偵測圓圈並不需要 tinyML,只需要幾個函式庫函數。在下一篇文章中,我們將探索內建的機器學習範例,然後再研究另一個較複雜的範例,以便訓練並部署此偵測專案。

Have questions or comments? Continue the conversation on TechForum, Digi-Key's online community and technical resource.
Visit TechForum