Lobe ai 是微軟推出的離線版神經網路分類工具,相較於 Google Teachable Machine,離線就能訓練神經網路也許更適合教室使用。這股浪潮確實是資料驅動(data-driven)的時代,誰能掌握高品質的資料誰就能更快擁有合乎需求的神經網路。CAVEDU 2019 年所出版[實戰AI資料導向式學習]也有談到這個概念,使用 Raspberry Pi 搭配 Keras 訓練的視覺分類神經網路模型來實作路牌辨識機器人(讓我打一下書~嘛)
#
# -------------------------------------------------------------
# Copyright (c) CAVEDU. All rights reserved.
# -------------------------------------------------------------
"""
Skeleton code showing how to load and run the TensorFlow Lite export package from Lobe.
"""
import argparse
import json
import os
import numpy as np
from PIL import Image
import cv2
import tflite_runtime.interpreter as tflite
def get_prediction(image, interpreter, signature):
"""
Predict with the TFLite interpreter!
"""
# Combine the information about the inputs and outputs from the signature.json file with the Interpreter runtime
signature_inputs = signature.get("inputs")
input_details = {detail.get("name"): detail for detail in interpreter.get_input_details()}
model_inputs = {key: {**sig, **input_details.get(sig.get("name"))} for key, sig in signature_inputs.items()}
signature_outputs = signature.get("outputs")
output_details = {detail.get("name"): detail for detail in interpreter.get_output_details()}
model_outputs = {key: {**sig, **output_details.get(sig.get("name"))} for key, sig in signature_outputs.items()}
# process image to be compatible with the model
input_data = process_image(image, model_inputs.get("Image").get("shape"))
# set the input to run
interpreter.set_tensor(model_inputs.get("Image").get("index"), input_data)
interpreter.invoke()
# grab our desired outputs from the interpreter!
# un-batch since we ran an image with batch size of 1, and convert to normal python types with tolist()
outputs = {key: interpreter.get_tensor(value.get("index")).tolist()[0] for key, value in model_outputs.items()}
# postprocessing! convert any byte strings to normal strings with .decode()
for key, val in outputs.items():
if isinstance(val, bytes):
outputs[key] = val.decode()
return outputs
def process_image(image, input_shape):
"""
Given a PIL Image, center square crop and resize to fit the expected model input, and convert from [0,255] to [0,1] values.
"""
width, height = image.size
# ensure image type is compatible with model and convert if not
if image.mode != "RGB":
image = image.convert("RGB")
# center crop image (you can substitute any other method to make a square image, such as just resizing or padding edges with 0)
if width != height:
square_size = min(width, height)
left = (width - square_size) / 2
top = (height - square_size) / 2
right = (width + square_size) / 2
bottom = (height + square_size) / 2
# Crop the center of the image
image = image.crop((left, top, right, bottom))
# now the image is square, resize it to be the right shape for the model input
input_width, input_height = input_shape[1:3]
if image.width != input_width or image.height != input_height:
image = image.resize((input_width, input_height))
# make 0-1 float instead of 0-255 int (that PIL Image loads by default)
image = np.asarray(image) / 255.0
# format input as model expects
return image.reshape(input_shape).astype(np.float32)
def main():
"""
Load the model and signature files, start the TF Lite interpreter, and run prediction on the image.
Output prediction will be a dictionary with the same keys as the outputs in the signature.json file.
"""
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
'--model', help='Model path of .tflite file and .json file', required=True)
args = parser.parse_args()
with open( args.model + "/signature.json", "r") as f:
signature = json.load(f)
model_file = signature.get("filename")
interpreter = tflite.Interpreter(args.model + '/' + model_file)
interpreter.allocate_tensors()
cap = cv2.VideoCapture(0)
#擷取畫面 寬度 設定為640
cap.set(cv2.CAP_PROP_FRAME_WIDTH,640)
#擷取畫面 高度 設定為480
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
key_detect = 0
times=1
while (key_detect==0):
ret,frame =cap.read()
image = Image.fromarray(cv2.cvtColor(frame,cv2.COLOR_BGR2RGB))
if (times==1):
prediction = get_prediction(image, interpreter, signature)
print('Result = '+ prediction['Prediction'])
print('Confidences = ' + str(max(prediction['Confidences'])) )
cv2.putText(frame, prediction['Prediction'] + " " +
str(round(max(prediction['Confidences']),3)),
(5,30), cv2.FONT_HERSHEY_SIMPLEX, 1,
(0,0,255), 1, cv2.LINE_AA)
cv2.imshow('Detecting....',frame)
times=times+1
if (times >= 5):
times=1
read_key = cv2.waitKey(1)
if ((read_key & 0xFF == ord('q')) or (read_key == 27) ):
key_detect = 1
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
請選「Tensorflow Lite」à「Quantized」à「Download my model」。「Floating point」格式建議在個人電腦的環境操作;「Quantized」格式適合在像Raspberry Pi的單板電腦操作則有最佳效能;「Edge TPU」格式則僅限於Google Coral 的系列產品,如: Google Coral USB Accelerator 或 Google Coral Dev Board 的產品上。
燒錄完成後可將SD卡插至RPi4 卡槽後,但先別急著開機,而是先將RPi4連結到螢幕再開機,否則開機後再接螢幕是沒有畫面的,最後在接上鍵盤、滑鼠即可,這樣較好設定網路。將網路和地區都設定好之後,請開啟RPi4圖示à「Preferences」à「Raspberry Pi configuration」à「Interfaces」,將所有功能開啟後重新開機,以便可用遠端軟體控制RPi4。
本次的專案主要是針對工廠無塵室對於空氣灰塵顆粒數量的偵測進行一個監控介面設計與製作,適用於對於環境潔淨度要求甚高的場域,透過本專案的製作可以精細的對於環境中的灰塵顆粒數量進行監測與後續的清潔作業,由於工廠無塵室對於空氣中灰塵的數量有著嚴格的要求,因此,在本專案將會採用OMRON製造的ZN-PD SN300空氣灰塵顆粒偵測器當成本專案的感測裝置,本專案將透過Arduino Mega 2560進行整個控制核心的設計與製作,人機操作介面將透過觸控螢幕進行設計,希望透過簡單直覺的觸控手感進行操控。此外,為了適應實際的工廠操作的環境需求,還要透過空氣靜電消除器進行除靜電噴氣的動作,因此還需要透過輸出介面控制繼電器與空氣電磁閥,這個完整系統的建置,經過實測的確可以滿足無塵室的控制所需。
一、系統架構
系統整體的架構,是一個具有反饋(Feedback)控制流程的控制系統,系統主要是以OMRON的灰塵顆粒偵測器來負責灰塵顆粒的收集與計量,灰塵顆粒偵測器會以TCP/IP有線網路的方式將相關灰塵顆粒數量資料傳出,將資料轉換成為UART進行後續的資料應用,以Arduino Mega 2560作為控制核心透過4吋的觸控螢幕進行人機介面的操作,系統必須能操作空氣電磁閥進行除靜電的噴氣,這部分為了能適應工廠操作環境普遍採用直流24V電源,因此需要透過繼電器進行控制,透過靜電消除器噴出空氣進行表面灰塵的預防性清除。
2.Arduino Mega 2560控制核心主要是接收來自空氣灰塵顆粒偵測器的訊息資料,以UART的方式進行資料的傳輸,透過UART可以較容易進行後續硬體的擴充,且目前許多微控器都也大量使用UART當成標準的傳輸溝通介面,此外,控制核心也負責人機介面的操作,在本專案當中採用的是4吋的TFT觸控螢幕,採用觸控螢幕主要是為了能夠方面使用者能快速直覺的操作系統,並且可以省去各種操作開關的配接線,也方便之後各種軟硬體操作功能的擴充。
本專案在設計之初採用透過各種目前常用的介面控制電路模組進行設計與製作,可以有效快速完成原型的製作,而程式的運作採用C語言進行設計,電路的電源來自DC-DC直流電源進行供電,無塵室當中的生產機具有甚多是採用24V的供電,因此必須透過降壓穩壓的電路模組將電源穩定在Arduino Mega 2560可運作的直流電源電壓範圍,此外,為了能夠達成主電源一鍵開關整體系統的設計目的,因此連同OMRON的ZN-PD SN300灰塵顆粒偵測器的電源、電磁閥電源、噴氣式靜電消除器都必須共用電源,因此必須採用較高額定輸出電流的電源供應模組,以期讓整體電路的電源都能穩定維持系統運作。
此外,OMROM的灰塵顆粒偵測器與Arduino Mega 2560控制核心均能保持同步運作,控制核心可以透過4吋觸控螢幕進行各種顆粒大小的上限值的設定,只要透過觸控的方式就可以輕易設定系統的運作,相關設定值亦可以透過控制核心進行電源離線紀錄,如此便可以防止因為發生電源斷電重啟後還要進行冗長的設定程序,加速整體系統運作的流暢程度。