1. 미디어파이프(Mediapipe)를 활용한 AI Web페이지 개발하기

 

미디어파이프는 사용하기 편하게 라이브러리 형태로 모듈화되어 제공되는데 지원가능한 환경이나 언어가 매우 다양해 Andoid, iOS, C++, Python, JavaScript, Coral 등이 지원된다. 이중에서 JavaScript언어 지원기능을 사용하면 미디어파이프 AI기능이 포함된 Web 페이지를 손쉽게 개발할 수 있다. 

 

미디어파이프에서 JavaScript 방식으로 제공하는 모듈들은 다음과 같다. 

Solution NPM Package Example
Face Mesh @mediapipe/face_mesh mediapipe.dev/demo/face_mesh
Face Detection @mediapipe/face_detection mediapipe.dev/demo/face_detection
Hands @mediapipe/hands mediapipe.dev/demo/hands
Holistic @mediapipe/holistic mediapipe.dev/demo/holistic
Objectron @mediapipe/objectron mediapipe.dev/demo/objectron
Pose @mediapipe/pose mediapipe.dev/demo/pose
Selfie Segmentation @mediapipe/selfie_segmentation mediapipe.dev/demo/selfie_segmentation

 이외에 다음과 같은 추가 모듈이 제공된다. 

 

2.설치 

 

위의 모듈들은 NPM 패키지형태로 제공되는데 이를 자체 웹서버에 설치하려면 npm install명령으로 가능하다. 즉 손모양인식을 위한 hands모듈은 "npm install @mediapipe/hands."라는 명령어로 설치하면 된다. 그러나 웹서버가 인터넷환경에서 운영될 것이라면 굳이 자체 서버에 설치할 필요도 없이 구글에서 제공하는 사이트를 링크걸어 사용하면 된다. 

<head>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/drawing_utils@0.1/drawing_utils.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/holistic@0.1/holistic.js" crossorigin="anonymous"></script>
</head>

 

 

3.샘플 웹페이지 

 

-HTML 코드 

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/@mediapipe/control_utils/control_utils.js" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/@mediapipe/drawing_utils/drawing_utils.js" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/@mediapipe/hands/hands.js" crossorigin="anonymous"></script>
</head>

<body>
  <div class="container">
    <video class="input_video"></video>
    <canvas class="output_canvas" width="1280px" height="720px"></canvas>
  </div>
</body>
</html>

5~8 line : 세가지 유티리티 모듈과 손동작 인식 AI 모델기능인 hands.js를 링크하는 것 만으로 필요한 미디어파이프 기능을 모두 사용할 수 있다  

 

-CSS 

body {
  bottom: 0;
  font-family: 'Titillium Web', sans-serif;
  color: white;
  left: 0;
  margin: 0;
  position: absolute;
  right: 0;
  top: 0;
  transform-origin: 0px 0px;
  overflow: hidden;
}

.container {
  position: absolute;
  background-color: #596e73;
  width: 100%;
  max-height: 100%;
}

.input_video {
  display: none;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  &.selfie {
    transform: scale(-1, 1);
  }
}


.output_canvas {
  max-width: 100%;
  display: block;
  position: relative;
  left: 0;
  top: 0;
}

 

-JavaScript

<script type="module">
const videoElement = document.getElementsByClassName('input_video')[0];
const canvasElement = document.getElementsByClassName('output_canvas')[0];
const canvasCtx = canvasElement.getContext('2d');

function onResults(results) {
  canvasCtx.save();
  canvasCtx.clearRect(0, 0, canvasElement.width, canvasElement.height);
  canvasCtx.drawImage(
      results.image, 0, 0, canvasElement.width, canvasElement.height);
  if (results.multiHandLandmarks) {
    for (const landmarks of results.multiHandLandmarks) {
      drawConnectors(canvasCtx, landmarks, HAND_CONNECTIONS,
                     {color: '#00FF00', lineWidth: 5});
      drawLandmarks(canvasCtx, landmarks, {color: '#FF0000', lineWidth: 2});
    }
  }
  canvasCtx.restore();
}

const hands = new Hands({locateFile: (file) => {
  return `https://cdn.jsdelivr.net/npm/@mediapipe/hands/${file}`;
}});
hands.setOptions({
  maxNumHands: 2,
  minDetectionConfidence: 0.5,
  minTrackingConfidence: 0.5
});
hands.onResults(onResults);

const camera = new Camera(videoElement, {
  onFrame: async () => {
    await hands.send({image: videoElement});
  },
  width: 1280,
  height: 720
});
camera.start();
</script>

24~28 Line :  손동작 인식 AI모델을 실행할 때 option으로  인식할 최대 손모양 갯수, 최소 신뢰도 값을 지정한다. 

6 ~ 19 Line : 손동작 인식 AI모델 실행결과에 따른 처리 

12 ~ 16 Line : 인식된 손가락 Landmark 좌표를 이용하여 원하는 기능의 동작을 프로그램할 수 있다. 

9~10 Line의 촬영이미지 Display 부분을 삭제하면 다음과 같이 인식된 손가락 모양만 표시된다. 

 

4.  테스트 사이트 

 

다음 링크에 접속하면 Codepen 기능을 이용하여 구글에서 제공하는 데모 프로그램을 동작시켜 볼 수 있고, 여기에서 내용을 수정해 가면서 작동되는 내용을 즉석에서 테스트 확인해 볼 수도  있다.  

 

 

 

MediaPipe - Hands

...

codepen.io

 

1. 미디어파이프(Mediapipe)를 활용한 AI기능 개발  

 

미디어파이프는 구글에서 주로 인체를 대상으로하는 비전인식기능들을  AI모델 개발과 기계학습까지 마친 상태로 제공하는 서비스이다. 다양한 프로그램언어에서 사용하기 편하게 라이브러리 형태로 모듈화되어 제공되며 사용방법 또한 풍부하게 제공되기 때문에 몇가지 간단한 단계로 미디어파이프에서 제공하는 AI기능을 활용한 응용 프로그램개발이 가능하다. 여기에서는 Python언어로 손가락 동작을 인식하는 AI프로그램을 개발하는 과정에 대해 정리한다. 

 

2. 미디어파이프 설치 

 

Python 개발환경이 설치되어 있다면 단순히 mediapipe 모듈을 설치하기만 하면 된다. 즉, "pip install mediapipe" 명령을 입력하여 설치하기만 하면  Python프로그램에서 "import mediapipe"문장으로 호출하여 Mediapipe 기능을  전부 사용할 수 있다. 물론 부가적인 영상처리 등을 위해서는 OpenCV나 numPy 등의 모듈 정도는 기본적으로 설치되어 있어야 한다.  

단 Jetson Nano나  라즈베리파이 등 aarch64 Linux systems기종에 대해서는 아직 pip insall이 지원되지 않고 다음 안내에 따라 설치해 주어야 한다.

 

 

GitHub - jiuqiant/mediapipe_python_aarch64

Contribute to jiuqiant/mediapipe_python_aarch64 development by creating an account on GitHub.

github.com

 

3. 미디어파이프 기본 가이드 

 

설치 후 미디어파이프의 기능별 사용 안내는 다음 링크에서 확인할 수 있다.  

 

그리고 각자의 컴퓨터에 미디어파이프 모듈을 직접 설치하여 개발하기 전에 구글 Colab환경으로 접속하여 코드를 돌려가며 테스트할 수 있는 환경도 제공된다. 

MediaPipe on Google Colab

 

4. 샘플 python 프로그램 

 

Python에서 Hands 인식기능을 이용하여 손가락 동작을 인식하는 샘플 프로그램인데 몇줄 되지 않는다. 이중에서도 실제 AI 모델을 가동시켜 손모양을 인식하는 작업은  20번째 line의 results = hands.process(image) 하나의 명령으로 실행되는 것이다.   

import cv2
import mediapipe as mp

mp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.hands

cap = cv2.VideoCapture(0)

with mp_hands.Hands(
    max_num_hands=1,
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5) as hands:

    while cap.isOpened():
        success, image = cap.read()
        if not success:
            continue
        image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)

        results = hands.process(image)

        image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

        if results.multi_hand_landmarks:
            for hand_landmarks in results.multi_hand_landmarks:
                finger1 = int(hand_landmarks.landmark[4].x * 100 )
                finger2 = int(hand_landmarks.landmark[8].x * 100 )
                dist = abs(finger1 - finger2)
                cv2.putText(
                    image, text='f1=%d f2=%d dist=%d ' % (finger1,finger2,dist), org=(10, 30),
                    fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1,
                    color=255, thickness=3)

                mp_drawing.draw_landmarks(
                    image, hand_landmarks, mp_hands.HAND_CONNECTIONS)

        cv2.imshow('image', image)
        if cv2.waitKey(1) == ord('q'):
            break

cap.release()

 

2~5  Line : mediapipe 모듈을 import하고 약식으로 사용할 명칭을 지정한다. mediapipe.solutions.hands모듈이 손동작인식을 위한 모듈이다. 

7 Line : OpenCV로 웹캠을 읽어 입력데이터 소스로 지정한다. 

 

9~12 Line :  hands 손가락 인식모듈의  작동 option을 지정한다. 

    -max_num_hands=1,   : 인식할 손모양의 갯수, 생략하면 2가 지정된다. 

    -min_detection_confidence=0.5,  : 성공적인 것으로 간주되는 최소 신뢰도 값. 0.0 ~1.0사이로서 기본값은 0.5이다.

    -min_tracking_confidence=0.5 :손 랜드마크가 성공적으로 추적된 것으로 간주되는 최소 신뢰도 값. 0.0 ~1.0 사이로서 기본값은 0.5이다. 이 값을 높이면 시간이 더 소요되지만 좀 더 정확한 작동이 보장된다. 

 

18 Line :  OpenCV 영상은 BGR 형식인데 MediaPipe에서는 RGB 형식을 사용하므로 영상형식을 변환해 준다 

 

20 Line : MediaPipe의 hands 모듈을 이용해서 손동작을 인식한다. 이 한줄로서 손동작 인식 AI모델이 작동되고 결과 값이 result로 저장된다. 

 

22 Line :  MediaPipe용 RGB 형식으로 변환했던 것을 OpenCV 영상저리를위해 다시 BGR형식으로 되돌린다. 

 

24~25 : result값이 정상인 경우에만 후속 작업 처리한다. 

 

26~27 : result로 반환된 landmark 데이터를 사용한다. 

 

인식된 손가락 모양은 다음과 같은 index값으로 가지는 배열로 제공된다.

즉, 업지손가락 끝은 landmark[4]에, 검지 손가락 끝은 landmark[8]에 좌표값이 반환되는데, 좌표값은 image상의 x,y위치값을 0.0~1.0 사이의 값으로 표시한다. 즉 image 좌측 최상단은 x=0.0 y=0.0  우측최하단은 x=1.0, y=1.0이 된다. 따라서int(hand_landmarks.landmark[4].x * 100)은 엄지손가락 끝의 x좌표를 100분율로 표시한 것이 된다. 

 

28 Line : 두 손가락 끝의 x좌표값 차이의 절대값을 구해 두 손가락 끝이 벌어진 정도를 계산한다. 

 

34 ~ 35 Line : MediaPipe에 내장된 유틸리티 기능을 이용해서 구해진 손가락 모양을 서로 연결한 그림을 그려준다.

 

위와 같이 손가락 모양을 인식하고 좌표값을 구해낼 수 있고 이를 이용하여 다양한 기능을 개발할 수 있다. 예를 들어 샘플프로그램에서 처럼 두 손가락 끝이 벌어진 정도값을 구해 스피커 볼륨을 조정하는 기기를 개발할 수 있고 가위바위보 게임을 개발할 수도 있다.  또는 연속되는 손동작 변화를 저장해서 animation용 데이터로 활용할 수 도 있을 것이다. 

1.플랫폼아이오(PlatformIO)

PlatformIO는 다양한 플랫폼의 Embeded 환경 개발을 통합해서 지원하는 개발환경이다.  평소 아두이노 IDE를 사용하다가 코드 편집기가 너무 단순하여 딥답하거나 지원기능이 너무 적어 좀 복잡한 개발 프로젝트를 하기에는 불편하다고 느낀다면 대안으로 좀더 전문적인 PlatformIO 개발환경을 사용해 볼 수 있다.     

 

 

2. PlatformIO 장단점 

  2.1. 장점  

 

 - 아두이노 뿐만 아니라 STM32 프로세서 시리즈와 같은 다양한 환경의 개발을 PlatformIO 단일 개발환경에서 수행할 수 있다 

 

- 프로젝트별로 각기 다른 라이브러리 환경을 정의해서 개발 할 수 있다, 아두이노IDE의 경우 프로젝트별로 각기 다른 버전의 라이브러리를 사용하기가 매우 불편했지만 PlatformIO에서는 프로젝트별로 피료로 하는 라이브러리 버전을 환경파일로 지정할 수 있어 편리하다. 

  

- Visual Studio Code를 소스코드 편집기로 사용하므로 다양하고 편리한 Visual Studio Code기능을 사용할 수 있다

 

- Debug 및 Test를 위한 체계적인 기능 지원 

 

 2.2. 단점  

 

다양한 종류 기기와 Framework를 통합해서 지원하는 도구이다보니 사용방법이 복잡해 지고 시간이 많이 소요된다는 것이다. 단순히 아두이노 호환기기만을 사용할 것이라면 기존 아두이노 IDE를 사용하는 편이 정신건겅에 좋고 오히려 더 효율적일 것이다.   

 

3. PlatformIO 설치 

  3.1 사전 준비사항 

 

PlatfromIO는 Visual Studio Code라는 편집기 위에서 작동되는 확장기능 형태로 제공되며 Python으로 개발되어 있기 때문에 Visual Studio Code와 Python 환경이 설치되어 있어야 한다, Visual Studio Code는 아래 Link에서 다운로드 받을 수있고 Python 환경은 PlatformIO 설치시에 자동으로 확인하여 설치해 주므로 굳이 미리 설치해 주지 않아도 된다.    

 

Visual Studio Code - Code Editing. Redefined

Visual Studio Code is a code editor redefined and optimized for building and debugging modern web and cloud applications.  Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows.

code.visualstudio.com

 

 3.2 PlatformIO 설치하기  

 

Visual Studio Code 의 좌측 탭메뉴의 맨아래에 있는 Extentions를 선택한 후 검색창에 platformio라 입력하여 PlatformIO IDE를 선택한다, 

화면 오른쪽에 표시되는 설명에서 Install 버튼을 클릭하여 설치하면 된다.  

만약 Python 환경이 설치되어 있지 않다면 설치하라는 화면이 나오므로 이때 설치해 주면 된다. 

 

설치작업이 완료되면  완료메세지가 표시되고 Visual Source Code를 재시작한다.  

 

Visual Source Code가 재시작되면 다음과 같은 외계인 모양의 탭메뉴가 추가되어 표시되는데 이것이 Visual Studio Code에서 PlatformIO 개발환경을 사용하기 위한 메뉴이다.    

 

4.  프로그램 작성하기  

 PlatformIO를 선택하고 표시되는 서부메뉴에서 QUICK ACCESS -> PIO Home ->Open메뉴를 선택하면 다음과 같이 

프로젝트 오픈화면이 표시된다.

여기에서 새 프로젝트를 시작하려면 New Project를 선택하면되고, 기존의 아두이노 IDE에서 개발했던 내용을 끌어와서 사용하려면 Import Arduino Project를 선택하면 된다. 

 

New Project를 선택하면 다음과 같이 Project정의 화면이 표시되는데 Board에서 원하는 개발보드를 선택하면  아래 Framework에는 해당 보드에서 선택할 수 있는 Framework가 선별되어 표시된다. 예를 들어 ESP32 보드를 사용한다 해도 Framwork는 아두이노를 선택할 수도 있고 ESP32 제조사에서 직접 제공하는 Espressif IOT Development Framwork를 사용할 수도  있다. 

 

 

Location 의 자동선택 옵션을 해제하면 임의의 폴더를 지정하여 프로젝트 내용을 저정할 수 있다. 

 

설정을 마치고 Finish 버튼을 선택하면 한동안 설치 및 설정작업이 수행된후 다음과 같은 개발작업화면이 표시된다. 

 

입력한 프로젝트 명을 폴더명으로 해서 아래에 여러가지 파일과 폴더들이 생성되는데 여기에서 실제 프로그램을 작성하는 파일은 src 폴더에 작성하는데  main.cpp라는 파일이 기본적으로 생성된다. 아두이노 Framwork일 경우 기본 구조에 맞춰 Setuo()과 loop() function 표시되므로 아두이노 IDE에서와 동일하게 프로그램을 코딩하면 된다.    

 

PlatformIO가 기돈된 상태에서는 화면 하단에 위와 같은 아이콘 메뉴들이 표시되는데 아두이노 IDE에서와 같이 V자 테크 표시는 compile verify 이고 -> 표시는 보드에 업로드하기 기능이다. 

 

참으로 편리한 점중의 하나는 코드 자동 check 기능으로 다음과 같이 코딩과정에서 문제가 있을 경우 자동 check하여 이를 표시해 주는 기능이다.  문장뒤의 ';'를  빠트리는 등 Error가 있을 경우 해당 소스명을 붉게 표시하고 에러 갯수를 표시해 준다. 

이를 수정하여 ';'를 입력하면 다음과 같이 에러표시가 없어 진다. 

이외에도 코드 자동추천 및 자동완성 등 Visual Studio Code의 다양한 기능을 편리하게 사용할 수 있다

'메이킹 도구 활용법' 카테고리의 다른 글

Arduino IDE 2.0 소개  (0) 2021.08.09
자신만의 전용 PCB 제작하기  (1) 2021.03.20
Fritzing 사용법_2  (0) 2021.03.18
Fritzing사용법_1  (0) 2021.03.17
Fritzing 유료화 및 무료설치방법  (0) 2021.02.21

+ Recent posts