あなたの表情を訓練アプリを開発:顔API.ネクスト.タイプスクリプト


おい、人々.
私はあなたの表情を訓練アプリを開発した.
あなたが家で一人でいるときあなたの表現を失うか?
負けた LOL

だから私はそれについての危機感を感じたので、私はあなたの表情を訓練することができますアプリを作った.
今やってみましょう.
デモ:https://face-expression-challenge.vercel.app/
ギタブ:https://github.com/yuikoito/face-expression-challenge
私はこの時点で最小限の機能を追加したので、コードの内容は将来的に劇的に変化する可能性があります.

関数
関数は簡単です.
ときにスタートボタンを押すと、カウントダウンを起動し、質問が表示されます.
被験者は、ランダムに与えられ、件名を示した後、判断は1.5秒を開始します.そして、その時の表情に基づいて判断する.
判定する式は、以下の7つのパターンである

フェイスAPIの紹介方法を省略します.JSモデルは、上記の記事に書かれています.

対象と表情が一致するかどうかをチェックする
被験者と表情が一致するかどうかをチェックするために、被験者を引数として、ビデオ(FaceDemothAndler)の表情を認識する関数に置きました.
次に、0.1秒毎に表情を検出する.
  const faceDetectHandler = (subject: string) => {
    const video = webcamRef.current.video;
    const intervalHandler = setInterval(async () => {
      const detectionsWithExpressions = await faceapi
        .detectAllFaces(video, new faceapi.TinyFaceDetectorOptions())
        .withFaceExpressions();
      if (detectionsWithExpressions.length > 0) {
        detectionsWithExpressions.map((detectionsWithExpression) => {
          const Array = Object.entries(detectionsWithExpression.expressions);
          const scoresArray = Array.map((i) => i[1]);
          const expressionsArray = Array.map((i) => i[0]);
          const max = Math.max.apply(null, scoresArray);
          const index = scoresArray.findIndex((score) => score === max);
          const expression = expressionsArray[index];
          if (expression === subject) {
            setIsMatch(true);
          }
        });
      }
    }, 100);
    setIntervalHandler(intervalHandler);
  };
そして、式と件名が一致する場合、フラグをtrueに設定します.
しかし、それがtrueにセットされるならば、ismatchは常に真実であるので、faceDemothAndlerを呼ぶとき、私はそれをfalseにそれをリセットしました.
呼び出し元の部分は次のようになります.
  const drawSubject = (expression: string) => {
    // Count how many times to have drawn the subject in order to stop the process when the game count reaches 5 times.
    setGameCount((gameCount) => gameCount + 1);
    // Reset to false
    setIsMatch(false);
    faceDetectHandler(expression);
    const canvas = canvasRef.current;
    // Import subject image and show it
    const ctx = canvas.getContext("2d");
    const image = document.createElement("img");
    image.onload = () => {
      coverCanvas(ctx, canvas);
      ctx.drawImage(
        image,
        (canvas.width - 300) / 2,
        (canvas.height - 300) / 2,
        300,
        300
      );
    };
    image.src = `/emojis/${expression}.png`;
    // If the faceDetectHandler already moved before, the last interval should be stopped.
    if (intervalHandler) {
      clearInterval(intervalHandler);
    }
    // Do clearRect 1.5s after showing the subject.
    setTimeout(() => {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
    }, 1500);
    // Then, judge 1.5s after it
    setTimeout(() => {
      setStage("judge");
    }, 3000);
  };
ゲームの開始の流れは、被験者を提出し、裁判官を作り、ゲームを終了すると、状態管理は段階的に乱雑に管理されます.
  const [stage, setStage] = useState<
    "isNotStart" | "ready" | "start" | "judge" | "finish"
  >("isNotStart");
  useEffect(() => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext("2d");
    if (stage === "judge") {
      judge(ctx, canvas);
    }
    if (stage === "start") {
      const expression =
        ExpressionTypes[Math.floor(Math.random() * ExpressionTypes.length)];
      drawSubject(expression);
    }
    if (stage === "finish") {
      setTimeout(() => {
        coverCanvas(ctx, canvas);
        drawText(ctx, canvas, `${point}/5`);
      }, 1500);
    }
  }, [stage]);

次の機能は、今後開発する
私が公式リリースの前に修正する予定です.
まず、被験者が与えられた直後に表情認識が実行されるので、UIに関しては被写体(1.5秒)→判断開始(1.5秒)が行われるが、実際には、被験者が与えられると判断が開始されるので、3秒以内にその表情を出すべきである.それはよくない.
また、表情の判断はかなり緩い.
式を判断する方法は、以下のように、式の中で最も高いスコアに基づいているからである.
          const Array = Object.entries(detectionsWithExpression.expressions);
          const scoresArray = Array.map((i) => i[1]);
          const expressionsArray = Array.map((i) => i[0]);
          const max = Math.max.apply(null, scoresArray);
          const index = scoresArray.findIndex((score) => score === max);
顔APIで.JSは、以下に示すように、すべての式のスコアを得ることができますし、最高得点(この場合は中立)が1に近い場合は、以下の例のように、それは素晴らしいですが、すべてのスコアが0.1と0.2の間にある場合、私はそれがその式であると仮定するにはあまりにも雑多なと思います.
{
  angry: 0.00012402892753016204
  disgusted: 0.00000494607138534775
  fearful: 2.4963259193100384e-7
  happy: 0.00011926032311748713
  neutral: 0.9996343851089478
  sad: 0.00010264792217640206
  surprised: 0.000014418363207369111
}
したがって、私は推定式が0.5以下であると言う規則を加えることを考えています.
また、最終的な判断で共有機能、ダイナミックOBP、および何らかのメッセージを追加する予定です.
来週発売予定ですので、リリース後にプレイしてください!

それだ!
この記事は毎週少なくとも1つの記事を書きたいという16週目です.
あなたが望むならば、私の前の毎週のポストを見てください!
すぐにお会いしましょう!
🍎🍎🍎🍎🍎🍎
必要ならメッセージを送ってください.
[email protected]
🍎🍎🍎🍎🍎🍎