📱테스트 환경
"react": "18.2.0"
"react-dom": "18.2.0"
"typescript": "^5.1.6"
요즘 또 남들이 핫하다는 티처블 머신을 이용해서 개발해보고싶었다.
먼저 필요한 걸 설치해줬다.
npm install @tensorflow/tfjs @tensorflow-models/mobilenet @tensorflow-models/knn-classifier
코드 자체는 공식 홈페이지에 가도 설명이 너무 잘 돼어있어서 딱히 설명이 필요할 것 같진 않다.
import { useEffect, useRef } from 'react';
import * as tf from '@tensorflow/tfjs';
import * as tmImage from '@teachablemachine/image';
const TeachableMachinePage = () => {
const videoRef = useRef();
const classifierRef = useRef();
useEffect(() => {
async function loadModel() {
const URL = '/path/to/your/model/'; // Teachable Machine에서 내보낸 모델의 경로
const modelURL = URL + 'model.json';
const metadataURL = URL + 'metadata.json';
const model = await tf.loadLayersModel(modelURL);
const metadata = await (await fetch(metadataURL)).json();
classifierRef.current = await tmImage.create(
model,
metadata
);
startWebcam();
}
function startWebcam() {
navigator.mediaDevices.getUserMedia({ video: true })
.then((stream) => {
videoRef.current.srcObject = stream;
detect();
})
.catch((err) => console.error('Error accessing webcam: ', err));
}
async function detect() {
if (classifierRef.current) {
const prediction = await classifierRef.current.predict(videoRef.current);
console.log(prediction);
// 여기에서 예측 결과를 사용하여 필요한 동작을 수행합니다.
}
requestAnimationFrame(detect);
}
loadModel();
}, []);
return (
<div>
<video
ref={videoRef}
autoPlay
playsInline
muted
style={{ maxWidth: '100%' }}
/>
</div>
);
};
export default TeachableMachinePage;
근데 학습데이터가 적으니 데이터도 정말 개판이였고, 화면 각도에 따라서도 데이터가 수시로 변하는지라,
그냥 이미지를 업로드해서 테스트 해보는 방식으로 나는 진행하였다.
- tmImage 모듈은 Teachable Machine과 관련된 이미지 분류에 사용
- onImageChange 함수는 이미지 선택 시 실행됨. 선택한 파일을 상태에 저장하고 파일 URL을 생성
- classifyImage 함수는 이미지 분류를 함. classifier 객체의 classify 함수를 사용
- gotResults 함수는 분류 결과를 처리하고 다음 웹캠 이미지에 대해 분류를 실행
- predict 함수는 Teachable Machine 모델을 로드하고 이미지 예측을 실행
import { useEffect, useRef, useState } from "react";
import { Col } from "@nextui-org/react";
import * as tmImage from "@teachablemachine/image";
import { Body, Button, CameraBox, Title } from "@/styles/commonStyle";
import { useRouter } from "next/router";
let classifier: {
classify: (
arg0: File | null,
arg1: (error: any, results: { label: any }[]) => Promise<void>
) => void;
};
const TeachableMachinePage = () => {
const [fileURL, setFileURL] = useState<string>("");
const [file, setFile] = useState<any>();
const [label, setLabel] = useState<String>();
const [results, setResults] = useState<
{ className: string; probability: number }[] | undefined
>();
const imgUploadInput = useRef<HTMLInputElement | null>(null);
const router = useRouter();
const onImageChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.files) {
setFile(event.target.files);
if (event.target.files[0] !== undefined) {
const newFileURL = URL.createObjectURL(event.target.files[0]);
setFileURL(newFileURL);
}
}
};
const classifyImage = () => {
try {
// Check if file is not null before calling classifier.classify
if (file) {
classifier.classify(file, gotResults);
}
} catch (err) {
console.log(err);
}
};
const gotResults = async (error: any, results: { label: any }[]) => {
setLabel(results[0].label); //Predicted label with highest confidence
classifyImage(); // Run on next webcam image
};
async function predict() {
const URL = "https://teachablemachine.withgoogle.com/path/to/your/model/";
const modelURL = URL + "model.json";
const metadataURL = URL + "metadata.json";
let model;
// predict can take in an image, video or canvas html element
model = await tmImage.load(modelURL, metadataURL);
const imageElement = new Image();
imageElement.src = fileURL;
const tempImage = document.getElementById("srcImg");
const prediction = await model.predict(imageElement, false);
prediction.sort((a, b) => b.probability - a.probability);
setResults(prediction);
}
return (
<>
<Body>
<Col
onClick={(event) => {
if (fileURL === "") {
event.preventDefault();
if (imgUploadInput.current) {
imgUploadInput.current.click();
}
}
}}
>
<CameraBox>
<img width="256px" height="256px" src={fileURL} />
</CameraBox>
</Col>
</Body>
<input
style={{ display: "none" }}
type="file"
id="img"
accept="image/*"
required
ref={imgUploadInput}
onChange={onImageChange}
/>
</>
);
};
export default TeachableMachinePage;
'Javascript > Next' 카테고리의 다른 글
[NextJS] NextJS 모바일 시스템공유 하는방법 (0) | 2023.08.17 |
---|---|
[NextJS] 이미지 다운로드 하는 방법 (0) | 2023.08.17 |
[NextJS] SSR 방식이 뜨는 이유, 그중 NextJS (0) | 2023.08.17 |
[NextJS] Syled-components props 전달 하는 방법 (0) | 2023.08.16 |
[NextJS] NextJS Typescript 프로젝트 생성 (0) | 2023.08.14 |