利用 TinyML 和 OpenMV 開始使用機器視覺 – 第 1 篇

機器學習和 tinyML 有潛力能為嵌入式系統工程師解決許多應用問題。偵測影像中的物件並進行辨識是個相當獨特的難題,更難以從頭開始編寫這類程式。碰巧的是,偵測和辨識物件是 tinyML 的完美應用。但要開始使用 tinyML 和機器視覺 (MV) 則較複雜。在接下來的幾篇文章中,我們將探討如何利用 OpenMV 相機開始使用機器視覺。

OpenMV Cam H7 簡介

假設您對使用微控制器在低功耗應用中達到機器視覺感興趣。在此前提下,您要不就是客製化設計相機模組,不然就是已經找到市售款式。從頭開始打造模組雖然很有趣,但成本高昂且耗時。有個有趣的市售解決方案是 OpenMV Cam。

OpenMV Cam 是一個類似 Arduino 的小型開發板,其中含有開發人員要開始使用 MV 所需的各項要素。首先,務必瞭解市面上有多種不同的硬體版本。最新版本是 OpenMV Cam H7 (圖 1)。Cam H7 是以 STMicroelectronicsSTM32H743VI 微控制器為基礎,並採用 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,只需要幾個函式庫函數。在下一篇文章中,我們將探索內建的機器學習範例,然後再研究另一個較複雜的範例,以便訓練並部署此偵測專案。

關於作者

Image of Jacob Beningo

Jacob Beningo 是嵌入式軟體顧問,目前與超過十幾個國家的客戶合作,透過產品品質、成本和上市時間的改善,促成業務的大幅轉型。他曾在嵌入式軟體開發技術上發表超過兩百篇文章,是深思熟慮的講師和技術培訓師,共擁有三個學位,包括密西根大學的工程碩士學位。歡迎透過以下方法洽詢,電郵:[email protected]、網站:www.beningo.com,亦可登記取得他發行的Embedded Bytes 每月電子報

More posts by Jacob Beningo
 TechForum

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

Visit TechForum