iBetter Books
수정

buffalo_l을 준비했다면, 실제 사용은 놀랍도록 간단합니다. app.get(이미지) 한 번이면 검출·정렬·임베딩·속성이 모두 끝납니다. PART 02~06에서 단계별로 배운 모든 것이 이 한 호출에 압축되어 있습니다. 이 장에서는 그 결과인 Face 객체를 속속들이 들여다봅니다.

app.get — 한 호출의 위력

# 파일: analyze_insight.py"""InsightFace로 한 번에 검출·임베딩·속성을 얻는다."""import cv2from insightface.app import FaceAnalysisapp = FaceAnalysis(name="buffalo_l", providers=["CPUExecutionProvider"])app.prepare(ctx_id=-1, det_size=(640, 640))img = cv2.imread("sample.jpg")faces = app.get(img)          # 검출·정렬·임베딩·속성 한 번에print(f"검출된 얼굴: {len(faces)}개")for f in faces:    print("  bbox:", [int(v) for v in f.bbox])    print("  임베딩 차원:", f.embedding.shape)     # (512,)    print("  검출 신뢰도:", round(float(f.det_score), 3))    print("  나이:", f.age, "/ 성별:", f.sex)

app.get(img)이 돌려주는 것은 Face 객체들의 목록입니다. 사진에 얼굴이 여럿이면 여러 개가 나옵니다. PART 06의 DeepFace가 함수마다(verify·analyze) 따로 호출해야 했다면, InsightFace는 한 번의 get으로 신원용 임베딩과 나이·성별을 동시에 줍니다.

Face 객체가 담은 것

Face 객체 하나에는 얼굴에 관한 거의 모든 정보가 들어 있습니다.

속성 내용 PART 대응
bbox 박스 [x1, y1, x2, y2] PART 02 검출
kps 5점 랜드마크 PART 03 랜드마크
det_score 검출 신뢰도 PART 02 신뢰도
embedding 512차원 임베딩 PART 04 임베딩
normed_embedding 정규화된 임베딩(코사인용) PART 04 거리
age / sex 나이 / 성별('M'/'F') (속성)

이 한 객체에 PART 02(박스), PART 03(5점), PART 04(임베딩)가 모두 들어 있는 셈입니다. 실제로 위 코드를 웃는 인물 사진에 돌려 결과를 그려 보면 다음과 같습니다.

InsightFace FaceAnalysis 결과

코사인 비교는 normed_embedding으로

두 얼굴을 비교할 때는 normed_embedding을 쓰는 것이 편합니다. 이미 길이가 1로 정규화되어 있어, 두 벡터의 내적이 곧 코사인 유사도가 됩니다.

# 파일: compare_insight.pyimport numpy as npf1 = app.get(cv2.imread("a.jpg"))[0]f2 = app.get(cv2.imread("b.jpg"))[0]# 정규화된 임베딩의 내적 = 코사인 유사도 (클수록 닮음)similarity = float(np.dot(f1.normed_embedding, f2.normed_embedding))print(f"코사인 유사도: {similarity:.3f}")print("같은 사람?" , similarity > 0.4)   # 임계값은 데이터로 조정

PART 04의 코사인 유사도가 여기서는 np.dot(정규화 임베딩) 한 줄로 끝납니다. ArcFace 임베딩의 코사인 임계값은 0.4 안팎이 흔한 출발점이며, 늘 그렇듯 내 데이터로 조정합니다.

나이 추정의 한계를 다시 확인

흥미로운 점 하나. 같은 사진을 PART 06의 DeepFace와 이 InsightFace로 분석하면 추정 나이가 다르게 나옵니다. 모델마다 학습 데이터와 방식이 다르기 때문입니다. 한 모델이 30대 후반으로, 다른 모델이 50대로 추정하는 일이 흔합니다.

이는 어느 한쪽이 틀렸다기보다, 나이 추정 자체가 본질적으로 불확실하다는 신호입니다. PART 06에서 강조했듯, 나이·성별 같은 속성은 "정확한 값"이 아니라 "대략의 경향"으로만 쓰는 것이 안전합니다. 반면 신원 인식용 임베딩은 훨씬 안정적이라, InsightFace의 진짜 강점은 속성이 아니라 인식 정확도에 있습니다.

실무 팁. app.get은 매번 검출부터 다시 합니다. 같은 이미지를 여러 번 분석할 일은 없지만, 영상에서 매 프레임 호출하면 무겁습니다. 실시간이라면 det_size를 줄여(예: 320×320) 속도를 높이거나, 몇 프레임에 한 번만 get을 호출하고 사이는 추적(tracking)으로 메우는 방식을 씁니다. 정확도와 속도의 예산 배분은 PART 06과 같은 원리입니다.

이 장에서 기억할 것

InsightFace는 app.get(img) 한 번으로 검출·정렬·임베딩·속성을 모두 처리해 Face 객체 목록을 돌려줍니다. 한 객체에 bbox·kps·embedding·normed_embedding·age·sex가 모두 담겨 PART 02~04가 통합됩니다. 비교는 normed_embedding의 내적(코사인)으로 간단히 하고, 나이 추정은 모델마다 달라 경향으로만 봅니다. 다음 장에서는 이 모든 것을 TensorFlow 없이 가볍게 돌리는 onnxruntime 기반을 다룹니다.