iBetter Books
수정

DeepFace 감정이 무겁다면, EmotiEffLib는 그 대안입니다. 예전 이름 HSEmotion으로도 알려진 이 라이브러리는 가벼운 ONNX 모델로 감정을 빠르게 분류하고, 한 걸음 더 나아가 영상에서 몰입도(engagement)까지 추정합니다. PART 07의 InsightFace처럼 onnxruntime 기반이라 TensorFlow 없이 가볍습니다.

검출은 따로, 감정만 담당

EmotiEffLib는 한 가지 일에 집중합니다. 이미 잘라낸 얼굴을 받아 감정만 분류합니다. 얼굴을 찾는 일은 하지 않으므로, 앞단에 검출기가 필요합니다. PART 02에서 배운 YuNet 등으로 얼굴을 잘라(crop) EmotiEffLib에 넘기는 구조입니다.

flowchart LR A[이미지] --> B[검출기 YuNet
얼굴 크롭] B --> C[EmotiEffLib
predict_emotions] C --> D[표정·점수]

감정 분류 코드

PART 01에서 설치한 emotiefflib를 씁니다. 검출은 OpenCV YuNet으로, 감정은 EmotiEffLib로 처리합니다.

# 파일: emotiefflib_demo.py"""YuNet으로 얼굴을 잘라 EmotiEffLib로 감정을 분류한다."""import cv2from emotiefflib.facial_analysis import EmotiEffLibRecognizer# 경량 8분류 ONNX 모델 (CPU)fer = EmotiEffLibRecognizer(engine="onnx",                            model_name="enet_b0_8_best_vgaf", device="cpu")detector = cv2.FaceDetectorYN.create(    "face_detection_yunet_2023mar.onnx", "", (320, 320), 0.9, 0.3, 5000)img = cv2.imread("face.jpg")h, w = img.shape[:2]detector.setInputSize((w, h))_, faces = detector.detect(img)if faces is not None:    x, y, bw, bh = faces[0][:4].astype(int)    crop = img[y:y + bh, x:x + bw]                 # 얼굴 영역만 자르기    rgb = cv2.cvtColor(crop, cv2.COLOR_BGR2RGB)    # RGB로 변환해 입력    emotions, scores = fer.predict_emotions(rgb, logits=False)    print("표정:", emotions)        # 예: ['Happiness']    print("점수:", scores)          # 각 분류의 확률

EmotiEffLibRecognizerengine="onnx"와 모델 이름을 주어 만들고, predict_emotions에 잘라낸 얼굴(RGB)을 넘기면 표정과 점수가 나옵니다. logits=False는 점수를 확률 형태로 받겠다는 뜻입니다. 모델 이름의 8은 8분류(7분류 + 경멸)를 뜻하며, get_model_list()로 다른 모델을 확인할 수 있습니다.

몰입도(engagement) 추정

EmotiEffLib의 특색은 몰입도 기능입니다. 한 장이 아니라 영상의 여러 프레임을 묶어 넘기면, 그 사람이 얼마나 집중·참여하고 있는지를 추정합니다. 화상 강의나 회의의 참여도 분석에 쓸 수 있습니다.

# 파일: engagement.py (개념)# face_imgs: 한 사람의 연속 프레임 얼굴 크롭 목록engagement = fer.predict_engagement(face_imgs, sliding_window_width=16)

몰입도는 단일 프레임으로는 알기 어렵습니다. 표정이 시간에 따라 어떻게 변하는지를 봐야 하기 때문입니다. 그래서 여러 프레임을 슬라이딩 윈도로 묶어 분석합니다. PART 03에서 만든 졸음 감지(EAR)와 결합하면 더 풍부한 집중도 분석이 됩니다.

DeepFace 감정과 비교

항목 DeepFace emotion EmotiEffLib
실행기 TensorFlow onnxruntime(가벼움)
검출 내장(자동) 따로 필요(YuNet 등)
분류 7가지 8가지(경멸 포함)
특색 인식·나이와 통합 몰입도(engagement)
속도 보통 빠름

감정만 빠르게, 특히 몰입도까지 보고 싶다면 EmotiEffLib가, 인식·나이와 한 라이브러리로 묶고 싶다면 DeepFace가 유리합니다.

실무 팁. EmotiEffLib에 넘기는 얼굴 크롭의 품질이 결과를 좌우합니다. 너무 빡빡하게 자르면 표정 정보(눈썹·입꼴)가 잘리고, 너무 헐렁하면 배경이 섞입니다. YuNet 박스를 그대로 쓰기보다 위아래로 약간(10~20%) 여유를 주어 자르면 표정 분류가 안정적입니다. PART 03의 정렬을 앞에 두면 더 좋습니다.

이 장에서 기억할 것

EmotiEffLib(구 HSEmotion)는 onnxruntime 기반의 가벼운 감정 분류기로, 검출은 하지 않으니 YuNet 등으로 얼굴을 잘라 predict_emotions에 넘깁니다. 8분류 표정과 함께, 여러 프레임을 묶어 몰입도를 추정하는 특색이 있습니다. TensorFlow 없이 빠른 것이 DeepFace 감정과의 차이입니다. 다음 장에서는 분류가 아니라 근육 계수로 표정을 다루는 전혀 다른 접근, MediaPipe 블렌드셰이프를 만납니다.