개요

Tensorflow-models에 속해 있는 모델들의 전형적인 사용 구조를 설명하려고 함. 미래의 나를 위해... 이하 모든 글과 코드는 근본적으로 Tensorflow-models 공식 깃헙에 출처가 있음.

 


 

1. model loading : createDetector

_createDetector() {
  const model = SupportedModels.MediaPipeHands;
  const detector = createDetector(model, {
      runtime: "tfjs",
      modelType: "lite",
      maxHands: 2, // or 2~10.
      flipHorizontal: false,
      staticImageMode: false,
      detectorModelUrl:
          "/static/tensorflow-models/tfjs-model_handpose_3d_detector_lite_1/model.json",
      landmarkModelUrl:
          "/static/tensorflow-models/tfjs-model_handpose_3d_landmark_lite_1/model.json",
  });

  console.log("model loading success!, detector: ", this._detector);
  return detector;
}

 


 

2. detect

  • detector.estimateHands(video or image)
  • estimateFaces 등 다양한 시리즈 있음
detect(imageData) {
  if (!this._detector) {
      this._createDetector().then(detector => {
          this._detector = detector;
          console.log("model loading success!, detector: ", this._detector);
      })
  }

  return new Promise((resolve, reject) => {   
      this._detector.estimateHands(imageData).then(result => {
          this._result = result;
          console.log(`this._result: `, this._result);

          this._result.forEach((res) => {
              console.log(`${res.handedness} hand keypoints:`);
              res.keypoints.forEach((keypoint, i) => {
                  let x = keypoint.x - 320;
                  let y = keypoint.y - 240;
                  console.log(`Keypoint ${i}: [${x}, ${y}]`);
              })
          })
          resolve(this._result);
      }).catch(e => {
          reject(e);
      });
  })
}

 


 

3. draw : draw(canvas) 등 매개 변수는 다양할 수 있음

  • drawKeypoint
  • drawPath
draw(canvas) {
    if (!canvas || !this.isExistContent(this._result)) return canvas;
    const ctx = canvas.getContext("2d");
    if (this._result) {
        this._result.forEach( (res) => {
            ctx.fillStyle = res.handedness === "Left" ? "Red" : "Blue";
            ctx.strokeStyle = "White";
            ctx.lineWidth = 2;
            res.keypoints.forEach(keypoint => {
                this._drawKeypoint(ctx, keypoint);
            });
            Object.keys(FINGER_INDICES).forEach(finger => {
                const points = FINGER_INDICES[finger].map(idx => res.keypoints[idx]);
                this._drawPath(ctx, points, false);
            });
        });
    }
    return canvas;
}

_drawKeypoint(ctx, keypoint) {
    ctx.beginPath();
    ctx.arc(keypoint.x - 2, keypoint.y - 2, 3, 0, 2 * Math.PI);
    ctx.fill();
}

_drawPath(ctx, points, closePath) {
    const region = new Path2D();
    region.moveTo(points[0].x, points[0].y);
    points.slice(1).forEach(point => region.lineTo(point.x, point.y));
    if (closePath) {
        region.closePath();
    }
    ctx.stroke(region);
}

 

 

+ Recent posts