Google Teachable Machine https://teachablemachine.withgoogle.com/
Use Arduino IDE
p5.js Code https://editor.p5js.org/yining/sketches/eHYnYa5BR
P5 App https://github.com/p5-serial/p5.serialcontrol/releases
Image Recognization
Google Teachable machine
觀察測試,用左右手都測試
發現左手效果不好,就補拍照片
影響因素:不同背景、不同燈光都會影響辨識度
匯出:先點 Export Model -> Download My Model
複製連結,然後按ESC
三條線 -> Save project to Drive
下次使用的時候需要再重新訓練
燒錄Arduino IDE
紅綠藍黃(2,3,4,5)
修改第一行跟第五行
第一行const myImageModelURL = '改成你的';
第五行let portName = 'COM5';// fill in your serial port name here
然後按play做測試
click "Export Model",Download my model
Don't close teachable machine
have to Modifiy p5.js
const myImageModelURL = '修改成自己的';
let myImageModel;
let resultDiv;
let serial;// variable to hold an instance of the serialport library
let portName = '修改成自己的';// fill in your serial port name here
let outByte = 0;// for outgoing data
let video;
function preload() {
video = createCapture(VIDEO);
myImageModel = ml5.imageClassifier(myImageModelURL+ 'model.json');
}
function setup() {
resultDiv = createElement('h1', '...');
serial = new p5.SerialPort(); // make a new instance of the serialport library
serial.on('error', serialError); // callback for errors
serial.open(portName); // open a serial port
myImageModel.classify(video, gotResults);
}
function serialError(err) {
console.log('Something went wrong with the serial port. ' + err);
}
function gotResults(err, results) {
if (err) console.log(err);
if (results) {
console.log(results);
// Wait for 0.5 second before classifying again
setTimeout(() => myImageModel.classify(video, gotResults), 500);
if (results[0].confidence < 0.7) return;
resultDiv.html('Result is: ' + results[0].label);
console.log(results[0].label);
if (results[0].label === 'paper') {
outByte = 1;
} else if (results[0].label === 'rock') {
outByte = 2;
} else if (results[0].label === 'sicssors') {
outByte = 3;
} else if (results[0].label === 'other') {
outByte = 4;
} else {
outByte = 0;
}
// send it out the serial port:
console.log('outByte: ', outByte)
serial.write(outByte);
}
}
#include <Servo.h>
Servo myservo;
int servoPin = 9;
int yellowPin = 5;
int redPin = 2;
int greenPin = 3;
int bluePin = 4;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(yellowPin, OUTPUT);
myservo.attach(servoPin);
myservo.write(0); // set servo to mid-point
// start serial port at 9600 bps:
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) { // if there's serial data available
int inByte = Serial.read(); // read it
Serial.println(inByte);
if (inByte == 1) {
myservo.write(10);
// Light red LED
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, LOW);
} else if (inByte == 2) {
myservo.write(50);
// Light green LED
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, LOW);
} else if (inByte == 3) {
myservo.write(90);
// Light BLUE LED
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, HIGH);
digitalWrite(yellowPin, LOW);
} else if (inByte == 4) {
myservo.write(140);
// Light BLUE LED
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, HIGH);
}
else {
myservo.write(0);
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
digitalWrite(yellowPin, HIGH);
}
// Wait for 1 second
delay(500);
}
}
open ur computer folder C:\BlocklyduinoF2\arduino-1.8.19
double click arduino.exe
paste my code, then follow my step
Open "P5 SERIAL CONTROL"
click 'open'
rock greenPin=3
paper resPin=2
sicssors bluePin=4
other yellowPin=5
// https://teachablemachine.withgoogle.com/models/hFUsMix1m/
const mySoundModelURL = '修改成自己的';
let mySoundModel;
let resultDiv;
let serial;// variable to hold an instance of the serialport library
let portName = '修改成自己的';// fill in your serial port name here
let outByte = 0;// for.usbming data
function preload() {
mySoundModel = ml5.soundClassifier(mySoundModelURL+ 'model.json');
}
function setup() {
resultDiv = createElement('h1', '...');
serial = new p5.SerialPort(); // make a new instance of the serialport library
serial.on('error', serialError); // callback for errors
serial.open(portName); // open a serial port
mySoundModel.classify(gotResults);
}
function serialError(err) {
console.log('Something went wrong with the serial port. ' + err);
}
function gotResults(err, results) {
if (err) console.log(err);
if (results) {
// console.log(results);
if (results[0].confidence < 0.7) return;
resultDiv.html('Result is: ' + results[0].label);
if (results[0].label === 'RED') {
outByte = 1;
} else if (results[0].label === 'GREEN') {
outByte = 2;
} else if (results[0].label === 'BLUE') {
outByte = 3;
} else if (results[0].label === 'YELLOW') {
outByte = 4;
} else {
outByte = 0;
}
// send it out the serial port:
// console.log('outByte: ', outByte)
serial.write(outByte);
}
}
//int servoPin = 9;
int yellowPin = 5;
int redPin = 2;
int greenPin = 3;
int bluePin = 4;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(yellowPin, OUTPUT);
Serial.begin(9600); // initialize serial communications
}
void loop() {
if (Serial.available() > 0) { // if there's serial data available
int inByte = Serial.read(); // read it
if (inByte == 1) {
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, LOW);
} else if (inByte == 2) {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, LOW);
} else if (inByte == 3) {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, HIGH);
digitalWrite(yellowPin, LOW);
} else if (inByte == 4) {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, HIGH);
}
else {
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
digitalWrite(yellowPin, HIGH);
}
delay(100); // waits
}
}
// Update this following link to your own model link
const poseModelUrl = '修改成自己的';
let serial;// variable to hold an instance of the serialport library
let portName = '修改成自己的';// fill in your serial port name here
// the json file (model topology) has a reference to the bin file (model weights)
const checkpointURL = poseModelUrl + "model.json";
// the metatadata json file contains the text labels of your model and additional information
const metadataURL = poseModelUrl + "metadata.json";
const size = 300;
let webcam;
let model;
let totalClasses;
let myCanvas;
let ctx;
let outByte = 0;// for outgoing data
// A function that loads the model from the checkpoint
async function load() {
model = await tmPose.load(checkpointURL, metadataURL);
totalClasses = model.getTotalClasses();
console.log("Number of classes, ", totalClasses);
}
async function loadWebcam() {
webcam = new tmPose.Webcam(size, size, true); // can change width and height
await webcam.setup(); // request access to the webcam
await webcam.play();
}
async function setup() {
serial = new p5.SerialPort(); // make a new instance of the serialport library
serial.on('error', serialError); // callback for errors
serial.open(portName); // open a serial port
myCanvas = createCanvas(size, size);
ctx = myCanvas.elt.getContext("2d");
// Call the load function, wait until it finishes loading
await load();
await loadWebcam();
predictVideo(webcam.canvas);
}
function serialError(err) {
console.log('Something went wrong with the serial port. ' + err);
}
async function predictVideo() {
webcam.update();
// Prediction #1: run input through posenet
// predictPosenet can take in an image, video or canvas html element
const flipHorizontal = false;
const { pose, posenetOutput } = await model.estimatePose(webcam.canvas);
// Prediction 2: run input through teachable machine assification model
const prediction = await model.predict(posenetOutput);
console.log('prediction', prediction);
// Find the class with the highest probability
const maxClass = prediction.reduce((prev, current) => (prev.probability > current.probability) ? prev : current)
// Show the result
const res = select('#res'); // select <span id="res">
res.html(maxClass.className);
// Show the probability
const prob = select('#prob'); // select <span id="prob">
prob.html(maxClass.probability.toFixed(2));
// draw the keypoints and skeleton
if (pose) {
const minPartConfidence = 0.5;
ctx.drawImage(webcam.canvas, 0, 0);
tmPose.drawKeypoints(pose.keypoints, minPartConfidence, ctx);
tmPose.drawSkeleton(pose.keypoints, minPartConfidence, ctx);
}
if (maxClass.className === 'left tilt') {
outByte = 1;
} else if (maxClass.className === 'no tilt') {
outByte = 2;
} else if (maxClass.className === 'right tilt') {
outByte = 3;
} else {
outByte = 0;
}
// send it out the serial port:
console.log('outByte: ', outByte)
serial.write(outByte);
// Wait for 0.2 second before classifying again
setTimeout(() => predictVideo(), 200);
}
int yellowPin = 5;
int redPin = 2;
int greenPin = 3;
int bluePin = 4;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(yellowPin, OUTPUT);
Serial.begin(9600); // initialize serial communications
}
void loop() {
if (Serial.available() > 0) { // if there's serial data available
int inByte = Serial.read(); // read it
if (inByte == 1) {
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, LOW);
} else if (inByte == 2) {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, LOW);
digitalWrite(yellowPin, LOW);
} else if (inByte == 3) {
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
digitalWrite(bluePin, HIGH);
digitalWrite(yellowPin, LOW);
} else {
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, HIGH);
digitalWrite(bluePin, HIGH);
digitalWrite(yellowPin, HIGH);
}
delay(300); // waits
}
}