اكتشاف تعبير الوجه باستخدام كيراس Facial Expression Recognition using Keras

التدقيق العلمي: د. دانيا صغير، م. رامي عقّاد
التدقيق اللغوي: هبة الله فلّاحة

مقدّمة

تعدّ تعابير الوجه تجليًّا واضحًا عن الحالات النّفسيّة والعاطفيّة، وبها يتمّ بروز الشّخصيّة  ضمن الموقف الّذي يتعرّض له خلال اليوم، إذ تلعب دورًا تفاعليًّا في العلاقات البشريّة. ونتيجةً لتطوّر التّقنيات الحاسوبيّة فإنّ تفاعلات الإنسان بالحاسب أصبحت موضوعًا هامًّا ومن أجل التّواصل الحقيقيّ بين الإنسان والحاسب فعلى الحاسب أن يكون قادرًا على التّفاعل الطّبيعيّ مع الإنسان بنفس الطّريقة الّتي يتفاعل بها الإنسان مع إنسان آخر؛ إذ أنّ قدرة الحواسيب على تعرّف مشاعر الإنسان والاستجابة للحالة العاطفيّة، تساعد على تحسين التّفاعل بين الإنسان والحاسوب. وتتمثّل هذه التّقنية بالخوارزميّة التّالية:

  • تحديد موقع الأشخاص في الصّورة.
  • اكتشاف الوجه داخل الصّورة والتعرّف عليه.
  • اكتشاف السّمات الخاصّة بكلّ وجه، مثلًا أن يحتوي على العينين والحاجبين والفم.
  • تحديد أو تصنيف التّعبير العاطفيّ للشّخص.

سنقوم في هذه  المقالة باستخدام شَبَكَات الطَّيّ العُصبونيَّة CNN (Convolutional Neural Network) في مكتبة كيراس Keras للتعرّف على تعبير الوجه.

 

استخدامات تقنيّة التّعرّف على تعابير الوجه

  • التّعليم

تؤثّر المودّة على حالة التّعلم لدى المتعلّمين، فباستخدام تقنيّة التعرّف على تعابير الوجه؛ يمكن للحواسيب أن تحكم على حالة المتعلّمين من خلال التّعرّف على تعابير وجوههم.

في التعليم، يمكن للمدرّس استخدام نتيجة التحليل لفهم تعلم الطالب وقدرته على القبول، ثم صياغة خطط تدريس معقولة. في الوقت نفسه، يمكنهم الاهتمام بمشاعر الطلاب الداخلية، مما يساعد على صحة الطلاب الفسيولوجية، خاصة في التعليم عن بعد.

  • الرّعاية الصّحيّة

 تستفيد الروبوتات الاجتماعية، بالإضافة إلى عدد متزايد من الروبوتات المستخدمة في الرعاية الصحية من الوعي العاطفي لأنه يمكنهم الحكم بشكل أفضل على الحالات العاطفية للمستخدمين والمرضى وتغيير استجابتهم بشكل مناسب، وهذا مهم بشكل خاص في تلك البلدان ذات النمو السكاني المتزايد ، كما يتم تطبيق الحوسبة العاطفية لتطوير تقنيات التواصل لاستخدامها من المصابين بالتوحد.

  • أنظمة الأمان

تتركز التطبيقات المحتملة الأخرى حول المراقبة الاجتماعية، على سبيل المثال، يمكن للسيارة مراقبة انفعال جميع الركاب والانخراط في تدابير أمان إضافية.

وتُستخدم هذه التّقنية مثلا من قبل المدارس والمؤسّسات الأخرى؛ لأنّه يمكن أن تساعد في منع العنف وتحسين الأمن العامّ في المكان.

  • التّسويق الإلكترونيّ

تُستخدم هذه التّقنية في تتبّع ردود فعل المستخدمين لأحد المنتجات في أثناء مشاهدتهم للإعلانات ومقاطع الفيديو، حيث يتمّ تعديل الفيديو بعد ملاحظة ردود فعل النّاس تجاه المنتج.

  • خدمة العملاء

يتمّ استخدام هذه التّقنية في مراكز خدمة العملاء مع كاميرات مجهّزة بالذّكاء الصّنعي؛ هذه الكاميرات تقارن عواطف النّاس عند دخولهم ومغادرتهم المبنى لتحديد مستوى رضاهم.

  • التّوظيف

هناك شركات تستخدم هذه التّقنيّة للتّعرف على المشاعر كمساعدين للموارد البشريّة؛ إذ أنّها تفيد في تحديد ما إذا كان المرشّح صادقًا ومهتمًا حقًا بالمنصب من خلال تقييم تعبيرات الوجه.

  • مشاركة الجمهور

تستخدم الشركات أيضًا هذه التّقنية لتحديد نتائج أعمالها من حيث استجابات الجمهور العاطفيّة. 

تُستخدم أيضاً في تحليل تعابير وجوه الشّخصيات المهمّة مثل الفنّانين أو المسؤولين.

ما هي مكتبة كيراس Keras؟

كيراس هي مكتبة بناء وتطوير الشبكات العصبونية  وهي مفتوحة المصدر وتعدّ من أقوى المكتبات المكتوبة في بايثون Python وتستند إلى تنسور فلو Tensorflow وثيانو Theano، تُستخدم لتطوير وتقييم نماذج التّعلم العميق.

ميّزات مكتبة كيراس Keras:

  • تدعم مكتبة كيراس الشَّبَكَاتُ العُصبُونِيَّةُ الإرجاعِيَّةُ RNN  وشبكات الطيّ العصبونيّة CNN.
  • تدعم مكتبة كيراس وحدة المعالجة المركزيّة CPU ووحدة المعالجة الرّسومية  GPU.
  • تحتوي مكتبة كيراس على نماذج جاهزة للعديد من المكوّنات الأساسيّة المستخدمة في بناء الشّبكات العصبونيّة مثل دوال الهدف، دوال التّنشيط، خوارزميات  التّحسين، ومجموعة من الأدوات لجعل العمل مع بيانات النّصوص والصّور أسهل؛ لتبسيط ما يلزم من كتابة الأكواد المطلوبة لبناء شبكة عصبونية  عميقة.
  • كيراس هي واجهة برمجة تطبيقات بسيطة ومنسّقة وقابلة للتّوسع.
  • تشتهر كيراس بقابليّتها الحسابيّة العالية جدًّا.

المبدأ العامّ لعمل خوارزميّة التّعرّف على تعابير الوجه

سيتمّ التّعرّف على عدّة أنواع من التّعابير(العواطف) مثل: التّغيّر الطّبيعيّ – السّعادة – الحزن – التّفاجؤ – الغضب – الخوف – والاشمئزاز، بحيث يمكن تصنيف هذه المشاعر على أنّها مشاعر إيجابيّة ومشاعر سلبيّة، بحيث أنّ الخوف والغضب والحزن هي مشاعر سلبيّة ومعظم البشر لا يحبّونها، بينما السّعادة هي عاطفة إيجابيّة والجميع يرغب بها، على سبيل المثال؛ عندما يكون الشّخص غاضبًا يمكن أن يؤذي الآخرين بشكل مقصود، وبهذا نقول إنّ عاطفة الغضب من أكثر العواطف خطورة وفي الشّكل (1) نوضّح أشكال البشر في الحالات العاطفيّة الّتي ذكرناها.

الشّكل 1. أنواع العواطف المستخدمة من أجل التّعرّف على تعبير الوجه

تتضمّن تقنية التّعرّف على تعبير الوجه FER Facial Expressions Recognition عدّة مراحل أساسيّة كما هو واضح  بالشّكل (2):

  1. المعالجة المسبقة لصورة الوجه (Preprocessing).
  2. تحديد مكان الوجه (Face Detection)
  3. استخراج سّمات الوجه (Feature Extraction).
  4. تصنيف التّعبير العاطفيّ (Classification).
الشّكل 2. مخطّط مراحل عمل التّعرّف على تعابير الوجه Facial Expression Regression

التّطبيق العمليّ

  1. المعالجة المسبقة لصورة الوجه (Preprocessing)

وتعتبر هذه المرحلة مهمّة جدًّا من أجل تحسين أداء تقنيّة التّعرف على الوجه؛ حيث تتضمّن العديد من العمليّات مثل وضوح الصّورة وقياسها وتعديل التّباين وعمليّات تحسين أخرى، حيث غالبًا ما تكون البيانات غير كاملة وتفتقر إلى سمات معيّنة قد تهمّنا، أوغير منسقة، أو تحتوي العديد من الأخطاء.

  1. تحديد مكان الوجه (Face Detection)

إنّ مهمّة الكشف عن الوجه أصبحت من المهامّ المطلوبة بشكل كبير في كثير من التّطبيقات، بحيث استخدمت في مجال الأنظمة الأمنيّة والكثير من التّطبيقات، حيث يتمّ في هذه المرحلة تحويل الصّورة الملوّنة إلى صورة رماديّة؛ لأنّ الصّورة الملوّنة تتكوّن من ثلاث مركبات RGB، وبالتّالي اكتشاف الوجه في صورة ملوّنة يصبح أكثر تعقيدًا ويأخذ زمنًا أكبر مقارنةً مع الصّورة الرماديّة الّتي تتكوّن من مركبة واحدة، لذلك نقوم بتحويل الصّور إلى صور رماديّة.

 

الشّكل 3. الصّورة المراد استخدامها في تطبيق خوارزميّة التّعرّف على تعابير الوجه

ومن أجل تحديد أماكن الوجه في الصّورة، يتمّ تدريب الحاسوب على عدد كبير من الصّور بحيث تحتوي فقط معالم الوجه الرئيسيّة مثل العين – الحاجب – الفم – الأنف. بعد تكرار عمليّة التّدريب على آلاف الصّور يصبح الحاسوب قادرًا على تحديد أماكن الوجه كما موضّح في الشّكل (4).

الشّكل 4. تحديد مكان الوجه في الصّورة المدخلة
  1. استخراج سمات الوجه (Feature Extraction)

في هذه المرحلة يتمّ استخراج الميّزات من الوجه لتصنيف التّعبير، حيث تتواجد هذه السّمات في الحاجب – الحافة الخارجيّة للعين – الحافة الدّاخليّة للعين – حول الفم – حول الأنف، ويتمّ إيجاد هذه السّمات من خلال تدريب شبكة الطّيّ العصبونيّة كما هو موضّح بالشّكل (5).

الشّكل 5. تحديد السّمات في الوجه
  1. تصنيف التّعبير العاطفيّ (Classification)

إنّ المرحلة الأخيرة من نظام التّعرّف على تعبير الوجه يكون من خلال تحليل تعابير الوجه؛ وهي مرحلة التّصنيف بحيث يتمّ تدريب الشّبكة على مجموعة من الصّور لتصنيف الحالة العاطفيّة للوجه إلى تعبير معيّن كما هو موضّح في الشّكل (6).

الشّكل 6. النّاتج النّهائيّ لتطبيق خوارزميّة التّعرّف على تعبير الوجه

التّطبيق العمليّ

في مشروعنا هذا تمّ استخدام مجموعة البيانات Fer2013 من كاجل Kaggle فمن أجل بناء نموذج يقوم بالتّعرّف على تعبير الوجه، لابدّ من تضمين هذا النّموذج بصور تحتوي على وجوه هؤلاء الأشخاص بالإضافة إلى تعبير كلّ وجه، وبالتّالي تمّ استخدام قاعدة البيانات Fer 2013 الّتي تحتوي على 30000 صورة وجه لتعابير مختلفة، حيث تحتوي على 7 أنواع من التّعابير (الخوف – الاشمئزاز – الحزن – التّفاجؤ – الغضب – السّعادة – التّعبير الطّبيعيّ)، بالتّالي يحتوي مجلد قاعدة البيانات على عدّة مجلّدات فرعيّة وكلّ مجلّد يسمّى بالتّعبير العاطفيّ للوجه، ويتمّ الحصول على قاعدة البيانات من خلال المصدر [1].

الآن بعد أن ألقينا نظرة عامّة عن عمل الخوارزميّة وقاعدة البيانات المستخدمة، سنقوم بتنفيذ هذه الخطوات باستخدام لغة البرمجة بايثون.

 في البداية سنقوم بتثبيت المكتبات والتّوابع التي سنتعامل معها:

 

pip install tensorflow
pip install keras
pip install numpy
pip install sklearn
pip install pandas
pip install opencv-python

الطريقة الأولى:

إذا كنت لا ترغب في تدريب المصنف من نقطة الصفر يمكنك الاستفادة من هذا التطبيق بشكل مباشر من خلال fer.jason وهو (نموذج مدرب) وfer.h5 (أوزان مدربة) حيث يمكن استخدامها للتنبؤ بالعواطف على أي صورة اختبار موجودة في المجلد.

الطّريقة الثّانية:

البناء من الصّفر ويكون وفق الخطوات التّالية:

الخطوة الأولى: سنقوم بتنفيذ ملفّ Preprocessing.py المسؤول عن المعالجة المسبقة للصّور.

import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings("ignore")
data = pd.read_csv('./fer2013.csv')
width, height = 48, 48
datapoints = data['pixels'].tolist()
#الحصول على ميزات التدريب
 X = []
for xseq in datapoints:	
xx = [int(xp) for xp in xseq.split('  ')]
xx = np.asarray(xx).reshape(width, height)
X.append(xx.astype('float32'))
X = np.asarray(X)
X = np.expand_dims(X, -1)
#الحصول على الخرج المتوقع للتدريب
y = pd.get_dummies(data['emotion']).as_matrix() 
np.save('fdataX', X)
np.save('flabels', y)
print("Preprocessing Done")
print("Number of Features: "+str(len(X[0])))
print("Number of Labels: "+ str(len(y[0])))
print("Number of examples in dataset:"+str(len(X)))
print("X,y stored in fdataX.npy and flabels.npy respectively")

تمثل الأسطر من 1 – 5 استيراد المكتبات وقراءة ملف fer2013.csv الذي يحتوي على ميزات التدريب X والخرج المتوقع(labels Y).

تمثل الأسطر من 7 – 25 الحصول على ميزات التدريب X والخرج المتوقع Y من وحدات البكسل وأعمدة التعبير العاطفي في ملف csv وتحويلها إلى مصفوفات. 

الخطوة الثّانية: سنقوم بتنفيذ ملفّ fertrain.py حيث أنّ هذا الملفّ مسؤول عن بناء شبكات الطّيّ العصبونيّة.

import sys, os
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D, BatchNormalization
from keras.losses import categorical_crossentropy
from keras.optimizers import Adam
from keras.regularizers import l2
from keras.callbacks import ReduceLROnPlateau, TensorBoard, EarlyStopping, ModelCheckpoint
from keras.models import load_model
from keras.models import model_from_ json

تمثل الأسطر 1 -13 استيراد الأصناف والتوابع المطلوبة لبناء شبكة CNN من مكتبة Keras.

num_features = 64.
num_labels = 7
batch_size = 64
epochs = 100
width, height = 48, 48
x = np.load('./fdataX.npy')
y = np.load('./flabels.npy')
x -= np.mean(x, axis=0)
x /= np.std(x, axis=0)

تمثل الأسطر السابقة تهيئة المتغيرات التي سوف نحتاجها لتدريب شَبَكَات الطَّيِّ العُصبُونِيَّة CNN حيث قمنا بتهيئة العرض والارتفاع للصورة (48 * 48) وأيضاً قمنا بتهيئة عدد حالات التعبير العاطفية التي سوف نتنبأ بها وهي 7 تعابير (الخوف، الغضب، الاشمئزاز، السعادة، الحزن، التفاجؤ، الشعور الطبيعي) ومن ثم قمنا بتحميل الميزات إلى X والخرج المتوقع labels إلى Y.

 

#   for xx in range(10):
#    plt.figure(xx)
#    plt.imshow(x[xx].reshape((48, 48)), interpolation='none', cmap='gray')
#    plt.show()
#   تقسيم البيانات إلى عينات تدريب وعينات اختبار
X_train, X_test, y_train, y_test=train_test_split(x, y, test_size=0.1, random_state=42)
X_train, X_valid, y_train, y_valid = train_test_split(X_train, y_train, test_size=0.1, random_state=41)

تمثل الأسطر من السابقة تقسيم مجموعة البيانات إلى مجموعة تدريب ومجموعة اختبار باستخدام تابع train_test_spilt () من مكتبة sklearn وحفظ ميزات الاختبار و الخرج المتوقع labels لاستخدامها لاحقاً.

# حفظ عينات التدريب التي ستستخدم لاحقاً
np.save('modXtest', X_test)
np.save('modytest', y_test)
#CNN تصميم شبكة 
model = Sequential()
   
model.add(Conv2D(num_features, kernel_size=(3, 3), activation='relu', input_shape=(width, height, 1), data_format='channels_last', kernel_regularizer=l2(0.01)))
model.add(Conv2D(num_features, kernel_size=(3, 3), activation='relu', padding='same'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Dropout(0.5))
   
model.add(Conv2D(2*num_features, kernel_size=(3, 3), activation='relu', padding='same'))
model.add(BatchNormalization())
model.add(Conv2D(2*num_features, kernel_size=(3, 3), activation='relu', padding='same'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Dropout(0.5))
  
model.add(Conv2D(2*2*num_features, kernel_size=(3, 3), activation='relu', padding='same'))
model.add(BatchNormalization())
model.add(Conv2D(2*2*num_features, kernel_size=(3, 3), activation='relu', padding='same'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Dropout(0.5))
  
model.add(Conv2D(2*2*2*num_features, kernel_size=(3, 3), activation='relu', padding='same'))
model.add(BatchNormalization())
model.add(Conv2D(2*2*2*num_features, kernel_size=(3, 3), activation='relu', padding='same'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Dropout(0.5))
   
model.add(Flatten())

عند بناء شَبَكَات الطَّيِّ العُصبُونِيَّة CNN ننشئ نموذج instance  من الصنف التسلسلي Sequential  الذي يستخدم لبناء الشبكة.

تمثل الأسطر من 7– 11 بناء أول مجموعة من الطبقات.

تمثل الأسطر من 13– 19 بناء ثاني مجموعة من الطبقات .

تمثل الأسطر من 21– 26 بناء ثالث مجموعة من الطبقات.

تمثل الأسطر من 28– 33 بناء رابع مجموعة من الطبقات.

في السطر 35 نأخذ خرج التجمِيع وفقَ القيمةِ الكُبرى Max Pooling السابقة ونسطحه إلى شعاع واحد مما يسمح لنا بتطبيق الطبقات الكثيفة كاملة الاتصال والتي تعتبر إحدى طبقات الشبكات العصبونية العميقة حيث يتصل كل عصبون في الطبقة السابقة مع جميع عصبونات الطبقة التالية.

model.add(Dense(2*2*2*num_features, activation='relu'))
model.add(Dropout(0.4))
model.add(Dense(2*2*num_features, activation='relu'))
model.add(Dropout(0.4))
model.add(Dense(2*num_features, activation='relu'))
model.add(Dropout(0.5))
  
model.add(Dense(num_labels, activation='softmax'))
    
# model.summary()
# Compliling the model with adam optimixer and categorical crossentropy loss
model.compile(loss=categorical_crossentropy,
  	optimizer=Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-7),
   	metrics=['accuracy'])
# نموذج التدريب
model.fit(np.array(X_train), np.array(y_train),
                 batch_size=batch_size,
                 epochs=epochs,
                 verbose=1,
                 validation_data=(np.array(X_valid), np.array(y_valid)),
                  shuffle=True)
# حفظ نموذج التدريب  للاستخدام لاحقاً
fer_json = model.to_json()
with open("fer.json", "w") as json_file:
           json_file.write(fer_json)
           model.save_weights("fer.h5")
           print("Saved model to disk")

 تمثل الأسطر من 1– 6 بناء خامس مجموعة من الطبقات.

يُعرف السطر 8 صنف آخر من الطَّبَقة الكثيفة Dense حيث يقبل الحجم كمتغير num_labels هذا الحجم عبارة عن عدد الأصناف والتي يكون عددها في حالتنا هي 7 أصناف.

وأخيراً نضيف التابع الانحدار اللوجستي متعدد الحدود multinomial logistic regression SoftMax الذي يعيد قائمة من الاحتمالات، احتمال لكل واحد من الأصناف السبعة  حيث يتم اختيار الصنف ذو قيمة الاحتمال الأكبر كتصنيف نهائي للرقم من الشبكة.

تقييم شَبَكَات الطَّيِّ العُصبُونِيَّة التي تم بناؤها باستخدام بايثون وكيراس:

الشّكل 7. توصلت شَبَكَات الطَّيِّ العُصبُونِيَّة إلى دقة تصنيف 66.66% على بيانات التدريب

الخطوة الثّالثة: سنقوم بتنفيذ ملفّ fertest.py و هو المسؤول عن اختبار النّموذج على بيانات الاختبار التي تمّ حفظها مسبقًا.

 # json تحميل ملف 
from __future__ import division
from keras.models import Sequential
from keras.layers import Dense
from keras.models import model_from_json
import numpy
 import os
import numpy as np
json_file = open('fer.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
# تحميل الأوزان إلى النموذج
loaded_model.load_weights("fer.h5")
print("Loaded model from disk")
truey=[]
predy=[]
x = np.load('./modXtest.npy')
y = np.load('./modytest.npy')
yhat= loaded_model.predict(x)
yh = yhat.tolist()
yt = y.tolist()
 count = 0
for i in range(len(y)):
       yy = max(yh[i])
       yyt = max(yt[i])
       predy.append(yh[i].index(yy))
       truey.append(yt[i].index(yyt))
       if(yh[i].index(yy)== yt[i].index(yyt)):
       count+=1
acc = (count/len(y))*100
 
np.save('truey', truey)
np.save('predy', predy)
print("Predicted and true label values saved")
print("Accuracy on test set :"+str(acc)+"%")

الشّكل 8. توصلت شَبَكَات الطَّيِّ العُصبُونِيَّة إلى دقة تصنيف 66.36% على بيانات الاختبار

الخطوة الرّابعة: سنقوم بتنفيذ ملفّ fertestcustom.py وهو المسؤول عن تصنيف أو تحديد التّعبير العاطفيّ للصّورة المدخلة.

# Json تحميل ملف
from __future__ import division
from tensorflow.keras.models import Sequential
 from tensorflow.keras.layers import Dense
from tensorflow.keras.models import model_from_json
import numpy
import os
import numpy as np
import cv2
# تحميل النموذج
json_file = open('fer.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
# تحميل الأوزان في نموذج جديد
loaded_model.load_weights("fer.h5")
print("Loaded model from disk")
#ضبط بارامترات  تغيير حجم الصورة
WIDTH = 48
HEIGHT = 48
x=None
y=None
labels = ['Angry', 'Disgust', 'Fear', 'Happy', 'Sad', 'Surprise', 'Neutral']
#تحميل الصورة
full_size_image = cv2.imread("test.jpg")
print("Image Loaded")
gray=cv2.cvtColor(full_size_image,cv2.COLOR_RGB2GRAY)
face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
faces = face.detectMultiScale(gray, 1.3  , 10)
#كشف الوجوه
for (x, y, w, h) in faces:
       roi_gray = gray[y:y + h, x:x + w]
       cropped_img = np.expand_dims(np.expand_dims(cv2.resize(roi_gray, (48, 48)), -1), 0)
       cv2.normalize(cropped_img, cropped_img, alpha=0, beta=1, norm_type=cv2.NORM_L2,    
       dtype=cv2.CV_32F)
       cv2.rectangle(full_size_image, (x, y), (x + w, y + h), (0, 255, 0), 1)
#توقع العاطفة
       yhat= loaded_model.predict(cropped_img)
       cv2.putText(full_size_image, labels[int(np.argmax(yhat))], (x, y), cv2.FONT_HERSHEY_SIMPLEX,
       0.8, (0, 255, 0), 1, cv2.LINE_AA)
       print("Emotion: "+labels[int(np.argmax(yhat))])
cv2.imshow('Emotion', full_size_image)
cv2.waitKey()

بعد تنفيذ الخطوات السّابقة نحصل على الخرج النّاتج عن التّطبيق العمليّ  

الشّكل 9. صورة الخرج النّهائيّة بعد تنفيذ التّطبيق العمليّ

عزيزي القارئ يمكنك أيضًا تنفيذ الملفّ Video_fer () وهو المسؤول عن قراءة الإطارات المتدفّقة من الكاميرا، ومن ثمّ القيام بعمليّة معالجة كلّ إطار واكتشاف جميع الوجوه الموجودة فيه، ومن ثمّ استخراج ميّزات الوجه للتّعرّف على الوجه وتحديد التّعبير العاطفيّ للوجه.

#تحميل و إنشاء النموذج
from __future__ import division
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.models import model_from_json
import numpy
import os
import numpy as np
import cv2
#تحميل النموذج
json_file = open('fer.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
# تحميل الأوزان في نموذج جديد
loaded_model.load_weights("fer.h5")
print("Loaded model from disk")
#ضبط بارامترات تغيير حجم الصورة
WIDTH = 48
HEIGHT = 48
x=None
y=None
labels = ['Angry', 'Disgust', 'Fear', 'Happy', 'Sad', 'Surprise', 'Neutral']
# تحميل الفيديو
vid = cv2.VideoCapture(0)
while(True):
          ret, frame = vid.read()
          full_size_image = frame
          print("Image Loaded")
          gray = cv2.cvtColor(full_size_image, cv2.COLOR_RGB2GRAY)
          face = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
          faces = face.detectMultiScale(gray, 1.3, 10)
#كشف الوجوه
 for (x, y, w, h) in faces:
         roi_gray = gray[y:y + h, x:x + w]
         cropped_img = np.expand_dims(np.expand_dims(
         cv2.resize(roi_gray, (48, 48)), -1), 0)
         cv2.normalize(cropped_img, cropped_img, alpha=0, beta=1,
                                  norm_type=cv2.NORM_L2, dtype=cv2.CV_32F)
        cv2.rectangle(full_size_image, (x, y), (x + w, y + h), (0, 255, 0), 1)
# توقع العاطفة
yhat = loaded_model.predict(cropped_img)
print("Emotion: "+labels[int(np.argmax(yhat))])
if cv2.waitKey(1) & 0xFF == ord('q'):
   break
   cv2.imshow('Emotion', full_size_image)
   vid.release()
   cv2.destroyAllWindows()

فيديو يظهر خرج التّطبيق العمليّ

الخاتمة

إنّ تقنيّة التّعرّف على تعابير الوجه حالها حال أيّ تقنيّة لا تخلو من العيوب والتحدّيات، تتمثّل إحدى التّحدّيات في أنّ مجموعات البيانات يتمّ تصنيفها من قبل الأشخاص، ويمكن لأشخاص مختلفين قراءة العواطف وتفسيرها بطرق مختلفة، أي أنّ هذه التّقنية من السّهل خداعها، حيث تربط الحواسيب بعض تعابير الوجه بمشاعر معيّنة لكنّها تفشل في التّمييز على سبيل المثال بين الابتسامة الخبيثة و الابتسامة الأصليّة، لذلك لا ينبغي استخدام هذه التّقنيّة في القرارات التي تؤثّر على حياة الناس وإمكانيّة الوصول إلى الفرص، مثل قرارات التّوظيف لأنّها ليست دقيقة بما فيه الكفاية ويمكن أن تؤدّي إلى قرارات متحيّزة.

المراجع

: اكتشاف تعبير الوجه باستخدام كيراس Facial Expression Recognition using Keras
  1. challenges-in-representation-learning-facial-expression-recognition-challenge
  2. facial-expression-recognition-using-keras
  3. Facial Expression Recognition using Keras

الكاتب

  • رفيف الشاوي

    مهندسة حواسيب من جامعة تشرين، طالبة ماجستير في هندسة الحواسيب في كلية الهندسة الكهربائية والإلكترونية في جامعة حلب. مهتمة بعلوم الذكاء الصنعي، تعلم الآلة، وبشكل خاص الرؤية الحاسوبية، والتعلم العميق

0 Shares:
اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

You May Also Like