티처블머신( Teachable Machine)은 누구나 머신러닝 모델을 쉽고 빠르고 간단하게 만들 수 있도록 제작된 웹 기반 도구입니다.
https://teachablemachine.withgoogle.com/
오늘은 티처블머신을 활용하여 아두이노와 연동하는 방법에 대해 학습하겠습니다.
1) 티처블머신을 이용하여 모델링하기
여기에서 '이미지 프로젝트'를 선택합니다.
표준 이미지모델을 선택합니다.
- 클래스 이름을 변경하고 2개이상일 경우 클래스 추가를 눌러 생성합니다.,
- 클래스를 4개 만들었습니다.
- 웹캠 버튼을 눌러 카메라를 허용한 다음 길러 눌러 녹화하기를 계속 누르면서 데이터를 추가합니다.
- 4개의 클래스에 각각 데이터를 추가합니다.
- 모델학습시키기
- 결과 확인
- 모델 내보내기 한 후 모델 업로드를 누릅니다.
- 여기서 공유가능한 링크를 사용할 것입니다. 링크를 복사해서 메모장에 붙여넣기 합니다.
https://teachablemachine.withgoogle.com/models/dq7O8CBLc/
2) 아두이노 연결
- 서보모터 : GND, VCC, 9번핀
- I2C LCD : GND, VCC, A4, A5
- 아두이노 소스코드를 업로드하고 포트번호를 기억해 둡니다.
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16, 2); //lcd주고 확인 후 수정 가능
Servo servo;
int servopin=9;
int angle=0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
servo.attach(servopin);
lcd.init(); // LCD초기 설정
lcd.backlight(); // LCD초기 설정
lcd.setCursor(0,0);
}
void loop() {
// put your main code here, to run repeatedly:
if(Serial.available()>0){
byte actionCode=Serial.read();
lcd.clear();
switch(actionCode){
case 1:
angle=180;
lcd.print("Cell Phone");
break;
case 2:
angle=120;
lcd.print("Cup");
break;
case 3:
angle=60;
lcd.print("My Hand");
break;
case 4:
angle=0;
lcd.print("Nothing");
break;
default :
break;
}
}
servo.write(angle);
}
3) p5.js 활용하기
- 먼저 로그인을 합니다.(구글 아이디로 로그인하면 편리함)
- index.html을 열어 <head>~</head>와 사이에 아래있는 코드를 복사하여 붙여넣기 합니다.
- 웹 serial port 연결과 머신러닝 패키지 관련 코드입니다.
<script src="https://unpkg.com/p5-webserial@0.1.1/build/p5.webserial.js"></script>
<script type="text/javascript" src="https://unpkg.com/ml5@0.6.1/dist/ml5.min.js"></script>
- index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.3/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.3/addons/p5.sound.min.js"></script>
<script src="https://unpkg.com/p5-webserial@0.1.1/build/p5.webserial.js"></script>
<script type="text/javascript" src="https://unpkg.com/ml5@0.6.1/dist/ml5.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
<body>
<main>
</main>
<script src="sketch.js"></script>
</body>
</html>
- Ctrl+S 을 눌러 저장합니다.
- sketch.js
const modelURL="https://teachablemachine.withgoogle.com/models/dq7O8CBLc/"
let classifier;
let serial;
let video;
let flippedVideo;
let label;
let actionNum;
function preload(){
classifier = ml5.imageClassifier(modelURL + "model.json");
}
let port = new p5.WebSerial();
function setup() {
port.getPorts(); // 포트 사용 가능 확인
port.on('noport', makePortButton); // 기존 선택한 포트가 없으면 makePortButton() 호출
port.on('portavailable', openPort); // 사용 가능한 포트가 있으면 openPort() 자동 호출
createCanvas(320, 260);
video=createCapture(VIDEO);
video.size(320,240);
video.hide();
// flippedVideo = ml5.flipImage(video);
classifyVideo();
}
function draw() {
background(0);
// image(flippedVideo, 0, 0);
image(video, 0, 0);
fill(255);
textSize(16);
textAlign(CENTER);
text(label, width / 2, height - 4);
}
function makePortButton() { // 포트 첫 연결 시 포트 선택 버튼 생성
let portButton = createButton('포트 선택'); // 버튼 생성
portButton.mousePressed(choosePort); // 버튼 누르면 choosePort() 자동 호출
function choosePort() { // 콜백함수
port.requestPort(); // 시리얼 포트 선택창 오픈
}
}
function openPort() { // 콜백함수
port.open().then(initiateSerial); // 포트를 오픈 후 initiateSerial() 자동 호출
function initiateSerial() { // 콜백함수
console.log('포트 오픈');
}
}
function classifyVideo(){
flippedVideo = ml5.flipImage(video);
classifier.classify(flippedVideo, gotResult);
flippedVideo.remove();
}
function gotResult(error, results){
if (error){
console.error(error);
return;
}
label = String(results[0].label);
switch(label){
case "핸드폰" :
actionNum=1;
break;
case "컵" :
actionNum=2;
break;
case "손" :
actionNum=3;
break;
default:
actionNum=4;
break;
}
port.write(actionNum);
classifyVideo();
}
- 실행결과
'p5.js > p5.js' 카테고리의 다른 글
p5.js로 이미지 다루기 (0) | 2024.08.22 |
---|---|
p5.js 로 사운드 입출력하기 (0) | 2024.08.20 |
무료 음향효과 다운로드 사이트 (0) | 2024.08.19 |
p5.js -> 아두이노 연동하기 (0) | 2024.03.22 |
p5.js란 무엇인가? (2) | 2024.03.21 |