EAR(Eye Aspect Ratio) 알고리즘은 눈의 비율을 이용해 눈 감김을 확인합니다.
def calculate_EAR(eye): # 눈 거리 계산
A = distance.euclidean(eye[1], eye[5])
B = distance.euclidean(eye[2], eye[4])
C = distance.euclidean(eye[0], eye[3])
ear_aspect_ratio = (A+B)/(2.0*C)
return ear_aspect_ratio
EAR 계산
for n in range(36,42): # 오른쪽 눈 감지
x = face_landmarks.part(n).x
y = face_landmarks.part(n).y
leftEye.append((x,y))
next_point = n+1
if n == 41:
next_point = 36
x2 = face_landmarks.part(next_point).x
y2 = face_landmarks.part(next_point).y
cv2.line(frame,(x,y),(x2,y2),(0,255,0),1)
for n in range(42,48): # 왼쪽 눈 감지
x = face_landmarks.part(n).x
y = face_landmarks.part(n).y
rightEye.append((x,y))
next_point = n+1
if n == 47:
next_point = 42
x2 = face_landmarks.part(next_point).x
y2 = face_landmarks.part(next_point).y
cv2.line(frame,(x,y),(x2,y2),(0,255,0),1)
눈의 랜드마크 좌표들을 얻어내는 부분입니다.
최종 코드
import cv2
import dlib
from functools import wraps
from scipy.spatial import distance
import RPi.GPIO as GPIO
import time
def calculate_EAR(eye): # 눈 거리 계산
A = distance.euclidean(eye[1], eye[5])
B = distance.euclidean(eye[2], eye[4])
C = distance.euclidean(eye[0], eye[3])
ear_aspect_ratio = (A+B)/(2.0*C)
return ear_aspect_ratio
# 카메라 셋팅
cap = cv2.VideoCapture(0)
cap.set(3, 640)
cap.set(4, 480)
# dlib 인식 모델 정의
hog_face_detector = dlib.get_frontal_face_detector()
dlib_facelandmark = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
# gpio 셋팅
lastsave = 0
output_pin = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(output_pin, GPIO.OUT, initial = GPIO.LOW)
def counter(func):
@wraps(func)
def tmp(*args, **kwargs):
tmp.count += 1
time.sleep(0.05)
global lastsave
if time.time() - lastsave > 5:
lastsave = time.time()
tmp.count = 0
return func(*args, **kwargs)
tmp.count = 0
return tmp
@counter
def close():
cv2.putText(frame,"DROWSY",(20,100), cv2.FONT_HERSHEY_SIMPLEX,3,(0,0,255),4)
def sound():
global curr_value
GPIO.output(output_pin, GPIO.HIGH)
time.sleep(2)
GPIO.output(output_pin, GPIO.LOW)
while True:
_, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = hog_face_detector(gray)
for face in faces:
face_landmarks = dlib_facelandmark(gray, face)
leftEye = []
rightEye = []
for n in range(36,42): # 오른쪽 눈 감지
x = face_landmarks.part(n).x
y = face_landmarks.part(n).y
leftEye.append((x,y))
next_point = n+1
if n == 41:
next_point = 36
x2 = face_landmarks.part(next_point).x
y2 = face_landmarks.part(next_point).y
cv2.line(frame,(x,y),(x2,y2),(0,255,0),1)
for n in range(42,48): # 왼쪽 눈 감지
x = face_landmarks.part(n).x
y = face_landmarks.part(n).y
rightEye.append((x,y))
next_point = n+1
if n == 47:
next_point = 42
x2 = face_landmarks.part(next_point).x
y2 = face_landmarks.part(next_point).y
cv2.line(frame,(x,y),(x2,y2),(0,255,0),1)
left_ear = calculate_EAR(leftEye)
right_ear = calculate_EAR(rightEye)
EAR = (left_ear+right_ear)/2
EAR = round(EAR,2)
if EAR<0.19:
close()
print(f'close count : {close.count}')
if close.count == 15:
print("Driver is sleeping")
sound()
print(EAR)
cv2.imshow("Are you Sleepy", frame)
key = cv2.waitKey(30)
if key == 27:
break
cap.release()
cv2.destroyAllWindows()
저의 경우 임베디드 보드에 buzzer를 연결하여 경고음이 울리게 했습니다.
shape_predictor_68_face_landmarks.dat파일은 위의 링크에서 다운로드하여 사용하시면 됩니다.
'OpenCV-Python' 카테고리의 다른 글
OpenCV Python 원하는 이미지 영역 잘라내기(붙이기) (0) | 2021.11.27 |
---|---|
OpenCV Python 얼굴 검출(dlib) (0) | 2021.09.14 |
OpenCV Python 히스토그램 역투영 (0) | 2021.09.01 |
OpenCV Python 색상 영역 검출 (0) | 2021.08.31 |
OpenCV Python 히스토그램 평활화 (0) | 2021.08.30 |