主頁 >  其他 > OpenMV 從入手到跑TensorFlow Lite神經網路進行垃圾分類

OpenMV 從入手到跑TensorFlow Lite神經網路進行垃圾分類

2021-11-05 09:23:28 其他


-----------文章較長,可通過右側(或左側)目錄進行跳轉閱讀-----------

OpenMV 從入手到跑TensorFlow Lite神經網路進行垃圾分類

  • 一、了解OpenMV 4 plus的構成
    • 1.OpenMV 4 plus 的特點
      • 1.1 硬體資源
      • 1.2 引腳圖
    • 2.可用的學習資源
  • 二、建議的學習路線
    • 1.學習python基礎語法
    • 2.練習OpenMV的基礎實驗
      • 2.1 安裝軟體
      • 2.2 了解基礎環境使用方法并連接設備
      • 2.3 常用基礎例程
        • 2.3.1 查找例程方法
  • 三、一點教程
    • 1.常用的延時寫法
    • 2.如何 點亮or熄滅 一個LED燈
    • 3.控制IO口輸入輸出
    • 4.控制串口引腳輸出資訊
    • 5.第一個影像例程HelloWord
    • 6.單顏色識別例程
    • 7.多顏色識別例程
    • 8.【串口】多顏色識別-回傳色塊中心坐標
  • 四、開啟TensorFlow Lite神經網路之旅
    • 1.TensorFlow Lite介紹
    • 2.使用支持
    • 3.使用OpenMV采集訓練資料
    • 4.上傳Edge Impulse進行訓練
      • 4.1注冊賬號并創建Edge Impulse工程
      • 4.2 上傳訓練集
      • 4.3 生成特征
      • 4.4 進行訓練
    • 5.在OpenMV上部署
  • 五、錯誤情況問題 【更新時間2021-8-04】
    • 1.“OSError” 錯誤
    • 2.運行速度慢
    • 3.“MemoryError” 記憶體不足
    • 4.其他問題
    • 5.解決問題一般思路

一、了解OpenMV 4 plus的構成

??OpenMV 是一個開源專案,其使用stm32系列單片機作為主控單元,搭載攝像頭,將python語言決議器移植到openMV的主控芯片運行,使其可以使用python語言做一些影像處理相關的作業,最常見的從 OpenMV 2 搭載的 stm32f4 到 OpenMV 3 的 stm32f7,再到 OpenMV 4 的 stm32H7 ,主頻從180MHz一路升級到480MHz,記憶體也從256KB升級到1MB,而本次介紹的 OpenMV 4 plus版本在OpenMV 4的基礎上外掛了32 MB 的 SRAM 和 32 MB 的 Flash,將可用性再次提升一個大的臺階,
在這里插入圖片描述

1.OpenMV 4 plus 的特點

1.1 硬體資源

資源性能
處理器STM32H743II ARM Cortex M7 處理器,480 MHz ,1MB RAM,2 MB flash.
介面全速 USB (12Mbs) 介面,連接到電腦,當插入OpenMV攝像頭后,你的電腦會出現一個虛擬COM埠和一個“U盤”
介面一個μSD卡槽擁有100Mbs讀寫,這允許你的OpenMV攝像頭錄制視頻和把機器視覺的素材從SD卡提取出來
介面一個SPI總線高達100Mbs速度,允許你簡單的把影像流資料傳給LCD擴展板,WiFi擴展板,或者其他控制器
介面一個 I2C總線,CAN總線, 和2兩個異步串口總線 (TX/RX) ,用來鏈接其他控制器或者傳感器
介面一個12-bit ADC 和一個12-bit DAC
介面2個 I/O 引腳用于舵機控制
介面一個RGB LED(三色), 兩個高亮的 850nm IR LED(紅外)
介面所有的IO口都可以用于,中斷和PWM(板子上有10個I/O引腳)
擴展32 MB 外置的 32-bit SDRAM ,100 MHz的時鐘,達到 400 MB/s 的帶寬
擴展32 MB 外置的 quadspi flash, 100 MHz的時鐘,4-bit DDR模式達到 100 MB/s 的帶寬
攝像頭默認安裝 OV5640 感光元件的攝像頭,可處理2592×1944 (5MP)影像,并帶有M12標準的2.8mm焦距鏡頭

1.2 引腳圖

在這里插入圖片描述

2.可用的學習資源

名稱網址備注
外文官網https://openmv.io/唯一原版官網
外文檔案教程https://docs.openmv.io/openmvcam/quickref.html強調基礎控制
中國代理官網https://singtown.com/openmv/星瞳科技
中文檔案教程https://docs.singtown.com/micropython/zh/latest/openmvcam/openmvcam/quickref.html#外文檔案教程的翻譯版(星瞳科技)
中文檔案教程https://book.openmv.cc/quick-starter.html入門推薦 ☆ 星瞳科技
中文視頻教程https://singtown.com/learn/入門推薦 ☆ 星瞳科技
開源專案地址https://github.com/openmv/openmvgithub 韌體原始碼

二、建議的學習路線

1.學習python基礎語法

??python的學習資源非常豐富,但為了使用OpenMv并最終實作跑TensorFlow Lite神經網路進行垃圾分類,僅會使用其基礎語法和格式即可,以下為免費的入門教程,自己有其他的教程資源亦可,其他教程推薦去bilibili搜索python,大把的免費視頻,

名稱網址備注
中文檔案簡稱https://www.runoob.com/python3/python3-tutorial.html免費簡潔的學習網站
視頻教程https://www.bilibili.com/video/av27789609著名小甲魚教程(幽默有趣,但是有點污)

??前期學習python無需學得很精,如果有其它語言基礎如C語言,則只需要看python的基礎資料型別、基礎條件陳述句以及基礎回圈陳述句等與自己掌握語言的不同之處即可,如沒有語言基礎,則需要將以上內容在例程的基礎上訓練幾遍,讓自己熟悉編程規則,

2.練習OpenMV的基礎實驗

2.1 安裝軟體

??在開始使用OpenMV之前,您需要下載并安裝 OpenMV IDE(點擊藍字即可跳轉官網下載),如下圖,在Windows下,OpenMV IDE進入安裝程式后,它將自動安裝IDE以及OpenMV和MicroPython pyboard的驅動程式,只需按照默認的安裝程式提示即可,一般情況下一直點擊下一步就正常安裝完成了,要啟動OpenMV IDE,只需點擊開始選單中的快捷方式即可,【安裝有問題的點此】
在這里插入圖片描述

2.2 了解基礎環境使用方法并連接設備

??通過USB資料線將OpenMV連接至電腦USB口,然后打開資源管理器,找到OpenMv生成的U盤,打開會發現包含一個main.py檔案,此檔案就是OpenMV在離線(未連接OpenMvIDE)上電時自動執行的第一個代碼檔案,
在這里插入圖片描述
??之后打開剛安裝好的OpenMV IDE,將OpenMV生成的U盤內的main.py檔案拖至OpenMV IDE編輯器處打開該檔案,

在這里插入圖片描述
??打開檔案后,首先點擊編輯器下方的連接圖示,之后再點擊編輯器下方運行按鈕,OpenMV就會在OpenMV IDE的控制下執行編輯器打開的main.py檔案,并在右側顯示攝像頭傳輸的影像流,
在這里插入圖片描述
??點擊下方的串行終端部分可看到OpenMV列印的提示資訊,在默認例程中輸出為影像流的幀率,
在這里插入圖片描述

2.3 常用基礎例程

2.3.1 查找例程方法

①在OpenMV IDE的 【檔案->示例->openMV】中可找到帶有的所有官方例程,
在這里插入圖片描述
②在星瞳給出的教程檔案中,有對官方例程的翻譯和解釋,【點此前往】
在這里插入圖片描述
③當然是根據自己的需求去萬能的百度了,,,

三、一點教程


此處我寫的一點教程是表達一下我的理解以及綜合起來的一些使用方法,比如led燈控制以及識別影像后的影像坐標如何通過串口輸出等實用方法,更符合學過單片機同學的實際學習思路,

在學習影像處理操作前,先學習一點基礎操作知識,

1.常用的延時寫法

??延時函式依賴于time模塊,所以在使用前應引入time模塊,

import time        		# 匯入庫檔案

time.sleep(1)           # 延時1s
time.sleep(0.5)         # 延時0.5s [引數以秒為單位,可傳入小數或整數]
time.sleep_ms(500)      # 延時500ms
time.sleep_us(10)       # 延時10us

2.如何 點亮or熄滅 一個LED燈

??首先OpenMV 4 plus上搭載了一個全彩RGB燈和兩個紅外LED,一個RGB LED內部包含3個LED,但是兩個紅外LED是受一個埠控制的,那么OpenMV 4 plus上就總共有4個控制LED的埠,如下表所示,

LED埠編號定義寫法
紅色LED1led_R = pyb.LED(1)
紅色LED2led_G = pyb.LED(2)
紅色LED3led_B = pyb.LED(3)
兩個紅外LED4led_IR = pyb.LED(4)

??在上表中可以看到在寫法中都為“y = pyb.LED(x)”,可知LED的控制所依賴pyb模塊,所以在程式的開始應先將pyb模塊引入,控制LED燈點亮的方法為led_R.on(),熄滅的方法為led_R.off(),相應的使用示例如下,

import pyb,time        				# 匯入庫檔案

led_R = pyb.LED(1)					# 定義紅色LED控制
led_G = pyb.LED(2)					# 定義綠色LED控制
led_B = pyb.LED(3)					# 定義藍色LED控制
led_IR = pyb.LED(4)					# 定義紅外LED控制

while(True):						# 死回圈
	led_R.on()						# 紅色LED點亮
	led_G.on()						# 綠色LED點亮
	led_B.on()						# 藍色LED點亮
	led_IR.on()						# 紅外LED點亮
	time.sleep_ms(500)				# 延時0.5S
	led_R.off()						# 紅色LED熄滅
	led_G.off()						# 綠色LED熄滅
	led_B.off()						# 藍色LED熄滅
	led_IR.off()					# 紅外LED熄滅
	time.sleep_ms(500)				# 延時0.5S

3.控制IO口輸入輸出

??在上一個控制LED示例中并未通過直接控制IO口的方式去控制LED的狀態,而是呼叫了pyb庫中已經寫好的介面實作控制目的,此講來說一下如何直接控制一個IO口,首先IO的控制依賴Pin模塊,而Pin模塊又包含在pyb模塊中,所以在程式開始要提前添加Pin模塊【from pyb import Pin】,
??學習過stm32單片機的同學都知道,在初始化一個IO口時,需要配置IO口的引腳編號、輸入輸出模式以及上下拉模式等,在使用STM32為主控單元的OpenMV中也是如此,如下表所示,

配置模式輸入or輸出模式代碼上下拉模式代碼
下拉輸入Pin.INPin.PULL_DOWN
上拉輸入Pin.INPin.PULL_UP
浮空輸入Pin.INPin.PULL_NONE
開漏輸出Pin.OUT_OD
推挽輸出Pin.OUT_PP

??實際使用的例程如下:

from pyb import Pin								# 引入Pin庫

p0_out = Pin('P0', Pin.OUT_PP)					# 設定P0埠為推挽輸出模式
p0_out.high()									# 設定P0埠輸出高電平
p0_out.low()									# 設定P0埠輸出低電平

p1_in = Pin('P1', Pin.IN, Pin.PULL_UP)			# 設定P1埠為上拉輸入模式
p1_value = p1_in.value() 						# 獲取P1埠的值,0或1,高電平為1,低電平為0

4.控制串口引腳輸出資訊

??在OpenMV 4 Plus中,有兩個串口可以使用,分別為串口1和串口三,引腳對應關系如下表所示,

串口埠號對應功能
UART 1P5RX
UART 1P4TX
UART 3P0RX
UART 3P1TX

??常用的串口相關函式如下表,

型別函式名示例實作功能
配置UART()uart = UART(3, 9600)創建串口3物件,并初始化串口3,波特率9600,其他引數默認
配置uart.init()uart.init(9600, bits=8, parity=None, stop=1)重新配置串口引數【接UART()后使用】
波特率9600,8位資料長度,無校驗位,1位停止位
讀取uart.read()str = uart.read()讀取所有可用字符
讀取uart.read()str = uart.read(x)讀取x位字符
讀取uart.readchar()num = uart.readchar()讀取一個字符,并回傳其整數形式
讀取uart.readline()str = uart.read(x)讀取一行【到回車換行結束】
讀取uart.readinto()uart.readinto(buf)讀取并存入緩沖區buf內
讀取狀態uart.any()num = uart.any()回傳等待的字符數量,用于檢查是否有串口資料接收到
發送uart.write()uart.write(‘abc’)發送字串‘abc’
發送uart.writechar()uart.writechar(42)發送一個字符’B’ ,數值42對應ASCLL碼的符號B

對串口功能的使用也是依賴與pyb模塊,在程式開始要提前添加pyb模塊,使用示例如下,

from pyb import UART                # 匯入串口支持庫檔案

uart = UART(3, 115200)              # 創建串口3設備,并設定波特率為115200

num = 132							# 隨便定義一個數值變數
num_str = "[%d]" % num    			# 將資料轉化為字串用于輸出
uart.write(fps_str+"\r\n")      	# 串口3輸出【通過 P4埠】

while(True):
	if uart.any()>0:							# 如果串口接收到資料【通過 P5埠】
		str = uart.read()						# 讀取接收到的字符
		uart.write("redata:"+ str+ "\r\n")      # 將收到的資料通過串口3輸出【通過 P4埠】

5.第一個影像例程HelloWord

??此例程為最基礎的HelloWord級例程,內部包含了相關模塊的依賴、攝像頭的初始化、拍照并存放至快取變數中以及列印影像的獲取幀率,以后的所有有關影像處理的程式都將以此程式為基礎進行撰寫,


import sensor, image, time			# 引入此例程依賴的模塊,sensor是與攝像頭引數設定相關的模塊,image是影像處理相關的模塊,time時鐘控制相關的模塊,import相當于c語言的#include <>,模塊相當于c語言的庫,

sensor.reset()                      # 復位并初始化攝像頭,reset()是sensor模塊里面的函式
sensor.set_pixformat(sensor.RGB565) # 設定影像色彩格式,有RGB565色彩圖和GRAYSCALE灰度圖兩種
sensor.set_framesize(sensor.QVGA)   # 將影像大小設定為QVGA (320x240)
									# 設定影像像素大小,QQVGA: 160x120,QQVGA2: 128x160,QVGA: 320x240,VGA: 640x480, QQCIF: 88x72,QCIF: 176x144,CIF: 352x288

sensor.skip_frames(time = 2000)     # 等待設定生效,
clock = time.clock()                # 初始化時鐘,并創建一個時鐘物件來跟蹤FPS幀率,

while(True):						# python while回圈,一定不要忘記加冒號“:”
    clock.tick()                    # 更新FPS幀率時鐘,
    img = sensor.snapshot()         # 拍一張照片并回傳影像,截取當前影像,存放于變數img中,注意python中的變數是動態型別,不需要宣告定義,直接用即可,
    print(clock.fps())				# 列印當前的幀率,注意: 當連接電腦后,OpenMV會變成一半的速度,當不連接電腦,幀率會增加,

6.單顏色識別例程

??在OpenMV IDE的選單【檔案->示例->OpenMV-ColotTracking】中依次找到例程,即為單顏色識別程式,
在這里插入圖片描述
??單顏色識別的程式如下所示,可知此程式就是在上一個HelloWord例程的基礎上使用了find_blobs()方法對拍攝到的圖片進行顏色的識別,

import sensor, image, time

green_threshold   = (   0,   80,  -70,   -10,   -0,   30)   # 要識別的顏色LAB值

sensor.reset()                                              # 初始化sensor
sensor.set_pixformat(sensor.RGB565)                         # 設定影像色彩格式,有RGB565色彩圖和GRAYSCALE灰度圖兩種
sensor.set_framesize(sensor.QVGA)                           # 使用QVGA的解析度
sensor.skip_frames(10)                                      # 等待設定生效,
sensor.set_auto_whitebal(False)                             # 關閉白平衡,白平衡是默認開啟的,在顏色識別中,建議關閉白平衡,

while(True):

    img = sensor.snapshot()                                 # 拍一張照片并回傳影像,
    blobs = img.find_blobs([green_threshold])               # 識別并回傳結果【回傳一個串列】
    
    if blobs:                                               # 如果找到了目標顏色【即串列不為空】
        for b in blobs:                                     # 遍歷找到的目標顏色區域【因為可能存在不只一個顏色塊】
            img.draw_rectangle(b[0:4])                      # 用矩形標記出目標顏色區域
            img.draw_cross(b[5], b[6])                      # 在目標顏色區域的中心畫十字形標記
            print(b[5], b[6])                               # 輸出目標物體中心坐標【通過串行終端 USB設備】

??其中find_blobs()方法的輸入引數是一個LAB格式的顏色閾值,作為欲識別的顏色,回傳值是一個包括識別到的每個色塊物件的串列,回傳值具體是個什么意思呢,首先是個串列,串列內的每個一條資訊都是找到的一個色塊的資訊,此資訊中又包含10個值,分別代表的意義如下表所示【假設串列中某條資訊為b】,串列內資訊值的使用除了可以用下標的方式取出,還可以通過[.變數名]的方式使用,如下表所示【假設串列中某條資訊為b】:

標號方式使用內部方法方式使用意義
b[0]b.x()識別到的目標顏色區域左上頂點的x坐標
b[1]b.y()識別到的目標顏色區域左上頂點的y坐標
b[2]b.w()識別到的目標顏色區域的寬
b[3]b.h()識別到的目標顏色區域的高
b[4]b.pixels()識別到的目標顏色區域的像素點的個數
b[5]b.cx()識別到的目標顏色區域的中心點x坐標
b[6]b.cy()識別到的目標顏色區域的中心點y坐標
b[7]b.rotation()識別到的目標顏色區域的旋轉角度(是弧度值,浮點型,串列其他元素是整型)
b[8]b.count()識別到的所有顏色區域與此目標區域交叉的目標個數
b[9]b.code()識別到的目標顏色區域顏色的編號(它可以用來分辨這個區域是用哪個顏色閾值識別出來的)
blob.rect()回傳一個矩形元組(x, y, w, h) ,用于如色塊邊界框的 image.draw_rectangle 等 其他的 image 方法

??那么具體的待識別LAB顏色閾值如何設定呢,可以使用OpenMV IDE中的“閾值編輯器”工具,對攝像頭中拍攝的待識別影像進行LAB顏色閾值的調整,
在這里插入圖片描述
??選擇幀緩沖區
在這里插入圖片描述
??比如說要識別圖片中紅色的顏色,那么拖動下面的LAB最大最小值,使右側的串口中僅剩紅色部分為白色,此時視窗下方的LAB閾值即為需要識別的顏色的LAB閾值,此處我調整的經驗是,先將全部的最小值拖至最左側,全部的最大值拖至最右側,然后依次拖動LAB值,僅需一次完整程序即可將右側影像僅剩待處理顏色塊,【注意,白色部分是待識別的顏色】
在這里插入圖片描述
??將獲得的LAB值復制,并粘貼值代碼中的green_threshold=()括號內,即完成顏色的識別設定,此時運行程式,即可準確的將攝像頭捕獲的影像中的紅色標注出來,
在這里插入圖片描述

??如果欲讓OpenMV在不連接OpenMV IDE時也可以進行此程式功能,則可以在編輯器的選單欄【工具->將打開的腳本檔案保存到OpenMV Cam】中將程式代碼保存到OpenMV中去,
在這里插入圖片描述

7.多顏色識別例程

??多顏色識別與單顏色識別基本上是一致的,都是使用了同一個方法find_blobs(),只不過將輸入的閾值從一個增加至了多個,閾值的設定也與單顏色的設定相同,使用“閾值編輯器”依次將每種顏色的影像進行處理即可,調整后的識別效果如下,
在這里插入圖片描述
??多顏色識別代碼,其中find_blobs()方法比單顏色識別程式中多了兩個引數,pixels_threshold和area_threshold,其中pixels_threshold是設定邊界框區域閾值,若一個色塊的邊界框區域小于 area_threshold ,則會被過濾掉, pixel_threshold是設定像素數閾值,若一個色塊的像素數小于 pixel_threshold ,則會被過濾掉,

import sensor, image, time, math

# 多顏色識別最多可同時識別16種顏色
thresholds = [(0, 100, 13, 127, 34, 67),    # 待識別顏色LAB閾值1
              (81, 100, -128, -13, 13, 53), # 待識別顏色LAB閾值2
              (38, 100, -87, 22, -98, -33)] # 待識別顏色LAB閾值3

sensor.reset()                              # 初始化攝像頭,reset()是sensor模塊里面的函式
sensor.set_pixformat(sensor.RGB565)         # 設定影像色彩格式,有RGB565色彩圖和GRAYSCALE灰度圖兩種
sensor.set_framesize(sensor.QVGA)           # 設定影像像素大小302*240
sensor.skip_frames(time = 2000)             # 等待設定生效
sensor.set_auto_gain(False)                 # 顏色跟蹤建議關閉自動增益
sensor.set_auto_whitebal(False)             # 顏色跟蹤建議關閉白平衡

while(True):

    img = sensor.snapshot()															   # 拍照并獲取影像
    for blob in img.find_blobs(thresholds, pixels_threshold=200, area_threshold=200):  # 進行多顏色識別
        img.draw_rectangle(blob.rect())												   # 框出識別到的色塊
        img.draw_cross(blob.cx(), blob.cy())										   # 標出色塊中心點

8.【串口】多顏色識別-回傳色塊中心坐標

??在上個示例中已實作顏色的識別和色塊的框選,在教程的開始處還講解了串口的使用方法,本示例將其組合至一起,實作將識別到每個顏色色塊中心點的坐標通過串口發送出去,代碼如下:

import sensor, image, time, math            # 匯入串口支持庫檔案
from pyb import UART                        # 匯入串口支持庫檔案


# 多顏色識別最多可同時識別16種顏色
thresholds = [(0, 100, 13, 127, 34, 67),    # 待識別顏色LAB閾值1
              (81, 100, -128, -13, 13, 53), # 待識別顏色LAB閾值2
              (38, 100, -87, 22, -98, -33)] # 待識別顏色LAB閾值3

sensor.reset()                              # 初始化攝像頭,reset()是sensor模塊里面的函式
sensor.set_pixformat(sensor.RGB565)         # 設定影像色彩格式,有RGB565色彩圖和GRAYSCALE灰度圖兩種
sensor.set_framesize(sensor.QVGA)           # 設定影像像素大小302*240
sensor.skip_frames(time = 2000)             # 等待設定生效
sensor.set_auto_gain(False)                 # 顏色跟蹤建議關閉自動增益
sensor.set_auto_whitebal(False)             # 顏色跟蹤建議關閉白平衡

uart = UART(3, 115200)                      # 創建串口3設備,并設定波特率為115200

while(True):

    uart.write("-------------------------\r\n")                   	# 串口3輸出【通過 P4埠】
    img = sensor.snapshot()															   # 拍照并獲取影像
    for blob in img.find_blobs(thresholds, pixels_threshold=200, area_threshold=200):  # 進行多顏色識別
        img.draw_rectangle(blob.rect())												   # 框出識別到的色塊
        img.draw_cross(blob.cx(), blob.cy())										   # 標出色塊中心點
        Str_x = "[%3d]" % blob.cx()									# 將中心點X坐標轉為長度為3的字串
        Str_y = "[%3d]" % blob.cy()									# 將中心點y坐標轉為長度為3的字串
        if blob.code()==1:											# 如果識別
            uart.write("red   X:"+Str_x+"  Y:"+Str_y+"\r\n")        # 串口3輸出【通過 P4埠】
        if blob.code()==2:
            uart.write("green X:"+Str_x+"  Y:"+Str_y+"\r\n")      	# 串口3輸出【通過 P4埠】
        if blob.code()==4:
            uart.write("blue  X:"+Str_x+"  Y:"+Str_y+"\r\n")       	# 串口3輸出【通過 P4埠】
    uart.write("-------------------------\r\n\r\n")               	# 串口3輸出【通過 P4埠】

??在以上程式中,對于當前資訊是什么顏色的,使用code()方法配合判斷,code()方法回傳的是用于識別的閾值串列中的顏色位置,即,本次識別使用的LAB顏色閾值在上面程式中thresholds串列中是第幾個顏色,在上面程式中thresholds串列中有三個顏色,第一個是紅色(0, 100, 13, 127, 34, 67),第二個是綠色(81, 100, -128, -13, 13, 53),第三個是藍色(38, 100, -87, 22, -98, -33),【(感謝網友的指導)所以,當code()方法回傳1證明本次識別到的是紅色,回傳2證明本次識別到的是綠色,回傳3證明本次識別到的是藍色,但是在實際的使用中發現,識別藍色的時候回傳值為4,此處本人尚未查明原因,若有朋友知道誠邀指導,
??所以,當code()方法回傳二進制00000001->十進制1,證明本次識別到的是紅色;回傳00000010->2,證明本次識別到的是綠色;回傳00000100->4,證明本次識別到的是藍色,

??識別后在串口軟體中列印的效果如下:
在這里插入圖片描述

四、開啟TensorFlow Lite神經網路之旅

本章對應星瞳視頻教程:OpenMV 4 Plus 訓練神經網路進行口罩識別

1.TensorFlow Lite介紹

在這里插入圖片描述
??人工智能、神經網路以及機器學習等應用皆需要大量的計算資源以及高性能的處理器加成,動輒就是上GPU群或者云服務器集群來處理,想要在一般的嵌入式芯片或者單片機上執行是想都不要想的事情,
??但是當前的邊緣處理場景越來越多,需求也越來越大,所以一些針對IOT設備和嵌入式設備的遷移學習網路應運而生,而Tensorflow Lite就是在這樣的情境下誕生的,是在完整的Tensorflow上進行裁剪、優化以及量身定做的,是針對移動設備和嵌入式設備的專用輕量化解決方案,其占用空間小且延遲低,

①主要特點有:
???支持浮點運算和量化模型,并已針對移動平臺進行優化,可以用來創建和運行自定義模型,開發者也可以在模型中添加自定義操作,
???FlatBuffer格式
???具有在移動設備運行更快的內核解釋器
???支持通過Tensorflow訓練好的模型轉換為Tensorflow Lite格式(pd,h5等都可以)
???當支持所有優化操作時,模型小于300k,當僅支持inception v3和mobilenet模型優化時,模型小于200k

②預訓練模型:
???inception v3:用于目標檢測
???MobileNets:專門針對移動端的模型,具有低延遲,高速度,低記憶體,可用于影像識別,目標檢測,影像分割,但是精度小于inception v3
???量化版本的MobileNets,通過將float-32轉為int-8,在CPU上擁有更快的速度
???支持java,c++API

??以上談到的預訓練模型基于ImageNet資料集訓練,支持1000種類別,如果此資料集不能滿足你的專案需要,你需要準備自己的資料集和標簽,使用遷移學習重新訓練模型,

2.使用支持

??但是盡管Tensorflow Lite已經足夠小、足夠快速,但是作為資源非常緊俏的單片機來說,尤其是作影像處理,還是有點力不從心,好在OpenMV 4 Plus使用的單片機是當前stm32單片機中性能最強的H7系列,而且外擴了較大的SDRAM作為資料處理記憶體使用,已基本滿足進行一些資料量小、影像像素低的識別任務要求,
??但是滿足了基本的硬體資源支持,進行一款神經網路的搭建、訓練和除錯,還是需要付出極大的學習成本的,如果讓一個單片機從業者為了產品需求,進軍人工智能方面的學習,無論從產品周期來說、還是學習能力的考驗方面來說,都不是個好的方法,
??為了進一步降低神經網路模型在嵌入式設備部署的難度,在線訓練模型網站Edge Impulse誕生了,此網站專門針對各種設備創建了各種的訓練場景,以創建工程、設定引數的方式完成網路模型的訓練,基本步驟:添加訓練資料->選擇模型->設定訓練引數->點擊開始訓練->訓練結果準確度達到要求->生成指定設備的可執行代碼->直接將代碼下載到設備運行,直達網址:https://studio.edgeimpulse.com/login
在這里插入圖片描述

3.使用OpenMV采集訓練資料

??在進行神經網路模型訓練前需要先將訓練用的資料準備好,本次訓練目的為垃圾分類,那么訓練用的資料為圖片,打開OpenMV IDE,在選單處選擇【工具->資料集編輯器->新資料集】,
在這里插入圖片描述
??自己隨便選擇一個位置創建檔案夾命名為【資料集】(隨便),并點擊選擇檔案夾,
在這里插入圖片描述
??之后會進入如下界面,首先可以創建你想要分類的所有檔案夾(也稱為標簽),之后依次在每個標簽下拍下此類物品的各角度照片,建議在100張左右即可,
在這里插入圖片描述
??具體的操作如下(動圖,因為有5MB大小限制,動圖較模糊):

在這里插入圖片描述
??根據自己的所需,創建對應的標簽并采集完足夠的素材,展現效果如下:
在這里插入圖片描述

??★需要注意的是,采集的同一標簽下的影像要保證其特征明顯,這樣訓練出來的模型準確率才高,如果特征不明顯,在Edge Impulse網站進行特征生成時,甚至會生成失敗,此時就要重新對所采集的照片進行篩選處理,然后重新生成,★

4.上傳Edge Impulse進行訓練

4.1注冊賬號并創建Edge Impulse工程

??打開Edge Impulse網站,注冊就是一般流程沒有什么特殊性,就不描述了,登陸成功后會跳轉到創建工程頁面,按下圖步驟創建工程,
在這里插入圖片描述
??之后會進入指引頁面,因為是外文網站,所以整個網頁內容都是英文的,英語不好的小伙伴建議使用帶網頁翻譯功能的瀏覽器為好,我用的是Google Chrome瀏覽器自帶翻譯插件,翻譯后頁面效果如下,
在這里插入圖片描述

4.2 上傳訓練集

??雖然OpenMV IDE帶有直接上傳至Edge Impulse工程的功能,但是經過實測,并不是那么好用,會因為各種原因如防火墻等影響導致無法上傳,所以建議直接手動上傳就可以了,點擊左側“資料采集”導航欄,進入上傳資料頁面,點擊上傳圖示進入上傳頁面,
在這里插入圖片描述
??按照以下步驟,依次選擇檔案->設定輸入標簽->點擊上傳,完成一組標簽內容的上傳,重復此步驟,直至將采集到的全部的照片上傳完畢,

在這里插入圖片描述
??上傳完之后,再次點擊左側“資料采集”導航欄,重新進入上傳資料頁面,將會看到已上傳的資料詳情,
在這里插入圖片描述

4.3 生成特征

??首先點擊左側“創建沖動”導航按鈕,進行輸入資料物件、訓練模型的選擇,并點擊保存,如下動圖所示,【為方便處理,一般建議影像大小為96x96或160x160】
在這里插入圖片描述
??點擊右側影像導航欄按鈕,選擇RGB模式,點擊保存,保存后會自動跳轉至生成特征界面,
在這里插入圖片描述

??點擊生成特征按鈕,等待生成完畢,會顯示右側的生成特征的3維影像,如果顯示失敗,則證明采集的影像特征不明顯,導致特征有重疊部分,則需要重新對訓練的影像進行篩選后上傳訓練,
在這里插入圖片描述

4.4 進行訓練

??至此萬事具備只欠東風,進入遷移學習訓練界面,依次設定訓練的引數,如訓練周數:越大訓練次數越多、時間越長,相應的結果準確率也越有可能高,學習率:此值決定了訓練的速度,如果過擬合過快,則要降低此值,最低置信度:比較好理解,就是準確率達到百分之多少,標記為識別成功,然后選擇神經網路架構,可根據自己設定沖動是設定的圖片大小進行選擇,也可以使用默認的,每個神經網路架構訓練出來的模型結果也是不同的,可以自己實驗最符合自己要求的結構,之后點擊開始訓練,等待訓練完成即可,

在這里插入圖片描述
??如果最后的結果準確率不滿意,可嘗試更改引數重新訓練,如果一直不夠理想,可回傳之前的步驟重新設定圖片大小以及訓練引數等,甚至進一步考慮自己采集的訓練集影像是不是特征不明顯,導致的準確率低,在結果準確率滿意的情況下,可進行下一步,

5.在OpenMV上部署

??進入部署界面,選擇生成OpenMV韌體,點擊構建,會自動下載生成的OpenMV代碼和模型,
在這里插入圖片描述
??下載下來的壓縮包內包含訓練完的模型“trained.tflite”,OpemMV執行模型的代碼“ei_image_classification.py”,以及模型內部包含的所有分類標簽“labels.txt”,將OpenMV生成的U盤內的檔案全部洗掉掉,然后將下載下來的壓縮包內的檔案全部復制進去,為保證OpenMV離線狀態下可自動執行識別程式,將復制進去后的“ei_image_classification.py”重命名為“main.py”,
在這里插入圖片描述
??之后將U盤內的main.py檔案在OpenMV IDE內打開,并運行,此時觀察串口終端內會輸出識別結果以及準確率,輸出的標簽后面都跟著一個數值,此數值代表識別結果認為是此標簽的可能性,=1表示識別程式認為100%是此標簽的物品,
在這里插入圖片描述
??如果想讓其輸出的結果為中文,則可打開labels.txt檔案,并將其內部的英文標簽對應位置翻譯為中文保存即可,修改完畢后效果如下,
在這里插入圖片描述
??識別出結果后,可修改代碼通過串口輸出識別到的結果給其他單片機使用,串口相關的具體代碼已在文中有過說明,自己修改吧,😄😄😄


??🧡至此本文章欲說明的內容已全部做出示例和詳細的介紹🧡

五、錯誤情況問題 【更新時間2021-8-04】

??這段時間以來,很多小伙伴在實踐此文章的神經網路部署方面出現了各種各樣的問題,再此做一個匯總和解決方案,

1.“OSError” 錯誤

??出現最多的無非是OSError:,如下圖樣式,翻譯過來呢是說:目前,僅支持float32輸入型別,當然也有出現float16錯誤的,
在這里插入圖片描述
??最早出現此情況的一個朋友在我們共同的努力下,成功解決了此問題,雖然解決方法比較玄學,但是最終鎖定了原因出在訓練模型的引數配置上,下圖是問他最終什么原因他說的原話,他說把所有圖片放到了open mv 的flash中,不過我覺得這個應該是不需要的,根本原因應該是在訓練的配置上,
在這里插入圖片描述

??解決思路如下:
??①首先要查看自己的open MV是否為4Plus,若不是,則無法使用此例程,
??②之后連接open MV IDE進行韌體升級,確保為最新的韌體,
??③下載我提供的,我訓練好并且經過驗證沒有任何問題的韌體【點此下載-gitee】,部署到自己的open MV上運行,看是否還有例外問題,
??④-1如果運行還有例外,說明您的open MV有問題,請更換官方正版open MV 4Plus再次嘗試,
??④-2如果運行無例外,則說明您訓練的模型有問題,請重新訓練,
??⑤如果鎖定是訓練問題,請仔細檢查自己采集的訓練影像,看特征是否明顯,請重新創建一個新的訓練工程,按照步驟重新配置,可以盡量使用默認引數,這里因為本人并不是專業的人工智能人員,故這里的引數也無法給您提供建議,自己多嘗試嘗試吧,只要思路正確,找到問題所在,總能夠解決,

2.運行速度慢

??其實本來作為openMV來說,運行此類程式就是比較勉強的,所以出現幀率很低的情況也屬正常,但是在注意一些細節的情況下也有優化的空間,比如調低影像的生成特征的解析度,適當調整訓練引數,以及更改為更適合的模型結構等,自己多試試總結總結吧,
在這里插入圖片描述

3.“MemoryError” 記憶體不足

??還有小伙伴出現了以下的錯誤,提示說記憶體不足,注意這里的記憶體指的是RAM,是運行記憶體空間,而不是flash或者SD大小,出現這種情況,一般表明您的open MV不是4Plus,所以是無法運行此垃圾識別的程式的,
在這里插入圖片描述

4.其他問題

??如出現“trained.tflite - 無法讀取壓縮包資料”,這樣的問題,請仔細檢查是否將模型放置到了openMV的代碼空間內,或者查看名稱是否有寫錯誤等,
??其實除了上述3個問題外,其他問題基本都屬于細節性問題了,自己靜下心來再仔細檢查檢查吧,

5.解決問題一般思路

??其實如何解決問題,如何找到問題的關鍵所在,是一種非常重要的能力,在自己的專案出現問題時,首先要將思路理清,一般首先將專案分為幾個大的部分,通過控制變數法依次排除掉可以確定沒問題的部分,將問題鎖定在某一個范圍內,再次重復此程序直至找到問題的根源所在,

??比如咱們這個專案,可以首先將其分為兩大塊:①open MV ②訓練的模型,

??接下來就要大致鎖定問題出在①部分還是②部分,在這里有兩個思路:
??(1)將自己訓練好的模型放到其他運行過此類代碼并且確認完好的openMV上去執行,這樣可以確認自己訓練的模型是否出現問題;
??(2)去下載別人訓練好并且經過驗證的模型,然后在自己的openMV上執行,這樣可以查看自己openMV是否出現問題,
??如果是模型出現問題,則要考慮是采集的訓練集有問題?特征生成配置有問題?訓練引數有問題?還是最后的模型結構不匹配?
??如果是openMV有問題,則考慮韌體是否為最新版?是否硬體出了問題?是否為正版設備?還是說型號搞錯了?等等,

??當然,本專案比較簡單,可以比較容易的鎖定問題所在,如果是比較龐大的專案,則可能需要更多的排除次數,但是思路是一致的,


??加油,騷年們!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/348541.html

標籤:AI

上一篇:畢業設計 : 題目:基于深度學習的水果識別 設計 開題 技術

下一篇:李沐《動手學深度學習v2》學習筆記(二):線性回歸和實作

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more