تشخیص حالت صورت (احساس چهره) با رزبری پای
محتویات
در این آموزش ، ما می خواهیم یک سیستم تشخیص احساسات (سیستم تشخیص حالت چهره) را بر روی Raspberry Pi 4 پیاده سازی کنیم. از سیستم تشخیص حالت صورت می توان در پروژه های مختلف استفاده کرد. مثلا می تواند برای مطالعه یا تحلیل احساسات انسان مورد استفاده قرار گیرد. بسیاری از شرکت ها برای بررسی سطح افسردگی کارگران خود در حال پیاده سازی سیستم تشخیص حالت چهره هستند. برخی از شرکت های بازی سازی از سیستم تشخیص چهره برای ثبت میزان رضایت بازیکنان در هنگام بازی استفاده می کنند. ما می خواهیم یک سیستم ساده و مفید را روی Raspberry Pi پیاده کنیم تا حالت چهره یک شخص را تشخیص دهیم.
مراحل انجام تشخیص حالت چهره در Raspberry Pi
برای اجرای تشخیص حالت صورت در Raspberry Pi ، باید سه مرحله ذکر شده در زیر را دنبال کنیم.
- مرحله 1: چهره ها را در جریان فیلم ورودی شناسایی کنید.
- مرحله 2: منطقه مورد نظر (ROI) چهره ها را پیدا کنید.
- مرحله 3: برای تشخیص حالت صورت، از مدل تشخیص حالت چهره استفاده کنید.
ما در اینجا از شش کلاس استفاده می کنیم که “عصبانی” ، “ترس” ، “شاد” ، “خنثی” ، “غمگین” ، “سورپرایز” است. بنابراین ، حالت های تشخیص داده شده در یکی از این کلاس ها خواهد بود.
این پروژه سخت افزار زیادی را نیاز دارد و شما فقط به یک رزبری پای و ماژول دوربین نیاز دارید.
نصب OpenCV در Raspberry Pi 4
قبل از نصب OpenCV و سایر وابستگی ها ، Raspberry Pi باید کاملاً به روز شود. از دستورات زیر برای به روزرسانی Raspberry Pi به آخرین نسخه آن استفاده کنید:
sudo apt-get update
سپس از دستورات زیر برای نصب وابستگی های مورد نیاز برای نصب OpenCV در Raspberry Pi خود استفاده کنید.
sudo apt-get install libhdf5-dev -y sudo apt-get install libhdf5-serial-dev –y sudo apt-get install libatlas-base-dev –y sudo apt-get install libjasper-dev -y sudo apt-get install libqtgui4 –y sudo apt-get install libqt4-test –y
پس از آن ، از دستور زیر استفاده کنید تا OpenCV را روی Raspberry Pi خود نصب کنید.
pip3 install opencv-contrib-python==4.1.0.25
نصب Tensorflow و Keras در Raspberry Pi 4
قبل از نصب Tensorflow و Keras ، کتابخانه های ذکر شده زیر را که لازم است نصب کنید.
sudo apt-get install python3-numpy sudo apt-get install libblas-dev sudo apt-get install liblapack-dev sudo apt-get install python3-dev sudo apt-get install libatlas-base-dev sudo apt-get install gfortran sudo apt-get install python3-setuptools sudo apt-get install python3-scipy sudo apt-get update sudo apt-get install python3-h5py
با استفاده از دستور pip (اگر python3 را به عنوان محیط پیش فرض پایتون در raspberry pi خود دارید ، از دستور pip3 استفاده کنید) در ترمینال می توان کتابخانه Tensorflow و Keras را نصب کرد.
pip3 install tensorflow pip3 install keras
برنامه نویسی رزبری پای برای تشخیص حالت صورت
کد کامل پروژه و تمام فایل های مورد نیاز در انتهای صفحه برای دانلود قرار داده شده است. در اینجا ، ما در حال توضیح بخشهای مهم کد برای توضیح بهتر هستیم. پوشه پروژه شامل یک زیر پوشه (Haarcascades) ، یک فایل Python (emotion1.py) و مدل (ferjj.h5) است.
در اینجا قسمت های کد را توضیح میدهیم. در ابتدای کد کتابخانه های مورد نیاز را فراخوانی میکنیم.
توجه: ما از TensorFlow API برای وارد کردن کتابخانه Keras استفاده می کنیم.
from tensorflow.keras import Sequential from tensorflow.keras.models import load_model import cv2 import numpy as np from tensorflow.keras.preprocessing.image import img_to_array
بعد ، بارگیری مدل از پیش آموزش دیده (در پوشه پروژه ارائه شده) تابع load_model() از کتابخانه Keras وارد می شود. در خط بعدی ، یک دیکشنری ایجاد کنید و برچسب ها را به 6 کلاسی که داریم اختصاص دهید.
# ما 6 مدل برچسب برای حالت صورت داریم class_labels = {0: 'Angry', 1: 'Fear', 2: 'Happy', 3: 'Neutral', 4: 'Sad', 5: 'Surprise'} classes = list(class_labels.values()) # print(class_labels)
اکنون ، مسیر طبقه بندی Haarcascade با استفاده از عملکرد CascadeClassifier() از کتابخانه OpenCV فراهم میشود.
face_classifier = cv2.CascadeClassifier('./Haarcascades/haarcascade_frontalface_default.xml')
از تابع text_on_detected_boxes() می تواند برای طراحی برچسب های خروجی چهره های شناسایی شده استفاده شود. پارامترهای text_on_detected_boxes() از قبل دارای مقادیری هستند که میتوانید در صورت نیاز آن ها را تغییر دهید.
# این عملکرد برای طراحی مربع دور چهره استفاده میشود def text_on_detected_boxes(text,text_x,text_y,image,font_scale = 1, font = cv2.FONT_HERSHEY_SIMPLEX, FONT_COLOR = (0, 0, 0), FONT_THICKNESS = 2, rectangle_bgr = (0, 255, 0)):
تست سیستم تشخیص حالت صورت بر روی تصاویر:
در تابع face_detector_image (img) از تابع cvtColor () برای تبدیل تصویر ورودی به مقیاس خاکستری استفاده شده است. همانطور که در زیر مشاهده می کنید ، نمونه عکس گرفته شده در اینجا به مقیاس خاکستری تبدیل می شود.
سپس ناحیه مورد نظر (ROI) چهره ها از تصویر استخراج می شود. این عملکرد سه فاکتور مهم یعنی ROI چهره ها ، مختصات چهره ها و تصویر اصلی را برمی گرداند. یک مستطیل روی صورت شناسایی شده کشیده شده است. کد تبدیل تصویر به مقیاس خاکستری و ترسیم یک جعبه در اطراف ROI ما در زیر نشان داده شده است.
def face_detector_image(img): gray = cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY) # Convert the image into GrayScale image faces = face_classifier.detectMultiScale(gray, 1.3, 5) if faces is (): return (0, 0, 0, 0), np.zeros((48, 48), np.uint8), img allfaces = [] rects = [] for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2) roi_gray = gray[y:y + h, x:x + w] roi_gray = cv2.resize(roi_gray, (48, 48), interpolation=cv2.INTER_AREA) allfaces.append(roi_gray) rects.append((x, w, y, h)) return rects, allfaces, img
در این بخش از برنامه ، مدل با ارائه مقادیر ROI در حال استفاده است. همانطور که در بخش بالا توضیح داده شد ، از دو خط اول زیر تابع برای بدست آوردن تصویر ورودی و انتقال آن به face_detector_image (img) استفاده می شود.
پس از پردازش، نتیجه خروجی با چهره های شناسایی شده نمایش داده می شود. نتیجه خروجی از دیکشنری class_labels که قبلاً ایجاد کرده ایم نمایش داده می شود. ما از تابع text_on_detected_boxes () برای طراحی برچسب ها در چهره های شناسایی شده استفاده می کنیم. از تابع imshow () برای نمایش پنجره استفاده می شود.
def emotionImage(imgPath): img = cv2.imread(imgPath) rects, faces, image = face_detector_image(img) i = 0 for face in faces: roi = face.astype("float") / 255.0 roi = img_to_array(roi) roi = np.expand_dims(roi, axis=0) # make a prediction on the ROI, then lookup the class preds = classifier.predict(roi)[0] label = class_labels[preds.argmax()] label_position = (rects[i][0] + int((rects[i][1] / 2)), abs(rects[i][2] - 10)) i = + 1 # Overlay our detected emotion on the picture text_on_detected_boxes(label, label_position[0],label_position[1], image) cv2.imshow("Emotion Detector", image) cv2.waitKey(0) cv2.destroyAllWindows()
تشخیص حالت صورت در ویدئو دوربین:
از عملکرد face_detector_video (img) برای شناسایی چهره ها در یک جریان ویدیویی استفاده می شود. این عملکرد مختصات چهره های شناسایی شده ، منطقه مورد نظر (ROI) چهره ها و قاب اصلی را برمی گرداند. از تابع rectangle () برای ترسیم یک مستطیل که روی چهره های شناسایی شده همپوشانی دارد استفاده می شود.
def face_detector_video(img): # Convert image to grayscale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale(gray, 1.3, 5) if faces is (): return (0, 0, 0, 0), np.zeros((48, 48), np.uint8), img for (x, y, w, h) in faces: cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), thickness=2) roi_gray = gray[y:y + h, x:x + w] roi_gray = cv2.resize(roi_gray, (48, 48), interpolation=cv2.INTER_AREA) return (x, w, y, h), roi_gray, img
در این بخش ، ما از مدل خود برای شناسایی احساسات صورت در یک جریان ویدیویی استفاده می کنیم و خروجی پیش بینی شده در جریان ویدئو را در زمان واقعی نشان می دهیم.
در دو خط اول ، ما در حال استخراج یک فریم از جریان ویدئویی ورودی هستیم. سپس ، قاب را به عملکرد face_detector_video (قاب) میدهیم. سپس ما بعد از تشخیص حالت چهره، یکی از برچسب ها (کلاس ها) را انتخاب میکنیم. حال ، از imshow () برای نمایش پنجره با عبارت شناسایی شده در هر صورت استفاده می شود.
def emotionVideo(cap): while True: ret, frame = cap.read() rect, face, image = face_detector_video(frame) if np.sum([face]) != 0.0: roi = face.astype("float") / 255.0 roi = img_to_array(roi) roi = np.expand_dims(roi, axis=0) # make a prediction on the ROI, then lookup the class preds = classifier.predict(roi)[0] label = class_labels[preds.argmax()] label_position = (rect[0] + rect[1]//50, rect[2] + rect[3]//50) text_on_detected_boxes(label, label_position[0], label_position[1], image) # You can use this function for your another opencv projects. fps = cap.get(cv2.CAP_PROP_FPS) cv2.putText(image, str(fps),(5, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) else: cv2.putText(image, "No Face Found", (5, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2) cv2.imshow('All', image) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
این عملکرد اصلی کد است. از تابع () emotionVideo و از تابع () emotionImage می توان در عملکرد اصلی استفاده کرد. اگر می خواهید از تشخیص حالت صورت روی تصویر استفاده کنید ، فقط کافی است دو خط اول عملکرد اصلی را به کامنت تغییر دهید و دو خط باقی مانده را از حالت کامنت خارج کنید. اما مطمئن شوید که مسیر تصویر ورودی را در متغیر IMAGE_PATH ارائه می دهید.
if __name__ == '__main__': camera = cv2.VideoCapture(0) # If you are using an USB Camera then Change use 1 instead of 0. emotionVideo(camera) # IMAGE_PATH = "provide the image path" # emotionImage(IMAGE_PATH) # If you are using this on an image please provide the path
آزمایش سیستم تشخیص احساس صورت در رزبری پای
قبل از اجرای اسکریپت پایتون ، ماژول دوربین Raspberry Pi Camera را مانند تصویر زیر به Pi وصل کنید:
اکنون ، بررسی کنید که دوربین Pi کار می کند یا خیر. پس از بررسی دوربین ، اسکریپت پایتون را راه اندازی کنید ، پنجره ای پیدا می کنید که در آن ویدیو دوربین شما ظاهر می شود. هنگامی که Pi احساس را تشخیص داد ، آن را در فید ویدیویی در جعبه رنگ سبز نشان می دهد.
موارد موجود در فایل : سورس کامل
برای دانلود فایل ها باید حساب کاربری داشته باشید
با سلام
آیا در رزبری 3 هم کار میکند
و آیا سرعت و دقت خوبی دارد؟
ممنون
سلام عزیز، با رزبری پای 3 تست نشده، از لحاظ دقت و سرعت در فیلم نمونه مشخص هست
باعرض سلام
لطفا بگویین در کدام رزبری پای کار میکند
سلام عزیز
رزبری پای ۳ و ۴