Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: "TypeError: t is not a function" - when using customModel.estimatePose() in NextJs. #399

Open
Garreta11 opened this issue Oct 8, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@Garreta11
Copy link

Describe the bug
Hi, I would like to use teachablemachine in a NextJS project. I have created a custom model and import it to the code. It seems it is correct, because I can console.log it.

async function init() {
      try {
        const loadedModel = await tmPose.load(modelURL, metadataURL);
        modelRef.current = loadedModel;
        console.log(modelRef.current);
        const maxPred = loadedModel.getTotalClasses();
        setMaxPredictions(maxPred);

        requestAnimationFrame(loop);

        // append/get elements to the DOM
        if (!canvasRef.current) return
        const canvas = canvasRef.current as HTMLCanvasElement;
        canvas.width = webcamRef.current?.video?.videoWidth || 0;
        canvas.height = webcamRef.current?.video?.videoHeight || 0;
        ctxRef.current = canvas.getContext("2d") as CanvasRenderingContext2D;
        labelContainerRef.current = document.getElementById("label-container") as HTMLDivElement;
        for (let i = 0; i < maxPred; i++) { // and class labels
          labelContainerRef.current.appendChild(document.createElement("div"));
        }

      } catch (error) {
        console.error('Error loading model:', error);
      }
    }

The problem I have is when I want to estimatePose and I'm getting the following error:
Captura de pantalla 2024-10-08 134415

This is my component code:

import { useEffect, useState, useRef } from 'react';
import styles from './ModelWrapper.module.scss'
import Webcam from "react-webcam";
import * as tmPose from "@teachablemachine/pose";

const ModelWrapper = () => {

  // URL for the model and metadata
  const modelURL = '/models/model.json'; 
  const metadataURL = '/models/metadata.json';

  // useRefs
  const webcamRef = useRef<Webcam | null>(null);
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
  const modelRef = useRef<tmPose.CustomPoseNet | null>(null);
  const labelContainerRef = useRef<HTMLDivElement | null>(null);
  const ctxRef = useRef<CanvasRenderingContext2D | null>(null);

  // useStates
  const [maxPredictions, setMaxPredictions] = useState<number>(0);

  const videoConstraints = {
    facingMode: "user", // you can also set it to "environment" for back camera on mobile devices
  };

  useEffect(() => {
    async function init() {
      try {
        const loadedModel = await tmPose.load(modelURL, metadataURL);
        modelRef.current = loadedModel;
        const maxPred = loadedModel.getTotalClasses();
        setMaxPredictions(maxPred);

        requestAnimationFrame(loop);

        // append/get elements to the DOM
        if (!canvasRef.current) return
        const canvas = canvasRef.current as HTMLCanvasElement;
        canvas.width = webcamRef.current?.video?.videoWidth || 0;
        canvas.height = webcamRef.current?.video?.videoHeight || 0;
        ctxRef.current = canvas.getContext("2d") as CanvasRenderingContext2D;
        labelContainerRef.current = document.getElementById("label-container") as HTMLDivElement;
        for (let i = 0; i < maxPred; i++) { // and class labels
          labelContainerRef.current.appendChild(document.createElement("div"));
        }

      } catch (error) {
        console.error('Error loading model:', error);
      }
    }

    const loop = async () => {
     await predict();
    // requestAnimationFrame(loop);
    }

    const predict = async () => {
      if (modelRef.current && webcamRef.current && canvasRef.current && modelRef.current.model) {
        // Prediction #1: run input through posenet
        // estimatePose can take in an image, video or canvas html element
        const video = webcamRef.current.video as HTMLVideoElement;
        console.log(modelRef.current.model)
        const { pose } = await modelRef.current.estimatePose(video, false);
        drawCanvas(canvasRef.current, video);
        //console.log(pose)
      } else {
        console.error('modelRef.current or estimatePose is undefined');
      }
    }

    const drawCanvas = (canvas: HTMLCanvasElement, video: HTMLVideoElement) => {
      if (!canvas) return
      if (webcamRef.current) {
        ctxRef.current = canvas.getContext("2d") as CanvasRenderingContext2D;
        ctxRef.current.clearRect(0, 0, canvas.width, canvas.height);
        ctxRef.current.drawImage(video, 0, 0);
      }
    }

    init();
  }, []);
  

  return (
    <div className={styles.model}>
      <Webcam
          ref={webcamRef}
          className={styles.model__webcam}
          height='100%'
          width='100%'
          videoConstraints={videoConstraints}
        />
      <canvas ref={canvasRef} className={styles.model__canvas} />
      <div id="label-container"></div>
    </div>
  )
}

export default ModelWrapper;

Any idea?
Thanks

@Garreta11 Garreta11 added the bug Something isn't working label Oct 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant