📸

【React+TensorFlow.js】写真分類器つくってみた

2023/11/18に公開

はじめに

Webカメラで撮影を行い、写真を分類器にかける簡易アプリを作成してみた

動機

Webアプリで画像認識をすることができたら、作れるものの幅が広がりそうだな~

できたもの

リポジトリ

https://github.com/itojun-1230/classification_react

GitHub Page

⚠初期状態がインカメになってます
https://itojun-1230.github.io/classification_react/

参考にしたもの

https://codelabs.developers.google.com/codelabs/tensorflowjs-teachablemachine-codelab?hl=ja#0
https://www.tensorflow.org/js/guide/platform_environment?hl=ja
https://blog.usize-tech.com/take-photo-by-react-app/

技術

My Skills

ライブラリ

yarn add @tensorflow-models/mobilenet
yarn add @tensorflow/tfjs
yarn add react-webcam

開発環境

  • VScode
  • Windows

ソースコード

全体像はリポジトリを見てもらうとして、主要なところを抜粋

画像分類モデル読み込み

モデル読み込みはそこそこ時間がかかるので、useEffectを使って初期実行時のみ呼び出す。

App.tsx
useEffect(() => {
  if (tf.getBackend()) { //すでにバックエンドが定義されている場合、return
    return;
  }
  const initLoad = async () => {
    tf.setBackend("cpu"); //バックエンドをcpuに定義

    console.log("Loading mobilenet...");
    const MobileNet: mobilenet.MobileNet = await mobilenet.load(); //モデル読み込み
    setNet(MobileNet);  //モデルをStateに保存
    console.log("Successfully loaded model");
  };
  initLoad();
}, []);

WebCam

Webカメラを使って撮影する。
写真を分類処理を実行する関数である、props.Classificationに渡す。

WebCam.tsx
<Webcam
  ref={webcamRef}
  audio={false}
  width={200}
  height={200}
  screenshotFormat="image/jpeg"
  videoConstraints={{
    width: 200,
    height: 200,
    facingMode
  }}
/>
<button onClick={capture}>撮影</button>
WebCam.tsx
const capture = () => {
  //撮影
  const ImageSrc = webcamRef.current!.getScreenshot();
  if (ImageSrc) {
    props.setImgSrc(ImageSrc);
    props.Classification(ImageSrc);
  }
}

分類処理実行

WebCamから渡された写真を分類してresultに格納する。

App.tsx
const Classification = (src: string) => {
  //img要素を作成し、src属性にsrcを代入
  let imageElem = document.createElement('img');

  imageElem.onload = async () => {
    //分類実行
    setResult(await net!.classify(imageElem));
  }
  imageElem.src = src;
}

まとめ

ひとまず動くものができたのと、ある程度動きを理解しながら作れたと自負しているのでヨシ!

今回は学習済みモデルのMobileNetを用いて分類したけど、次は自分で学習モデルを作ってみたい
こちらで作って用意できたら、面白い遊びができそうだな~って思ってます

Discussion