티스토리 뷰
# 졸음 감지: 운전자 안전 시스템 만들기 졸음 감지는 딥러닝으로 운전자 얼굴을 실시간 분석해 눈 상태와 표정을 판단하는 안전 시스템입니다. 교통사고 20% 이상이 졸음운전으로 발생하며, 웹캠이나 차량 카메라로 눈 깜빡임 비율(EAR), PERCLOS(눈 감은 시간 비율)를 계산해 경고합니다. CNN이나 YOLO 모델로 95% 정확도를 달성할 수 있습니다. ## 졸음 판단 기준과 지표 주요 지표는 눈 가로/세로 비율(Eye Aspect Ratio, EAR)입니다. EAR = (|p2-p6| + |p3-p5| + |p1-p4|) / (2 * |p1-p7| + |p4-p8| + |p3-p9|)로 계산하며, 0.25 미만 시 눈 감김으로 판정합니다. PERCLOS는 1분간 눈 감은 프레임 비율로, 30% 초과 시 졸음 경고합니다. 추가로 입 벌림 비율(MAR), 머리 기울기, Yawn 감지를 결합합니다. 데이터셋으로는 NTHU-DDD(얼굴 영상), UTA-RLDD(실제 운전), Kaggle Drowsiness로 학습합니다. 각 이미지를 Alert/Drowsy/Open/No-face로 라벨링하며, 다양한 조명·각도에서 수집합니다. ## 얼굴·눈 검출 기술 Dlib 라이브러리로 68개 랜드마크 검출부터 시작합니다. HOG+SVM으로 얼굴 영역 추출 후, 눈 좌표(왼쪽: 36-42, 오른쪽: 42-48)를 얻습니다. 딥러닝으로는 MediaPipe Face Mesh나 MTCNN으로 더 정확한 랜드마크를 추출합니다. YOLOv8이나 tiny YOLOv3으로 눈·입 객체 감지합니다. 실시간 처리 위해 OpenCV DNN 모듈 사용하며, 프레임당 30fps 유지합니다. 어두운 환경 대응으로 CLAHE 히스토그램 평활화 적용합니다. ## CNN 모델 구현 Keras로 CNN 모델을 구축합니다. 입력 80x80 눈 이미지를 4채널(RGB+Depth)로 처리하며, 구조는 Conv2D(32,3x3)-MaxPool-ReLU 반복 후 Dense로 분류합니다. ```python from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout model = Sequential([ Conv2D(32, (3,3), activation='relu', input_shape=(80,80,1)), MaxPooling2D(2,2), Conv2D(64, (3,3), activation='relu'), MaxPooling2D(2,2), Flatten(), Dropout(0.5), Dense(128, activation='relu'), Dense(2, activation='softmax') # Alert/Drowsy ]) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) ``` 증강(회전·밝기 변화) 후 epoch 50, batch 32로 학습합니다. Adam optimizer(lr=0.001), EarlyStopping으로 과적합 방지합니다. ## 실시간 시스템 구축 OpenCV로 웹캠 캡처 후 얼굴 검출합니다. 연속 3프레임 EAR<0.25 시 카운터 증가, 48프레임(1.6초) 초과하면 경고음과 화면 알림입니다. ```python import cv2 import dlib detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat') cap = cv2.VideoCapture(0) COUNTER = 0 while True: ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = detector(gray) for face in faces: landmarks = predictor(gray, face) # EAR 계산 및 카운터 로직 if EAR < 0.25: COUNTER += 1 if COUNTER >= 48: cv2.putText(frame, "DROWSY!", (50,150), cv2.FONT_HERSHEY_SIMPLEX, 2, (0,0,255), 3) # 소리 재생 else: COUNTER = 0 cv2.imshow('Drowsiness Detection', frame) if cv2.waitKey(1) == ord('q'): break ``` 웹 서비스는 Flask+WebSocket으로 구현, 클라이언트에서 프레임 전송 후 서버 모델 예측합니다. ## 평가와 최적화 Accuracy 97%, F1-score 0.96 목표로 테스트합니다. 혼동 행렬로 false positive 최소화하며, ROC 곡선 AUC 0.98 확인합니다. 경량화 위해 MobileNetV2나 TensorRT 사용, Edge TPU로 실시간 60fps 달성합니다. 한계는 안경·마스크, 야간 환경입니다. 다중 카메라와 IR 센서 결합으로 보완합니다. 실제 차량 적용 시 CAN 버스 연동으로 자동 감속 기능 추가합니다. 이 시스템은 개인 프로젝트부터 상용화까지 확장 가능하며, GitHub 오픈소스로 재현하세요. 안전 운전의 미래를 여는 기술입니다.
