سیستم تشخیص خواب آلودگی راننده با OpenCV و Keras
با این پروژه پایتون، ما یک سیستم تشخیص خواب آلودگی خواهیم ساخت. تعداد بی شماری از مردم شبانه روز در بزرگراه رانندگی می کنند. رانندگان تاکسی، رانندگان اتوبوس، رانندگان کامیون و افرادی که در مسافت های طولانی سفر می کنند از کمبود خواب رنج میبرند. به همین دلیل رانندگی در هنگام احساس خواب آلودگی بسیار خطرناک میشود.
اکثر تصادفات به دلیل خواب آلودگی راننده اتفاق میافتد. بنابراین، برای جلوگیری از این حوادث، سیستمی با استفاده از Python، OpenCV و Keras ایجاد خواهیم کرد که به راننده در صورت احساس خواب آلودگی هشدار میدهد.
سیستم هشدار راننده خواب آلودگی
تشخیص خواب آلودگی یک فناوری ایمنی است که میتواند از تصادفات ناشی از رانندگانی که هنگام رانندگی به خواباند جلوگیری کند.
هدف از این پروژه ساخت یک سیستم تشخیص خواب آلودگی است که تشخیص میدهد چشمان فرد برای چند ثانیه بسته است. این سیستم در صورت تشخیص خواب آلودگی به راننده هشدار میدهد.
سیستم تشخیص خواب آلودگی راننده
در این مطلب، ما از OpenCV برای جمعآوری تصاویر از وبکم استفاده میکنیم و آنها را در یک مدل یادگیری عمیق قرار میدهیم که طبقهبندی میکند که آیا چشمان فرد «باز» یا «بسته» است. روشی که ما برای این پروژه پایتون استفاده خواهیم کرد به شرح زیر است:
مجموعه دادههای تشخیص خواب آلودگی راننده
مجموعه داده استفاده شده برای این مدل توسط ما ایجاد شده است. برای ایجاد مجموعه داده، ما یک اسکریپت نوشتیم که چشمها را از دوربین گرفته و در دیسک محلی ذخیره می کند. ما آنها را به برچسب های مربوطه خود “باز” یا “بسته” جدا کردیم. داده ها شامل حدود 7000 تصویر از چشمان افراد در شرایط نوری مختلف است. پس از آموزش مدل بر روی مجموعه داده خود، وزن نهایی و فایل معماری مدل “models/cnnCat2.h5” را پیوست کرده ایم.
اکنون میتوانید از این مدل برای طبقه بندی باز یا بسته بودن چشم افراد استفاده کنید.
از طرف دیگر، اگر میخواهید مدل خود را بسازید و آموزش دهید، میتوانید مجموعه داده را دانلود کنید: Driver Drowsiness Dataset
معماری مدل
مدلی که ما استفاده کردیم با Keras با استفاده از شبکه های عصبی کانولوشن (CNN) ساخته شده است. شبکه عصبی کانولوشنال نوع خاصی از شبکه عصبی عمیق است که برای اهداف طبقه بندی تصاویر بسیار خوب عمل میکند. یک CNN اساساً شامل یک لایه ورودی، یک لایه خروجی و یک لایه پنهان است که میتواند چندین لایه داشته باشد. با استفاده از فیلتری که ضرب ماتریس دوبعدی را بر روی لایه و فیلتر انجام میدهد، عملیات کانولوشن روی این لایه ها انجام می شود.
معماری مدل CNN از لایه های زیر تشکیل شده است:
- دو لایه کانولوشنال؛ 32 نود، اندازه هسته 3
- یک لایه کانولوشنال؛ 64 نود، اندازه هسته 33
- لایه کاملا متصل؛ 128 نود
لایه نهایی نیز یک لایه کاملا متصل با 2 نود است. یک تابع فعال سازی Relu در تمام لایهها به جز لایه خروجی که در آن از Softmax استفاده میشود.
پیش نیازهای پروژه
لازمه این پروژه پایتون یک وب کم است که از طریق آن تصاویر را می گیریم. شما باید پایتون را روی سیستم خود نصب کرده باشید.سپس با استفاده از pip می توانید بسته های لازم را نصب کنید.
- OpenCV – pip install opencv-python (face and eye detection)
- TensorFlow – pip install tensorflow (keras uses TensorFlow as backend)
- Keras – pip install keras (to build our classification model)
- Pygame – pip install pygame (to play alarm sound)
مراحل انجام تشخیص خوابآلودگی راننده
کد منبع پروژه سیستم تشخیص خواب آلودگی راننده را از فایل فشرده دانلود کنید و فایل های موجود در سیستم خود را استخراج کنید.Driver Drowsiness Project Code
محتویات فایل عبارتند از:
“haar cascade files” شامل فایلهای xml است که برای شناسایی اشیاء از تصویر مورد نیاز است.
پوشه مدل ها حاوی فایل مدل ما “cnnCat2.h5” است که بر روی شبکه های عصبی کانولوشن آموزش داده شده است.
ما یک کلیپ صوتی “alarm.wav” داریم که زمانی پخش می شود که فرد احساس خواب آلودگی می کند.
فایل “Model.py” حاوی برنامه ای است که از طریق آن مدل طبقه بندی خود را با آموزش بر روی مجموعه داده خود ساخته ایم. پیاده سازی شبکه عصبی کانولوشنال را در این فایل مشاهده می کنید.
“Drowsiness detection.py” فایل اصلی پروژه ما است. برای شروع مراحل تشخیص، باید این فایل را اجرا کنیم.
حالا بیایید بفهمیم که الگوریتم ما چگونه گام به گام کار می کند.
مرحله 1 – تصویر را به عنوان ورودی از دوربین بگیرید.
با یک وب کم، تصاویر را به عنوان ورودی می گیریم. بنابراین برای دسترسی به وبکم، یک حلقه بینهایت ایجاد کردیم که هر فریم را میگیرد. از روش ارائه شده توسط OpenCV، cv2.VideoCapture(0) برای دسترسی به دوربین و تنظیم شیء ضبط (cap) استفاده می کنیم. ()cap.read هر فریم را می خواند و تصویر را در یک متغیر فریم ذخیره می کنیم.
مرحله 2 – تشخیص چهره در تصویر و ایجاد منطقه مورد نظر(ROI)
برای تشخیص چهره در تصویر، ابتدا باید تصویر را به مقیاس خاکستری تبدیل کنیم زیرا الگوریتم OpenCV برای تشخیص اشیا تصاویر خاکستری را در ورودی می گیرد. سپس از طبقهبندی کننده آبشاری haar برای شناسایی چهرهها استفاده خواهیم کرد. این خط برای تنظیم face classifier = cv2.CascadeClassifier («مسیر به فایل xml haar cascade ») استفاده میشود. در ادامه تشخیص را با استفاده از faces = face.detectMultiScale (خاکستری) انجام میدهیم. آرایه ای از تشخیص ها را با مختصات x،y و ارتفاع، عرض جعبه مرزی جسم برمی گرداند. اکنون میتوانیم روی چهرهها تکرار کنیم و کادرهای مرزی را برای هر چهره ترسیم کنیم.
for (x,y,w,h) in faces: cv2.rectangle(frame, (x,y), (x+w, y+h), (100,100,100), 1 )
مرحله 3 – چشمها را از ROI تشخیص دهید و آن را به طبقه بندی کننده بدهید
از همین روش تشخیص چهره برای تشخیص چشم استفاده می شود. ابتدا طبقهبندی کننده آبشاری را برای چشمها تنظیم میکنیم و سپس با استفاده از left_eye = leye.detectMultiScale (خاکستری) چشمها را تشخیص میدهیم. اکنون باید فقط داده های چشم را از تصویر کامل استخراج کنیم. این را می توان با استخراج جعبه مرزی چشم به دست آورد و سپس با این کد می توانیم تصویر چشم را از کادر بیرون بکشیم.
l_eye = frame[ y : y+h, x : x+w ]
l_eye فقط حاوی داده های تصویری چشم است. این به طبقهبندیکننده CNN ما وارد میشود که باز یا بسته بودن چشمها را پیشبینی میکند. به طور مشابه، چشم راست را در r_eye استخراج خواهیم کرد.
مرحله 4 – طبقهبند باز یا بسته بودن چشم ها را دسته بندی می کند
ما از طبقه بندی کننده CNN برای پیش بینی وضعیت چشم استفاده می کنیم. برای وارد کردن تصویر به مدل، باید عملیات خاصی را انجام دهیم زیرا مدل برای شروع به ابعاد صحیح نیاز دارد.
ابتدا تصویر رنگی را با استفاده از r_eye = cv2.cvtColor(r_eye, cv2.COLOR_BGR2GRAY) به مقیاس خاکستری تبدیل می کنیم. سپس، همانطور که مدل ما بر روی تصاویر 24*24 پیکسل cv2.resize(r_eye, (24،24)) آموزش داده شد، تصویر را به 24*24 پیکسل تغییر می دهیم. ما داده های خود را برای همگرایی بهتر نرمال می کنیم r_eye = r_eye/255 (همه مقادیر بین 0-1 خواهد بود). ابعاد را گسترش دهید تا به طبقهبندیکننده ما وارد شود. ما مدل خود را با استفاده از model = load_model (‘models/cnnCat2.h5’) بارگذاری کردیم. اکنون هر چشم را با مدل خود lpred = model.predict_classes(l_eye) پیش بینی می کنیم. اگر مقدار lpred[0] = 1، نشان می دهد که چشم ها باز هستند، اگر مقدار lpred[0] = 0، بیان می کند که چشم ها بسته هستند.
مرحله 5 – برای بررسی اینکه آیا فرد خواب آلود است یا خیر، score را محاسبه کنید
scoreاساساً مقداری است که ما از آن برای تعیین مدت زمانی که فرد چشمان خود را بسته است استفاده می کنیم. بنابراین اگر هر دو چشم بسته باشند، به افزایش امتیاز ادامه میدهیم و وقتی چشمها باز است، امتیاز را کاهش میدهیم. ما نتیجه را روی صفحه با استفاده از تابع ()cv2.putText ترسیم می کنیم که وضعیت واقعی شخص را نمایش می دهد.
cv2.putText(frame, “Open”, (10, height-20), font, 1, (255,255,255), 1, cv2.LINE_AA )
یک آستانه تعریف می شود به عنوان مثال اگر نمره بیشتر از 15 شود به این معنی که چشمان فرد برای مدت طولانی بسته است. این زمانی است که با استفاده از sound.play () زنگ هشدار را به صدا در می آوریم.
کد منبع فایل اصلی ما به شکل زیر است:
import cv2 import os from keras.models import load_model import numpy as np from pygame import mixer import time mixer.init() sound = mixer.Sound('alarm.wav') face = cv2.CascadeClassifier('haar cascade files\haarcascade_frontalface_alt.xml') leye = cv2.CascadeClassifier('haar cascade files\haarcascade_lefteye_2splits.xml') reye = cv2.CascadeClassifier('haar cascade files\haarcascade_righteye_2splits.xml') lbl=['Close','Open'] model = load_model('models/cnncat2.h5') path = os.getcwd() cap = cv2.VideoCapture(0) font = cv2.FONT_HERSHEY_COMPLEX_SMALL count=0 score=0 thicc=2 rpred=[99] lpred=[99] while(True): ret, frame = cap.read() height,width = frame.shape[:2] gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face.detectMultiScale(gray,minNeighbors=5,scaleFactor=1.1,minSize=(25,25)) left_eye = leye.detectMultiScale(gray) right_eye = reye.detectMultiScale(gray) cv2.rectangle(frame, (0,height-50) , (200,height) , (0,0,0) , thickness=cv2.FILLED ) for (x,y,w,h) in faces: cv2.rectangle(frame, (x,y) , (x+w,y+h) , (100,100,100) , 1 ) for (x,y,w,h) in right_eye: r_eye=frame[y:y+h,x:x+w] count=count+1 r_eye = cv2.cvtColor(r_eye,cv2.COLOR_BGR2GRAY) r_eye = cv2.resize(r_eye,(24,24)) r_eye= r_eye/255 r_eye= r_eye.reshape(24,24,-1) r_eye = np.expand_dims(r_eye,axis=0) rpred = model.predict_classes(r_eye) if(rpred[0]==1): lbl='Open' if(rpred[0]==0): lbl='Closed' break for (x,y,w,h) in left_eye: l_eye=frame[y:y+h,x:x+w] count=count+1 l_eye = cv2.cvtColor(l_eye,cv2.COLOR_BGR2GRAY) l_eye = cv2.resize(l_eye,(24,24)) l_eye= l_eye/255 l_eye=l_eye.reshape(24,24,-1) l_eye = np.expand_dims(l_eye,axis=0) lpred = model.predict_classes(l_eye) if(lpred[0]==1): lbl='Open' if(lpred[0]==0): lbl='Closed' break if(rpred[0]==0 and lpred[0]==0): score=score+1 cv2.putText(frame,"Closed",(10,height-20), font, 1,(255,255,255),1,cv2.LINE_AA) # if(rpred[0]==1 or lpred[0]==1): else: score=score-1 cv2.putText(frame,"Open",(10,height-20), font, 1,(255,255,255),1,cv2.LINE_AA) if(score<0): score=0 cv2.putText(frame,'Score:'+str(score),(100,height-20), font, 1,(255,255,255),1,cv2.LINE_AA) if(score>15): #person is feeling sleepy so we beep the alarm cv2.imwrite(os.path.join(path,'image.jpg'),frame) try: sound.play() except: # isplaying = False pass if(thicc<16): thicc= thicc+2 else: thicc=thicc-2 if(thicc<2): thicc=2 cv2.rectangle(frame,(0,0),(width,height),(0,0,255),thicc) cv2.imshow('frame',frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
اجرای تشخیص خواب آلودگی راننده
بیایید سیستم تشخیص خواب آلودگی درایو را اجرا کنیم و کار پروژه خود را ببینیم. برای شروع پروژه، باید یک خط فرمان باز کنید، به دایرکتوری بروید که فایل اصلی ما “Drowsiness detection.py” وجود دارد. اسکریپت را با این دستور اجرا کنید.
python “drowsiness detection.py”
ممکن است چند ثانیه طول بکشد تا وب کم باز شود و شناسایی شروع شود.
نمونه اسکرین شات:
اسکرین شات خروجی:
خلاصه
در این پروژه پایتون، ما یک سیستم هشدار راننده خوابآلود ساختهایم که میتوانید به روشهای متعددی آن را پیادهسازی کنید. ما از OpenCV برای تشخیص چهره ها و چشم ها با استفاده از طبقه بندی کننده آبشاری haar استفاده کردیم و سپس از یک مدل CNN برای پیش بینی وضعیت استفاده کردیم.
دیدگاهتان را بنویسید