문제 인식

  • 일렉트론으로 구현해보았을 때는 이하 코드처럼 라이브 비디오 자체를 매개변수로 예측하였음.
const hands = await detector.estimateHands(camera.video, { flipHorizontal: false });
  • 그러나 자사 소프트웨어 기존 코드에서는 estimate 함수의 매개변수가 이미지임. 따라서 기존 방식을 따라 가야 했음

 


 

1. Tensorflow.js 공식 깃헙

  • 매개변수의 확인 → 이미지와 비디오 둘 다 가능!
  • 따라서 이미지로 estimate 함수 사용하여 일렉트론으로 구현해보고자 함
// 이미지
const result = await detector.estimateHands(image, {
  staticImageMode: true
} as handPoseDetection.MediaPipeHandsTfjsEstimationConfig);

// 비디오
const hands = await detector.estimateHands(video, null /* config */);

 


 

2. 일렉트론으로 구현 

  • 핵심 로직
    1. ctx.drawImage(video, 0, 0, canvas.width, canvas.height) 
      : 웹 캠에서 받아온 비디오 현재 프레임을 캔버스에 표시
    2. ctx.getImageData(0, 0, canvas.width, canvas.height)
      : 캔버스의 이미지 데이터를 가져옴 (캡처)
  • 핵심 코드 
_captureImageData(video) {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  canvas.width = video.videoWidth;  
  canvas.height = video.videoHeight;
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);  
  return ctx.getImageData(0, 0, canvas.width, canvas.height);
}

// estimate 함수에 적용
const detector = createDetector(SupportedModels.MediapipeHands);
const imageData = HandposeDetector.captureImageData(video);
const result = await detector.estimateHands(imageData);

 


 

해결법 (요약)

  • GUI 프로젝트 코드에 이미 video → image 로 바꾸는 로직이 작성되어 있었음
// drawImage()
if (lastUpdate + cacheTimeout < now) {
  try {
      if (mirror) {
          context.scale(-1, 1);
          context.translate(width * -1, 0);
      }
      context.drawImage(this._element,
          // source x, y, width, height
          0, 0, elementDimension.width, elementDimension.height,
          // dest x, y, width, height
          0, 0, width, height
      );
      context.setTransform(1, 0, 0, 1, 0, 0);
      workspace.lastUpdate = now;
  } catch {
      return null;
  }
}

// getImageData()
if (formatCache.lastUpdate + cacheTimeout < now) {
	if (format === CameraProvider.FORMAT_IMAGE_DATA) {
	    formatCache.lastData = context.getImageData(0, 0, width, height);
}

 

  • 나는 이미 정해져 있는 detect 함수의 매개변수인 imageData를 가져와 처리함
detect(imageData) {
	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);
    });
	})
}

 

 

 

+ Recent posts