#16 #얼굴 인증(Face Authentication) 기능 구현

서영·2025년 9월 8일

트러블슈팅

목록 보기
2/2
post-thumbnail

전동 킥보드 이용 시 헬멧 착용 여부를 AI로 인식해
안전한 주행 문화를 만드는 스마트 안전 시스템 쓰라(SR.A)
AI지니어스 파이널 미션 프로젝트로 개발하기로 결정했다.

이 시스템에서 나는,
회원가입 시 등록한 사용자의 면허증 얼굴과 실시간 카메라의 얼굴이 동일인인지 판별하는 기능을 구현해야 했다.
즉, 헬멧 인식 시 실제 사람이 면허증의 주인과 같은 사람인지 확인하는 과정이다.

본격적인 개발에 앞서, 얼굴 인식의 핵심 개념을 먼저 정리했다.

1. Face Detection과 Face Recognition의 차이

얼굴 인식 기술에는 여러 용어가 존재한다.
그중에서도 자주 혼동되는 개념인 Face Detection, Face Recognition,
그리고 그 하위 개념인 Face Verification, Face Identification을 명확히 구분할 필요가 있다.

(1) Face Detection (얼굴 탐지)

사진이나 영상에서 얼굴이 존재하는지 감지하는 과정이다.
즉, “이 화면에 얼굴이 있는가?”를 판단한다.
카메라가 사람의 얼굴을 찾아 초점을 맞추는 기능이 대표적인 예시다.

(2) Face Recognition (얼굴 인식)

탐지된 얼굴이 누구의 얼굴인지 식별하는 과정이다.
이는 다시 두 가지 방식으로 나뉜다.

Face Verification (1:1 검증)
→ “이 얼굴이 등록된 사람과 동일한가?”
예: 출입 시스템에서 얼굴을 등록된 정보와 비교해 본인 여부를 확인.

Face Identification (1:N 식별)
→ “이 얼굴이 데이터베이스의 누구인가?”
예: 여러 사람 중 입력된 얼굴과 가장 유사한 인물을 찾는 경우.

따라서, 나는 “이 얼굴이 등록된 사람과 동일한가?”를 확인하기 위한
Face Verification 기능을 선택하여 구현하기로 했다.

2. BEFORE (1차 버전: auto_register.py)

첫 번째 버전은 단순히 얼굴을 자동으로 등록하는 기능만 수행했다.
카메라가 켜지면 얼굴이 감지되는 즉시 임베딩(512차원 벡터)을 생성하고,
registered_face.jpg와 user_embedding.npy 파일을 저장하는 구조였다.

def auto_register():
    cap = cv2.VideoCapture(0)
    while True:
        ok, frame = cap.read()
        boxes, _ = mtcnn.detect(frame)
        if boxes is not None:
            emb = get_embedding_from_bgr(frame)
            if emb is not None:
                cv2.imwrite(IMG_PATH, frame)
                np.save(EMBED_PATH, emb)
                break

이 버전은 기본 기능은 안정적이었지만,
등록 이후 동일인 판별(인증) 과정이 없어 서비스 확장에 한계가 있었다.

3. 문제점

구분 내용
기능 한계 얼굴 등록만 가능하고, 동일인 여부를 판별할 수 없음
확장성 부족 면허증 이미지 입력, 비교, 실시간 인증 등으로 확장 불가
테스트 불편 카메라가 감지될 때마다 자동 저장되어 실험 반복 시 제어가 어려움
UI 부재 사용자가 현재 어떤 단계(등록/인증)에 있는지 확인 불가

4. 해결 방법 (리팩터링 방향)

두 번째 버전(main.py)에서는 다음과 같은 방향으로 개선했다.

(1) 기능 구조 개선

단순 등록 기능 외에 인증(Verification) 기능을 추가

면허증 파일로 등록하거나 웹캠으로 등록 후 실시간 동일인 판별 가능

(2) 사용자 인터페이스 강화

키 입력(R, V, S, Q)을 통해 단계별 조작 가능

인증 결과를 실시간으로 시각적으로 표시 (“인증 성공 ✅ / 인증 실패 ❌”)

(3) 거리 기반 비교 기능 추가

FaceNet 임베딩 간 유클리드 거리 계산 함수 추가

등록된 얼굴과 실시간 얼굴의 유사도를 수치로 판단

(4) 시각적 피드백 구현

OpenCV를 사용하여 얼굴 박스 및 인증 결과를 화면에 표시

5. AFTER (2차 버전: main.py)

개선된 코드에서는 등록, 인증, 피드백, 저장 기능이 모두 한 프로그램 내에서 작동했다.

def verify_live(cap, registered_emb):
    while True:
        ok, frame = cap.read()
        boxes, _ = mtcnn.detect(frame)
        if boxes is not None:
            for (x1, y1, x2, y2) in boxes.astype(int):
                cv2.rectangle(frame, (x1, y1), (x2, y2), (0,255,0), 2)

        emb = get_embedding_from_bgr(frame)
        if emb is not None and registered_emb is not None:
            dist = euclidean_dist(registered_emb, emb)
            if dist < DIST_THRESHOLD:
                msg = f"인증 성공 ✅ dist={dist:.2f}"
            else:
                msg = f"인증 실패 ❌ dist={dist:.2f}"
        cv2.putText(frame, msg, (24, 48), FONT, 0.9, (255,255,255), 2)

실시간 결과 피드백을 통해 검증 효율성이 높아졌다.

함수 단위 분리로 코드 가독성과 유지보수성이 향상되었다.

6. 효과

항목 변화 내용
사용성 자동화 중심 구조에서 사용자 조작 기반 통합 구조로 발전
기능 확장성 단순 등록 → 파일 등록 + 실시간 인증으로 기능 범위 확대
UI 개선 시각 피드백(얼굴 박스, 인증 결과 표시) 추가
학습 효과 Face Detection → Verification 과정을 직접 구현하며 기술적 이해도 향상
차후 확장 기반 마련 InsightFace, Cosine Similarity, Liveness Detection 등 추가 실험이 용이한 구조 확보

7. 결론

리팩터링을 통해 코드는 단순한 “등록 도구”에서
“실제 서비스 흐름을 반영한 통합 얼굴 인증 시스템”으로 발전했다.

함수 구조화, 입력 방식 다양화, 실시간 비교 로직 추가 등을 통해
기능성, 확장성, 유지보수성이 모두 향상되었으며,
이 경험을 통해 Face Verification 기술의 원리와 구현 구조를 깊이 있게 이해할 수 있었다.

0개의 댓글