728x90
반응형
Solution
- 미디어파이프(Mediapipe)의 경우 c++로 구현할 수 도 있지만, 언리얼 엔진 내부에서 돌리기에는 많이 무거운듯하다. 그렇기 때문에 python으로 돌리고 osc 통신을 통해 결과값을 언리얼 엔진으로 전달하는 형태의 구조로 구성
- 언리얼 엔진 내부에서 동작하기에 미디어파이프도 C++로 구현되어 있지만, 빌드 체계가 언리얼 엔진과는 달라 통합하려면 상당한 작업이 필요하다고 알게 됨
1. Unreal에서 MediaPipe를 C++로 구현 가능할까?
✔️ 가능은 함(구글이 C++용 MediaPipe 라이브러리 제공)
- MediaPipe는 원래 C++로 만들어졌습니다.
- 다만 빌드 체계는 Bazel을 사용하며, Unreal은 CMake/Visual Studio 기반입니다.
- 두 시스템을 통합하려면 상당한 수작업이 필요합니다.
C++ MediaPipe를 Unreal 플러그인으로 컴파일하기 위해 Bazel 빌드된 .so 또는 .lib 파일을 Unreal로 가져와야 함
2. Unreal에서 MediaPipe를 직접 붙일 때의 장단점
장점
항목 | 설명 |
엔진 내부에서 직접 실행 | OSC 통신 없이 바로 Control Rig, Niagara 등에 연결 가능 |
모바일/배포 최적화 | 안드로이드/iOS 앱 안에 통합 가능 |
지연 최소화 | 데이터 송수신 지연 없이 곧바로 처리 가능 |
단점
항목 | 설명 |
빌드 통합 난이도 극단적 | MediaPipe는 Bazel 빌드를 요구하고, Unreal은 CMake/VS 기반. 두 환경 충돌 |
구글의 Graph 기반 처리 방식 | Unreal의 타임라인/프레임 기반 로직과 직접 연동 어려움 |
GPU 가속 구성 복잡 | OpenGL, Vulkan 등 백엔드가 충돌 가능 (특히 DX 기반 Unreal과 충돌 여지 있음) |
디버깅/패키징 어려움 | Unreal 프로젝트 내에서 직접 트래킹 문제 발생 시 원인 추적이 어려움 |
- 기본 미디어 파이프 종류
- Hand Tracking
Install Python
Visual Studio Code - Code Editing. Redefined
Visual Studio Code redefines AI-powered coding with GitHub Copilot 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
Download Python
The official home of the Python Programming Language
www.python.org
- 필요 모듈 임포트
pip install opencv-python mediapipe python-osc
- opencv-python : 이미지 및 영상 처리를 위한 OpenCV 라이브러리
- mediapipe : 구글에서 제공하는 실시간 포즈, 손, 얼굴 추적 등을 지원하는 라이브러리
- python-osc : Python에서 Open Sound Control (OSC) 프로토콜을 사용하기 위한 라이브러리
주요 코드
import cv2
import mediapipe as mp
from pythonosc import udp_client
# OSC 설정
OSC_IP = "172.30.1.21"
OSC_PORT = 8000
client = udp_client.SimpleUDPClient(OSC_IP, OSC_PORT)
# MediaPipe 설정
mp_hands = mp.solutions.hands
mp_drawing = mp.solutions.drawing_utils
hands = mp_hands.Hands(
static_image_mode=False,
max_num_hands=1,
model_complexity=1,
min_detection_confidence=0.5,
min_tracking_confidence=0.5
)
# 웹캠 시작
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
frame = cv2.flip(frame, 1)
image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
result = hands.process(image_rgb)
if result.multi_hand_landmarks:
for hand_landmarks in result.multi_hand_landmarks:
# 중심을 계산할 landmark 인덱스
center_indices = [0, 5, 9, 13, 17] # 손목 + 손가락 시작점
avg_x = sum([hand_landmarks.landmark[i].x for i in center_indices]) / len(center_indices)
avg_y = sum([hand_landmarks.landmark[i].y for i in center_indices]) / len(center_indices)
# OSC 전송
client.send_message("/hand/center", [avg_x, avg_y])
# 시각화
h, w, _ = frame.shape
cx, cy = int(avg_x * w), int(avg_y * h)
cv2.circle(frame, (cx, cy), 10, (0, 255, 0), -1)
mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
else:
# 손이 감지되지 않을 때 텍스트 표시
cv2.putText(frame, "No hand detected", (30, 50),
cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 2)
client.send_message(f"/hand/exit", 0)
cv2.imshow("Hand Center Tracking", frame)
if cv2.waitKey(1) & 0xFF == 27:
break
cap.release()
cv2.destroyAllWindows()
728x90
'Unreal > Tips' 카테고리의 다른 글
[UE Tips] Timeline vs Interp To (0) | 2025.05.08 |
---|---|
[UE5 Tips] Alembic(.abc)이란? (0) | 2025.02.24 |
[UE Tips] 언리얼 엔진에서 WebSocket 통신 구현하기 (1) | 2024.12.30 |
[UE Tips] Enhanced Input System 활용하기 (0) | 2024.12.23 |
[UE Tips] 언리얼 엔진에서 웹캠 출력하기 (0) | 2024.12.11 |