티스토리 뷰
SUMMARY
kwon_mediapipe_landmarker
Flutter용 MediaPipe Face/Pose Landmarker 플러그인 개발기입니다.
Face Landmarker는 478개 얼굴 랜드마크와 52개 ARKit 호환 블렌드쉐입을,
Pose Landmarker는 33개 신체 랜드마크를 감지합니다.
주요 기술적 도전: iOS 전면 카메라 미러링 해결, 플랫폼별 YUV-RGB 변환 최적화, 통일된 에러 핸들링
TABLE OF CONTENTS
목차
왜 이 플러그인을 만들었나? 주요 기능 소개 기술적 도전과 해결 사용 방법 활용 사례
WHY
왜 이 플러그인을 만들었나?
Flutter 생태계에서 MediaPipe 기반의 얼굴/포즈 인식 플러그인은 존재하지만, 대부분 기본적인 랜드마크 감지만 제공하거나 플랫폼별 동작 차이가 있는 경우가 많았습니다.
특히 iOS 전면 카메라에서 좌우가 반대로 인식되는 문제는 많은 개발자들이 겪는 어려움입니다.
저는 실시간 얼굴 표정 분석(눈 맞춤, 미소, 긴장도)과 자세 분석(어깨 대칭, 고개 기울기)이 필요한 프로젝트를 진행하면서, 이러한 기능을 쉽게 사용할 수 있는 플러그인의 필요성을 느꼈습니다.
FEATURES
주요 기능 소개
Face Landmarker
478개 얼굴 랜드마크 감지 — 눈, 코, 입, 얼굴 윤곽 등 세밀한 얼굴 특징점을 실시간으로 감지합니다.
52개 ARKit 호환 블렌드쉐입 — Apple ARKit과 동일한 블렌드쉐입 체계를 사용하여, eyeBlinkLeft, mouthSmileRight 등의 표정 데이터를 제공합니다.
Pose Landmarker
33개 신체 랜드마크 — MediaPipe Pose 모델 기반으로 전신 자세를 감지합니다.
World Landmarks 지원 — 미터 단위의 3D 좌표를 제공하여 실제 공간에서의 자세 분석이 가능합니다.
Helper Extensions
FaceResultHelper — 14개 분석 메서드
eyeContactScore smileScore tensionScore isLookingLeft/Right
PoseResultHelper — 19개 분석 메서드
postureScore shoulderSymmetryScore headTiltAngle isHandRaised
TROUBLESHOOTING
기술적 도전과 해결
PROBLEM 01
iOS 전면 카메라 미러링 문제
iOS 전면 카메라로 촬영하면 이미지가 미러링되어, 오른손을 들면 왼손으로 인식되는 문제가 발생했습니다. Android에서는 정상 동작하지만, iOS에서만 좌우가 반대로 나오는 현상이었습니다.
해결 시도 1 — X 좌표 반전
처음에는 단순히 x = 1.0 - x로 X 좌표만 반전했지만, 이것만으로는 부족했습니다. 좌표는 맞아도 랜드마크 인덱스 자체가 여전히 반대였습니다.
SOLUTION — X 좌표 반전 + Left/Right 인덱스 스왑
// iOS - PoseLandmarkerHelper.swift
private static let leftRightSwapMap: [Int: Int] = [
11: 12, 12: 11, // leftShoulder <-> rightShoulder
15: 16, 16: 15, // leftWrist <-> rightWrist
// ... 총 16쌍
]
let targetIndex = Self.leftRightSwapMap[originalIndex] ?? originalIndex
landmarksList[targetIndex] = [
"x": 1.0 - landmark.x, // X 좌표 반전
"y": landmark.y
]
PROBLEM 02
YUV-RGB 변환 성능 최적화
카메라에서 받은 YUV420 이미지를 MediaPipe가 처리할 수 있는 RGB 형식으로 변환해야 하는데, 이 과정이 성능 병목이 될 수 있습니다.
SOLUTION — 플랫폼별 최적화
Android
코루틴 기반 병렬 처리로 YUV-RGB 변환 수행
iOS
Apple Accelerate 프레임워크의 vImage를 사용하여 하드웨어 가속
PROBLEM 03
플랫폼 간 일관된 에러 핸들링
Dart, Android(Kotlin), iOS(Swift) 세 플랫폼에서 발생하는 에러를 일관된 방식으로 처리해야 했습니다.
SOLUTION — 통일된 에러 코드 Enum 정의
enum LandmarkerError {
notInitialized('NOT_INITIALIZED'),
modelLoadFailed('MODEL_LOAD_FAILED'),
invalidImage('INVALID_IMAGE'),
detectionFailed('DETECTION_FAILED'),
cameraPermissionDenied('CAMERA_PERMISSION_DENIED'),
// ... 총 11개 에러 코드
}
USAGE
사용 방법
1. 설치
# pubspec.yaml
dependencies:
kwon_mediapipe_landmarker: ^0.0.1
2. 기본 사용법
import 'package:kwon_mediapipe_landmarker/kwon_mediapipe_landmarker.dart';
// Face Landmarker 초기화
final faceLandmarker = FaceLandmarker();
await faceLandmarker.initialize(
options: FaceLandmarkerOptions(
numFaces: 1,
minDetectionConfidence: 0.5,
outputBlendshapes: true,
),
);
// 카메라 이미지에서 감지
final result = await faceLandmarker.detectFromCamera(cameraImage);
// 리소스 해제
await faceLandmarker.close();
3. Helper Extension 활용
// FaceResultHelper 사용
if (faceResult != null) {
print('눈 맞춤: ${(faceResult.eyeContactScore * 100).toInt()}%');
print('미소: ${(faceResult.smileScore * 100).toInt()}%');
}
// PoseResultHelper 사용
if (poseResult != null) {
print('자세 점수: ${(poseResult.postureScore * 100).toInt()}%');
print('오른손 들기: ${poseResult.isRightHandRaised ? "Yes" : "No"}');
}
USE CASES
활용 사례
화상 면접 앱
눈 맞춤 점수, 자세 점수, 긴장도를 실시간으로 분석하여 면접자에게 피드백 제공
헬스케어/피트니스 앱
운동 자세 분석, 스쿼트/푸쉬업 카운팅, 자세 교정 가이드
온라인 교육 플랫폼
학습자의 집중도 분석, 졸음 감지
엔터테인먼트
AR 필터, 표정 기반 이모지, 아바타 애니메이션
CONCLUSION
결론
MediaPipe의 강력한 얼굴/포즈 인식 기능을 Flutter에서 쉽게 사용할 수 있도록 kwon_mediapipe_landmarker 플러그인을 개발했습니다.
특히 iOS 전면 카메라 미러링 문제 해결과 Helper Extension을 통한 편의 기능 제공에 중점을 두었습니다.
이 플러그인은 화상 면접, 헬스케어, 교육 등 다양한 분야에서 활용될 수 있으며, 앞으로도 지속적으로 기능을 개선해 나갈 예정입니다.
긴 글을 읽어주셔서 감사합니다!
처음 이 플러그인을 개발하기 시작했을 때는 단순히 MediaPipe를 Flutter에서 사용하는 것이 목표였습니다.
하지만 개발을 진행하면서 iOS 미러링 문제, 성능 최적화, 에러 핸들링 등 예상치 못한 도전들을 마주하게 되었습니다.
특히 iOS에서 "오른손을 들었는데 왼손으로 인식되는" 문제를 해결하기 위해 X 좌표 반전뿐만 아니라 랜드마크 인덱스까지 스왑해야 한다는 것을 알아냈을 때, 플랫폼별 차이를 깊이 이해하는 것이 얼마나 중요한지 다시 한번 깨달았습니다.
이 플러그인이 Flutter로 얼굴/포즈 인식 앱을 개발하시는 분들께 작은 도움이 되었으면 합니다.
피드백이나 개선 사항은 GitHub Issue로 남겨주시면 감사하겠습니다!
- Total
- Today
- Yesterday
- Single Table Design
- ai 게임 개발
- riverpod
- flutter 개발자
- 내러티브 게임
- Clean Architecture
- KE-T5
- 크로스플랫폼
- https://github.com/kwongeneral/kortfolio.git
- 클린 아키텍처
- aws lambda
- 파이썬
- Compose
- Prompt Engineering
- 자막 생성기
- dynamodb
- TypeScript
- 서버리스 아키텍처
- flutter 면접 질문
- 개발자
- injectable
- OpenAI GPT
- 파이썬 기초
- flutter
- python 기초
- kotlin
- 상태관리
- python
- AWS CDK
- https://www.kwonputer.shop/
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |





