【K210】K210学习笔记七——使用K210拍摄照片并在MaixHub上进行训练
【K210】K210學習筆記七——使用K210拍攝照片并在MaixHub上進行訓練
- 前言
- K210準備工作
- K210如何拍攝照片
- 準備工作
- 拍攝相關代碼定義
- 用K210拍攝到的照片在MaixHub平臺上訓練模型
- 測試
- 未開啟數據增強的測試結果
- 開啟數據增強的測試結果
- 小結
前言
本人大四學生,電賽生涯已經走到盡頭,一路上踩過不少坑,但運氣也不錯拿了兩年省一,思來想去,決定開始寫博客,將電賽經驗分享一二,能力有限,高手輕噴。
往期的博客講述了 K210 的感光元件模塊 sensor 的配置,機器視覺模塊 image 中部分函數的使用(目前是用 find_blobs 函數實現一些尋找不同顏色的目標點,尋找不同顏色的線,后面會更新更多 image 模塊中的函數使用方法),按鍵、LCD、LED的使用,定時器的使用,串口通信的方法,以及如何使用MaixHub平臺在線訓練模型。
sensor 的學習筆記傳送門
【K210】K210學習筆記一——sensor
image 的學習筆記傳送門
【K210】K210學習筆記二——image
按鍵、LCD、LED的使用 的學習筆記傳送門
【K210】K210學習筆記三——按鍵、LCD、LED的使用
定時器的使用傳送門
【K210】K210學習筆記四——定時器的使用
串口通信傳送門
【K210】K210學習筆記五——串口通信
MaixHub在線模型訓練傳送門
【K210】K210學習筆記六——MaixHub在線模型訓練識別數字
串口通信(往期)傳送門
【串口通信】K210與STM32串口通信、K210與OpenMV串口通信
本文著重于如何使用K210拍攝圖片,并將圖片上傳到MaixHub平臺進行模型訓練。補充一下一些經驗心得,比如一些訓練參數的設置。
K210準備工作
由于K210的RAM只有8M,為了讓運行的模型可以更大,避免出現內存不夠的情況,需要刷入小一點的固件,固件及刷固件工具如下,我設置的是0積分免費下載。
固件燒入
將壓縮包解壓,點開kflash文件夾,雙擊運行程序。
在打開的程序中點擊打開文件,然后選擇要刷入的固件。
然后點擊下載即可開始刷入固件。
K210如何拍攝照片
準備工作
這里需要用到SD卡,首先需要用讀卡器打開SD卡,在SD卡根目錄下創建一個名為img的文件夾。
然后將SD卡直接插到K210上即可。
拍攝相關代碼定義
導入模塊,這里打算用K210上自帶的按鍵KEY進行拍照(該按鍵自動接到16腳),所以除了必要的感光元件模塊以外,還需要引入引腳注冊模塊,lcd是方便脫機拍照(代碼燒入后,可以拿個充電寶或者其他的可以輸出5V電壓的給K210供電,就可以拿著K210拍照了,不然還要帶個筆記本電腦怪麻煩的)。
# Get_V1.0 - By: FITQY - 周五 8 月 26 日 2022 #__________________________________________________________________ # 導入模塊 import sensor, time, image # 導入感光元件模塊 sensor 跟蹤運行時間模塊 time 機器視覺模塊 image import utime # 導入延時模塊 utime from fpioa_manager import fm # 從 fpioa_manager 模塊中導入 引腳注冊模塊 fm from Maix import GPIO # 從 Maix 模塊中導入 模塊 GPIO import lcd # 導入 LCD 模塊感光元件的設置,比起之前的設置,只是多了倒數第二行的設置圖像大小為224 x 224。
#__________________________________________________________________ # 感光元件設置 sensor.reset() # 重置并初始化感光元件 默認設置為 攝像頭頻率 24M 不開啟雙緩沖模式 #sensor.reset(freq=24000000, dual_buff=True) # 設置攝像頭頻率 24M 開啟雙緩沖模式 會提高幀率 但內存占用增加sensor.set_pixformat(sensor.RGB565) # 設置圖像格式為 RGB565 (彩色) 除此之外 還可設置格式為 GRAYSCALE 或者 YUV422 sensor.set_framesize(sensor.QVGA) # 設置圖像大小為 QVGA (320 x 240) 像素個數 76800 K210最大支持格式為 VGAsensor.set_auto_exposure(0) # 關閉自動曝光 #sensor.set_auto_exposure(0, exposure=120000) # 設置手動曝光 曝光時間 120000 us#sensor.set_auto_gain(0) # 關閉畫面增益 sensor.set_auto_gain(0, gain_db = 16) # 設置畫面增益 16 dB 影響實時畫面亮度sensor.set_auto_whitebal(0) # 關閉RGB自動增益(白平衡) #sensor.set_auto_whitebal(0, rgb_gain_db = (0,0,0)) # 設置RGB增益 0 0 0 dB 影響畫面色彩呈現效果 在 K210 上無法調節增益 初步判定是感光元件 ov2640 無法支持#sensor.set_contrast(0) # 設置對比度 0 這個參數無法讀取 且調這個參數對畫面似乎不會產生影響 暫時注釋 #sensor.set_brightness(0) # 設置亮度 0 這個參數無法讀取 且調這個參數對畫面似乎不會產生影響 暫時注釋 #sensor.set_saturation(0) # 設置飽和度 0 這個參數無法讀取 且調這個參數對畫面似乎不會產生影響 暫時注釋sensor.set_vflip(1) # 打開垂直翻轉 如果是 01Studio 的 K210 不開啟會導致畫面方向與運動方向相反 sensor.set_hmirror(1) # 打開水平鏡像 如果是 01Studio 的 K210 不開啟會導致畫面方向與運動方向相反sensor.set_windowing((224,224)) # 設置圖像大小為 224 224sensor.skip_frames(time = 2000) # 延時跳過2s 等待感光元件穩定LED的設置,這一步可以沒有,我只是用來判斷按鍵有沒有被按下才加的這個,我設置的是,如果按鍵按下的話,LED會切換。
#__________________________________________________________________ # LED的使用 # 注冊 LED 引腳 fm.register(14, fm.fpioa.GPIO2, force = True) # 配置 14 腳為 LED_R 強制注冊 fm.register(13, fm.fpioa.GPIO1, force = True) # 配置 13 腳為 LED_G 強制注冊 fm.register(12, fm.fpioa.GPIO0, force = True) # 配置 12 腳為 LED_B 強制注冊# 創建 LED 對象 LED_R = GPIO(GPIO.GPIO2, GPIO.OUT) # 創建 LED_R 對象 LED_G = GPIO(GPIO.GPIO1, GPIO.OUT) # 創建 LED_G 對象 LED_B = GPIO(GPIO.GPIO0, GPIO.OUT) # 創建 LED_B 對象# LED控制函數 def LED_Control(led_flag): # LED控制函數 根據傳入 led_flag 點亮對應的燈 需要注意的是 0為點亮 1為熄滅if led_flag == 0: # 傳入參數為 0 所有燈打開LED_R.value(0)LED_G.value(0)LED_B.value(0)elif led_flag == 1: # 傳入參數為 1 所有燈關閉LED_R.value(1)LED_G.value(1)LED_B.value(1)elif led_flag == 2: # 傳入參數為 2 紅燈常亮LED_R.value(0)LED_G.value(1)LED_B.value(1)elif led_flag == 3: # 傳入參數為 3 綠燈常亮LED_R.value(1)LED_G.value(0)LED_B.value(1)elif led_flag == 4: # 傳入參數為 4 藍燈常亮LED_R.value(1)LED_G.value(1)LED_B.value(0)else: # 其他情況 紫燈LED_R.value(0)LED_G.value(1)LED_B.value(0)按鍵的設置,和往期一樣的,只是把另外三個按鍵刪掉了而已,然后在按鍵0的回調函數中加入了拍照函數。
#__________________________________________________________________ # 按鍵的使用 # 定義按鍵控制類 class Key_Control(): # 定義按鍵控制類cnt = 0 # 按鍵計數值cs = 0 # 按鍵模式選擇標志位csmax = 0 # 按鍵模式上限csflag = 0 # 按鍵模式切換標志位cinput = 0 # 按鍵輸入值保存位control = 0 # 按鍵確認及發送控制標志位img_cnt = 0 # 照片計數值# 實例化按鍵類 key = Key_Control() # 實例化按鍵控制類 Key_Control() 為 key key.csmax = 3 # 按鍵模式上限為 3 即最多有 4 個模式 (0, 1, 2, 3)# 注冊按鍵引腳 fm.register(16, fm.fpioa.GPIOHS0, force = True) # 配置 16 腳為 KEY0 使用高速 GPIO 口 強制注冊# 創建按鍵對象 KEY0 = GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_UP) # 創建按鍵對象 KEY0# 中斷回調函數 KEY0 控制按鍵模式選擇 def Key0_Switch(KEY0):utime.sleep_ms(10) # 延時 10ms 消除按鍵抖動if KEY0.value() == 0: # 確認 按鍵0 按下key.csflag = 1 # 標記按鍵模式切換if key.cs < key.csmax: # 若當前按鍵模式值小于按鍵模式選擇上限值key.cs = key.cs + 1 # 控制按鍵模式選擇 自增else: # 若達到上限 則重新從 0 開始key.cs = 0Get_Image(key) # 觸發中斷的時候拍攝一張照片# 開啟中斷 下降沿觸發 KEY0.irq(Key0_Switch, GPIO.IRQ_FALLING) # 開啟 按鍵0 外部中斷 下降沿觸發拍照函數如下所示,主要就是根據計數器的值保存照片,可以支持保存0000.jpg到9999.jpg共1萬張照片,如果你要保存超過1萬張,再加個判斷就好了(emm應該也沒有什么電賽題目識別的東西需要這么大的數據集吧)
#__________________________________________________________________ # 獲取照片函數 def Get_Image(key):# 拍攝一張照片 保存到 SD卡 的 img 目錄下 名字為 000 + key.img_cnt.jpg 如 0001.jpgif key.img_cnt < 10:sensor.snapshot().save("/sd/img/000"+str(key.img_cnt)+".jpg")elif key.img_cnt < 100:sensor.snapshot().save("/sd/img/00"+str(key.img_cnt)+".jpg")elif key.img_cnt < 1000:sensor.snapshot().save("/sd/img/0"+str(key.img_cnt)+".jpg")elif key.img_cnt < 10000:sensor.snapshot().save("/sd/img/"+str(key.img_cnt)+".jpg")key.img_cnt = key.img_cnt + 1 # 計數值自增然后就是LCD的設置,這一步最好要有,有了會比較方便,還可以在LCD上看到當前拍攝了幾張圖片(第一行img_cnt后面顯示的數字就是拍攝照片的張數)
#__________________________________________________________________ # LCD # LCD 初始化 lcd.init() # lcd初始化# LCD 打印照片張數 def LCD_Show():lcd.draw_string(0, 0, "img_cnt: "+str(key.img_cnt), lcd.BLUE, lcd.WHITE)lcd.draw_string(0, 15, "Gain : "+str(sensor.get_gain_db()), lcd.BLUE, lcd.WHITE)lcd.draw_string(0, 30, "RGBGain: "+str(sensor.get_rgb_gain_db()), lcd.BLUE, lcd.WHITE)主函數如下所示,key.img_cnt這一句話是設置從第幾個序號開始保存照片,舉個例子。
比如設置為0,那么就是從0000開始保存。
設置為100,就是從0100開始保存。
這一個設置的目的就是,方便后續添加數據集,比如我現在只拍攝了31張圖片,那么img文件夾里面的照片是從0000.jpg到0030.jpg,如果要添加新。的數據集,那么需要將key.img_cnt的值改成31,就可以從0031.jpg開始保存,如果從0000開始的話會覆蓋掉之前的照片。
完整代碼如下,可以復制然后用K210拍攝你的數據集了!
# Get_V1.0 - By: FITQY - 周五 8 月 26 日 2022 #__________________________________________________________________ # 導入模塊 import sensor, time, image # 導入感光元件模塊 sensor 跟蹤運行時間模塊 time 機器視覺模塊 image import utime # 導入延時模塊 utime from fpioa_manager import fm # 從 fpioa_manager 模塊中導入 引腳注冊模塊 fm from Maix import GPIO # 從 Maix 模塊中導入 模塊 GPIO import lcd # 導入 LCD 模塊#__________________________________________________________________ # 感光元件設置 sensor.reset() # 重置并初始化感光元件 默認設置為 攝像頭頻率 24M 不開啟雙緩沖模式 #sensor.reset(freq=24000000, dual_buff=True) # 設置攝像頭頻率 24M 開啟雙緩沖模式 會提高幀率 但內存占用增加sensor.set_pixformat(sensor.RGB565) # 設置圖像格式為 RGB565 (彩色) 除此之外 還可設置格式為 GRAYSCALE 或者 YUV422 sensor.set_framesize(sensor.QVGA) # 設置圖像大小為 QVGA (320 x 240) 像素個數 76800 K210最大支持格式為 VGAsensor.set_auto_exposure(0) # 關閉自動曝光 #sensor.set_auto_exposure(0, exposure=120000) # 設置手動曝光 曝光時間 120000 us#sensor.set_auto_gain(0) # 關閉畫面增益 sensor.set_auto_gain(0, gain_db = 16) # 設置畫面增益 16 dB 影響實時畫面亮度sensor.set_auto_whitebal(0) # 關閉RGB自動增益(白平衡) #sensor.set_auto_whitebal(0, rgb_gain_db = (0,0,0)) # 設置RGB增益 0 0 0 dB 影響畫面色彩呈現效果 在 K210 上無法調節增益 初步判定是感光元件 ov2640 無法支持#sensor.set_contrast(0) # 設置對比度 0 這個參數無法讀取 且調這個參數對畫面似乎不會產生影響 暫時注釋 #sensor.set_brightness(0) # 設置亮度 0 這個參數無法讀取 且調這個參數對畫面似乎不會產生影響 暫時注釋 #sensor.set_saturation(0) # 設置飽和度 0 這個參數無法讀取 且調這個參數對畫面似乎不會產生影響 暫時注釋sensor.set_vflip(1) # 打開垂直翻轉 如果是 01Studio 的 K210 不開啟會導致畫面方向與運動方向相反 sensor.set_hmirror(1) # 打開水平鏡像 如果是 01Studio 的 K210 不開啟會導致畫面方向與運動方向相反sensor.set_windowing((224,224)) # 設置圖像大小為 224 224sensor.skip_frames(time = 2000) # 延時跳過2s 等待感光元件穩定#__________________________________________________________________ # 創建時鐘對象 clock = time.clock() # 創建時鐘對象 clock#__________________________________________________________________ # LED的使用 # 注冊 LED 引腳 fm.register(14, fm.fpioa.GPIO2, force = True) # 配置 14 腳為 LED_R 強制注冊 fm.register(13, fm.fpioa.GPIO1, force = True) # 配置 13 腳為 LED_G 強制注冊 fm.register(12, fm.fpioa.GPIO0, force = True) # 配置 12 腳為 LED_B 強制注冊# 創建 LED 對象 LED_R = GPIO(GPIO.GPIO2, GPIO.OUT) # 創建 LED_R 對象 LED_G = GPIO(GPIO.GPIO1, GPIO.OUT) # 創建 LED_G 對象 LED_B = GPIO(GPIO.GPIO0, GPIO.OUT) # 創建 LED_B 對象# LED控制函數 def LED_Control(led_flag): # LED控制函數 根據傳入 led_flag 點亮對應的燈 需要注意的是 0為點亮 1為熄滅if led_flag == 0: # 傳入參數為 0 所有燈打開LED_R.value(0)LED_G.value(0)LED_B.value(0)elif led_flag == 1: # 傳入參數為 1 所有燈關閉LED_R.value(1)LED_G.value(1)LED_B.value(1)elif led_flag == 2: # 傳入參數為 2 紅燈常亮LED_R.value(0)LED_G.value(1)LED_B.value(1)elif led_flag == 3: # 傳入參數為 3 綠燈常亮LED_R.value(1)LED_G.value(0)LED_B.value(1)elif led_flag == 4: # 傳入參數為 4 藍燈常亮LED_R.value(1)LED_G.value(1)LED_B.value(0)else: # 其他情況 紫燈LED_R.value(0)LED_G.value(1)LED_B.value(0)#__________________________________________________________________ # 按鍵的使用 # 定義按鍵控制類 class Key_Control(): # 定義按鍵控制類cnt = 0 # 按鍵計數值cs = 0 # 按鍵模式選擇標志位csmax = 0 # 按鍵模式上限csflag = 0 # 按鍵模式切換標志位cinput = 0 # 按鍵輸入值保存位control = 0 # 按鍵確認及發送控制標志位img_cnt = 0 # 照片計數值# 實例化按鍵類 key = Key_Control() # 實例化按鍵控制類 Key_Control() 為 key key.csmax = 3 # 按鍵模式上限為 3 即最多有 4 個模式 (0, 1, 2, 3)# 注冊按鍵引腳 fm.register(16, fm.fpioa.GPIOHS0, force = True) # 配置 16 腳為 KEY0 使用高速 GPIO 口 強制注冊# 創建按鍵對象 KEY0 = GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_UP) # 創建按鍵對象 KEY0# 中斷回調函數 KEY0 控制按鍵模式選擇 def Key0_Switch(KEY0):utime.sleep_ms(10) # 延時 10ms 消除按鍵抖動if KEY0.value() == 0: # 確認 按鍵0 按下key.csflag = 1 # 標記按鍵模式切換if key.cs < key.csmax: # 若當前按鍵模式值小于按鍵模式選擇上限值key.cs = key.cs + 1 # 控制按鍵模式選擇 自增else: # 若達到上限 則重新從 0 開始key.cs = 0Get_Image(key) # 觸發中斷的時候拍攝一張照片# 開啟中斷 下降沿觸發 KEY0.irq(Key0_Switch, GPIO.IRQ_FALLING) # 開啟 按鍵0 外部中斷 下降沿觸發#__________________________________________________________________ # 獲取照片函數 def Get_Image(key):# 拍攝一張照片 保存到 SD卡 的 img 目錄下 名字為 000 + key.img_cnt.jpg 如 0001.jpgif key.img_cnt < 10:sensor.snapshot().save("/sd/img/000"+str(key.img_cnt)+".jpg")elif key.img_cnt < 100:sensor.snapshot().save("/sd/img/00"+str(key.img_cnt)+".jpg")elif key.img_cnt < 1000:sensor.snapshot().save("/sd/img/0"+str(key.img_cnt)+".jpg")elif key.img_cnt < 10000:sensor.snapshot().save("/sd/img/"+str(key.img_cnt)+".jpg")key.img_cnt = key.img_cnt + 1 # 計數值自增#__________________________________________________________________ # LCD # LCD 初始化 lcd.init() # lcd初始化# LCD 打印照片張數 def LCD_Show():lcd.draw_string(0, 0, "img_cnt: "+str(key.img_cnt), lcd.BLUE, lcd.WHITE)lcd.draw_string(0, 15, "Gain : "+str(sensor.get_gain_db()), lcd.BLUE, lcd.WHITE)lcd.draw_string(0, 30, "RGBGain: "+str(sensor.get_rgb_gain_db()), lcd.BLUE, lcd.WHITE)#__________________________________________________________________ # 照片起始序號設置 key.img_cnt = 0#__________________________________________________________________ # 主函數模式選擇 while(True):clock.tick() # 跟蹤運行時間img=sensor.snapshot() # 攝像頭拍攝一張圖片lcd.display(img) # LCD 顯示圖像LCD_Show() # LCD 顯示照片張數LED_Control(key.cs) # 按鍵控制 LED 表示按鍵有成功按下#__________________________________________________________________用K210拍攝到的照片在MaixHub平臺上訓練模型
因為手頭上剛剛好有一個橘子,所以我就用它來做一個識別水果的(但我只做了一個識別橘子),將K210上電,然后對著橘子,按下KEY鍵即可拍照了。
然后,要用讀卡器打開K210上的SD卡,將文件夾img復制到電腦桌面。
然后打開MaixHub平臺,鏈接如下,賬號沒注冊的注冊一個就好(上一期有說)
MaixHub在線訓練平臺
需要新建一個項目,名稱就叫水果識別,類型選擇圖像檢測(圖像分類只能分類圖像,并不能獲取目標的坐標信息,因此圖像檢測用的比較多)
然后創建一個數據集,命名為水果。
然后選中該數據集。
然后將img中的圖片上傳到該訓練集。
然后這一步是上一篇教程中所沒有的,需要隨機選擇幾張圖片放到驗證集中,因為如果驗證集中沒圖片,訓練的時候會隨機抽取幾張圖片放到驗證集。
然后就是添加標簽,設置默認標簽,然后一張張開始打標簽了。
直到打完所有標簽,就可以開始訓練了。
訓練參數設置如下,這里隨機處理中的選項都不選(隨機鏡像、隨機旋轉、隨機模糊),模型選擇nncase,參數是訓練200次,批數據量大小是4,然后創建任務即可。
然后需要記住訓練的ID,不然后面找不到。
因為是在線訓練,不妨我們再創建一個任務,這次將圖像增強中的隨即部分全部勾選上,其他參數不變,再創建一個訓練任務,最后與之前的訓練任務比較一下。
同樣的需要記住訓練ID。
等待訓練結束,可以看到,平臺告訴我們準確率有1,但是在K210上未必每次都能正確識別到,因為我這里數據量太小了,就拍攝了四十幾張圖片,鏡頭拉近拉遠可能就無法識別了,如果對鏡頭到目標的距離有要求的,可以根據實際情況靠近或者遠一點拍攝圖片。
數據增強的那個訓練任務也完成了,可以看到,這個訓練的準確度比沒數據增強的高出不少。
然后就是下載壓縮包,進行測試了。
測試
首先要將壓縮包內的模型復制到SD卡中,這里我復制了兩個,一個是48,一個是50,48是沒有數據增強的,50是有數據增強的。
然后打開48的測試代碼測試即可。
記得將這兩個參數設置為1哦,這是開啟鏡頭轉置。
未開啟數據增強的測試結果
未開啟數據增強的(序號48)的測試結果不難看出,概率偏低,這是因為我拍攝的大部分圖片角度都差不多是同一個角度,因此可能我測試的時候角度換了一點,概率就下降了。
拿在手上的測試結果也不太理想,經常無法識別。
開啟數據增強的測試結果
可以看出,概率明顯上升了不少。
拿在手上,識別的效果也會比沒開啟數據增強的好上不少。
由此可得出,若需要提高識別的精準度,需要開啟數據增強,如果開啟數據增強后效果還是不理想,則需要增大數據集。
小結
使用K210拍攝照片,在MaixHub平臺進行模型訓練的教程已經做完了,并且分析了下數據增強對實際測試效果的影響。由于我并不是專門學這方面的,因此我感覺我這篇教程還寫的不是很好,有新的心得的話,后面我會持續更新的。 下一期主要說怎么將識別到的坐標通過串口通信傳輸到STM32,因為這里用的代碼是MaixHub平臺提供的,我需要將其中用得到的部分加入我之前的代碼中,然后通過串口通信發送出去,主要是為了方便大家使用,我想讓大家可以輕松的搞應用,在各種比賽拿獎,總之我的比賽之路是走到盡頭了,就是想將這些經驗傳承下去吧!下期再見咯!
總結
以上是生活随笔為你收集整理的【K210】K210学习笔记七——使用K210拍摄照片并在MaixHub上进行训练的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第三月模拟题——炉石传说
- 下一篇: 数据库实践LAB大纲 02 检索