[face-api] Uncaught (in promise) SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON"

Infinity-blue·2023년 11월 19일
0

Problem

React에서 face-api.js의 얼굴탐지 코드를 불러올 시 제목과 같은 에러가 뜬다.
에러를 일으키는 코드는 다음과 같다.

  //Load Face-detection models from './public/models.'
   const MODEL_URL = process.env.PUBLIC_URL + '/models';

      Promise.all([
        faceapi.nets.tinyFaceDetector.loadFromUri(MODEL_URL),
        faceapi.nets.faceLandmark68Net.loadFromUri(MODEL_URL),
        faceapi.nets.faceRecognitionNet.loadFromUri(MODEL_URL),
        faceapi.nets.faceExpressionNet.loadFromUri(MODEL_URL),
      ]).then(setModelsLoaded(true));
    }

Solution

위와같이 깃헙에서 face-api를 다운로드 받지말고 face-api 깃헙 url를 아래와 같이 직접 입력한다.

github의 '.json'파일의 내용을 URI로 불러올 시 링크의 수정이 필요하다.

e.g.

github.com/..../face-api.js/blob/master/weights/..json

위의 URI를 다음과 같이 수정한다. 하단의 솔루션 코드 참고.

githubusercontent.com/..../face-api.js/master/weights/..json
const detectionOptions = {
    withLandmarks: true,
    withDescriptors: true,
    minConfidence: 0.5,
    MODEL_URLS: {
      Mobilenetv1Model:
        "https://raw.githubusercontent.com/ml5js/ml5-data-and-models/main/models/faceapi/ssd_mobilenetv1_model-weights_manifest.json",
      FaceExpressionModel:
        "https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights/face_expression_model-weights_manifest.json",
      TinyFaceLandmarkModel:
        // "https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights/face_landmark_68_model-weights_manifest.json",
        "https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights/tiny_face_detector_model-weights_manifest.json",
      FaceLandmark68TinyNet:
        "https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights/face_landmark_68_model-weights_manifest.json",
      FaceRecognitionModel:
        "https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights/face_recognition_model-weights_manifest.json",
    },
  };

  useEffect(() => {
    const loadModels = async () => {
      try {
        await Promise.all([
          faceapi.nets.ssdMobilenetv1.loadFromUri(detectionOptions.MODEL_URLS.Mobilenetv1Model),
          faceapi.nets.tinyFaceDetector.loadFromUri(
            detectionOptions.MODEL_URLS.TinyFaceLandmarkModel
          ),
          faceapi.nets.faceLandmark68Net.loadFromUri(
            detectionOptions.MODEL_URLS.FaceLandmark68TinyNet
          ),
          faceapi.nets.faceRecognitionNet.loadFromUri(
            detectionOptions.MODEL_URLS.FaceRecognitionModel
          ),
          faceapi.nets.faceExpressionNet.loadFromUri(
            detectionOptions.MODEL_URLS.FaceExpressionModel
          ),
        ]);

만약 상단처럼 코드를 수정했음에도 같은 오류가 뜨는 경우가 있다. 한번에 여러개의 모델을 불러올 시 리소스 로드에 과부하가 걸려서 그런 듯 싶다. 이럴 땐 promise.all 대신 하단처럼 모델을 각각 불러오면 해결된다.

    // 'prommise.all' often makes loading stucked due to heavy resource load. try to load models one by one.
    await faceapi.nets.tinyFaceDetector.loadFromUri(
      detectionOptions.MODEL_URLS.TinyFaceLandmarkModel
    );
    // extracting data like face position, shape, and texture.
    await faceapi.nets.faceLandmark68Net.loadFromUri(
      detectionOptions.MODEL_URLS.FaceLandmark68TinyNet
    );
    // comparing facial features with existing data from the database.
    await faceapi.nets.faceRecognitionNet.loadFromUri(
      detectionOptions.MODEL_URLS.FaceRecognitionModel
    );
    await faceapi.nets.faceExpressionNet.loadFromUri(
      detectionOptions.MODEL_URLS.FaceExpressionModel
    );



References

face-api.js
How to load face-api.js
How to use face-api.js

0개의 댓글