프로젝트 소개
이 프로젝트는 동아리 수업 시간에 실시간 데이터 처리 라이브러리인 OpenCV를 배우면서, 이를 이용한 활용과 응용을 해보고자 시작했습니다.
해당 프로젝트를 기획하고 얼굴 패턴 인식에 무슨 문제점이 있나 찾아보는 와중에 기존의 보안·감시 시스템에서 사용되는 얼굴 인식 기술은 실제 얼굴 이미지를 그대로 저장하는 경우가 많아 자연스럽게 초상권 침해나 개인정보 유출 위험이 따라붙는다는 근본적인 한계가 있다는 점을 찾았습니다.
이를 해결하기 위해, 웹캠으로 입력된 얼굴 데이터를 저장할 때 원본 이미지는 남기지 않고, 딥러닝 모델로 추출한 얼굴의 패턴만을 NumPy 라이브러리를 사용한 벡터 형태로 변환하여 보관합니다.
또 사용자 등록 시 이름 대신 고유 ID 코드로만 관리하여, 실제 개인정보 노출을 최소화하고 익명성을 극대화한 보안 시스템을 구축하는 것을 목표로 잡고 해당 프로젝트를 개발하였습니다.
프로젝트 기획
개발은 VScode 환경에서 진행하였고 프로그램의 기본 구조는 먼저 웹캠에서 실시간 영상 프레임을 받아와, 이를 파이썬의 NumPy 라이브러리를 이용해 다차원 배열(벡터)로 변환합니다. 얼굴 인식과 특징 추출에는 OpenCV에 내장된 Haar Cascade 분류기(OpenCV_Haar)를 사용했습니다.
해당 모델은 오브젝트 검출을 위한 분류기이며 특정 패턴을 학습하여 얼굴, 눈, 입 모양, 등의 객체를 검출합니다.
이렇게 검출된 얼굴의 패턴은 딥러닝 기반의 유사도 계산 알고리즘을 거치는데 이때 코사인(cos) 유사도 개념이 적용되어 데이터베이스에 저장된 패턴과 비교됩니다. 마지막으로, OpenCV의 imshow 기능을 이용해 패턴 인식 결과가 실시간 영상에 오버레이되어 사용자에게 보여지는 방식으로 시스템을 완성했습니다.
프로젝트 결과
해당 프로그램은 사용자가 쉽게 다룰 수 있도록 직관적인 인터페이스와 간단한 키 조작 기능을 갖추도록 제작하였습니다.
핵심 기능들은 q키를 누르기 전까지 실시간 영상 프레임을 계속 처리하는 무한 반복문에서 이루어집니다. 먼저, 얼굴을 검출할 때는 OpenCV의 Haar Cascade 모델을 활용해 영상 속에서 얼굴을 빠르고 정확하게 찾아냅니다.
다음으로, n키를 누르면 패턴을 학습하고 등록하는 과정을 과정을 거치는데 이때 화면에서 가장 먼저 검출된 얼굴의 패턴을 추출해서 새로운 ID로 데이터베이스에 저장하고 학습합니다. 다음으로 실시간 인식 기능에서 검출된 얼굴 패턴을 데이터베이스에 저장된 벡터 패턴들과 비교합니다.
이때 유사도 기준값인 0.96을 넘기면 등록된 ID와 현재 유사도가 화면에 표시되어 사용자를 식별하며, 그보다 낮으면 ‘Unknown’으로 나타나 등록되지 않은 사용자임을 알려줍니다.
결과적으로 실시간으로 개인정보 보호에 초점을 맞춘 보안·감시 시스템의 주요 기능들이 효과적으로 작동하였습니다.
코드
import os # 운영체제 관리 및 조작 기능들이 담긴 모듈
import cv2
import numpy as np
# 1. 설정 값
DB_FILE = "face_patterns.npy"
SIM_THRESHOLD = 0.96 # 이 값 이상이면 ID로 인식, 미만이면 Unknown
# 2. 패턴 DB 관련 함수
def load_pattern_db():
if not os.path.exists(DB_FILE):
return []
arr = np.load(DB_FILE)
if arr.size == 0:
return []
return [arr[i] for i in range(arr.shape[0])]
def save_pattern_db(pattern_db):
if len(pattern_db) == 0:
if os.path.exists(DB_FILE):
os.remove(DB_FILE)
return
arr = np.stack(pattern_db, axis=0)
np.save(DB_FILE, arr)
def clear_pattern_db():
if os.path.exists(DB_FILE):
os.remove(DB_FILE)
print("[INFO] 패턴 DB 파일 삭제 완료.")
# 프로그램 시작 시 기존 DB 로드
pattern_db = load_pattern_db()
print(f"[INFO] 로드된 패턴 개수: {len(pattern_db)}")
# 3. 얼굴 임베딩(패턴) / 인식 함수
def get_embedding(face_img):
face_resized = cv2.resize(face_img, (64, 64))
vec = face_resized.flatten().astype(np.float32) / 255.0
norm = np.linalg.norm(vec)
if norm > 0:
vec = vec / norm
return vec
# 코사인 유사도 계산
def cosine_similarity(a, b):
return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b) + 1e-8))
# 인식 함수
def recognize_face(embedding, pattern_db, threshold=SIM_THRESHOLD):
if len(pattern_db) == 0:
return None, -1.0
best_idx = None
best_sim = -1.0
for idx, emb in enumerate(pattern_db):
sim = cosine_similarity(embedding, emb)
if sim > best_sim:
best_sim = sim
best_idx = idx
if best_sim >= threshold:
return best_idx, best_sim
else:
return None, best_sim
# 4. 얼굴 검출기 (OpenCV Haar)
face_cascade = cv2.CascadeClassifier(
cv2.data.haarcascades + "haarcascade_frontalface_default.xml"
)
# 5. 메인 루프
def main():
global pattern_db
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
while True:
ret, frame = cap.read()
if not ret: continue
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.1, 5, minSize=(80, 80))
for (x, y, w, h) in faces:
face_img = frame[y:y + h, x:x + w]
emb = get_embedding(face_img)
idx, sim = recognize_face(emb, pattern_db)
if idx is not None:
label = f"ID #{idx} ({sim:.2f})"
color = (0, 255, 0)
else:
label = "Unknown"
color = (0, 0, 255)
cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
cv2.putText(frame, label, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2)
cv2.imshow("Face Pattern", frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('n'):
if len(faces) > 0:
(x, y, w, h) = faces[0]
face_img = frame[y:y + h, x:x + w]
pattern_db.append(get_embedding(face_img))
save_pattern_db(pattern_db)
if key == ord('c'):
pattern_db = []; clear_pattern_db()
if key == ord('q'): break
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
시연
시연 영상
소감
이번 프로젝트를 혼자 완성하는 동안 딥러닝과 OpenCV에 대한 이해가 부족해 초반엔 어려움이 많았습니다.
OpenCV Haar의 패턴 추출 구조 이해와 얼굴 특징 패턴을 정규화하고 유사도를 정확하게 계산하는 부분에서 어려움이 많았습니다. 하지만 문제를 해결하는 과정에서 생성형 AI와 온라인 자료를 적극적으로 활용했더니 점차 감을 잡을 수 있었고, 실제로 AI 객체 추출 모델을 배울 수 있는 값진 경험이 됐습니다.
한편, 아쉬웠던 점은 지금 프로그램이 얼굴의 정면을 기준으로만 패턴을 분석하다 보니, 측면 얼굴 인식률이 낮거나 아예 인식되지 않았습니다.
다음에는 프로젝트를 진행할 때면 기존 정면으로만 패턴을 분석하는 기능을 확장해 측면, 뒷면 인식뿐만 아니라 OpenCV Haar Cascade뿐만 아니라 Dilb, MediaPipe 등의 모델을 적용하고 싶습니다.
그렇게 하여 다양한 각도나 측면에서도 사용자의 ID를 더 정확하게 인식할 수 있는 개인정보 걱정 없는 보안/감시 프로그램을 만들고 싶습니다.