- مقدمة في اكتشاف قناع الوجه
- عملية اكتشاف قناع الوجه باستخدام التعلم العميق
- تحميل مجموعة البيانات
- إنشاء دوال المساعد
- معالجة البيانات
- شبكة تدريب عصبية لاكتشاف قناع الوجه
- اختبار النموذج
أصبح اكتشاف الوجه مشكلة مثيرة للاهتمام للغاية في معالجة الصور والرؤية الحاسوبية. في هذه المقالة، سأقدم لك مشروع الرؤية الحاسوبية حول اكتشاف قناع الوجه باستخدام التعلم الآلي باستخدام بايثون.
مقدمة في اكتشاف قناع الوجه
يحتوي اكتشاف قناع الوجه Face mask detection على مجموعة من التطبيقات بدءًا من التقاط حركة الوجه وحتى التعرف على الوجه والذي يتطلب في البداية اكتشاف الوجه بدقة جيدة جدًا. يعد اكتشاف الوجه Face detection أكثر أهمية اليوم لأنه لا يستخدم فقط في الصور، ولكن أيضًا في تطبيقات الفيديو مثل المراقبة في الوقت الفعلي واكتشاف الوجه في مقاطع الفيديو.
أصبح تصنيف الصور عالي الدقة ممكنًا الآن مع التقدم في الشبكات العصبية التلافيفية CNN. غالبًا ما تكون المعلومات المتعلقة بمستوى البكسل مطلوبة بعد اكتشاف الوجه، والتي لا توفرها معظم طرق اكتشاف الوجه.
كان الحصول على تفاصيل على مستوى البكسل جزءًا صعبًا من التجزئة الدلالية semantic segmentation. التجزئة الدلالية هي عملية تعيين تسمية لكل بكسل في الصورة.
عملية اكتشاف قناع الوجه باستخدام التعلم الآلي
الخطوة 1: استخراج بيانات الوجه للتدريب.
الخطوة 2: تدريب المصنف على تصنيف الوجوه في قناع أو تسميات بدون قناع.
الخطوة 3: اكتشاف الوجوه أثناء اختبار البيانات باستخدام كاشف الوجه SSD.
الخطوة 4: باستخدام المصنف المدرب، صنف الوجوه المكتشفة.
في الخطوة الثالثة من العملية المذكورة أعلاه، عليك التفكير ما هو كاشف الوجه SSD؟ حسنًا، SSD عبارة عن كاشف متعدد الصناديق ذو اللقطة الواحدة Single Shot Multibox Detector. هذه تقنية تستخدم لاكتشاف الأشياء في الصور باستخدام شبكة عصبية واحدة عميقة.
يتم استخدامه للكشف عن الأشياء في الصورة. باستخدام بُنية أساسية لبنية VGG-16، يمكن أن يتفوق SSD على أجهزة الكشف عن الكائنات الأخرى مثل YOLO وFaster R-CNN من حيث السرعة والدقة.
اكتشاف قناع الوجه مع التعلم الآلي
الآن، دعنا نبدأ بمهمة اكتشاف قناع الوجه باستخدام التعلم الآلي باستخدام لغة برمجة بايثون. سأبدأ هذه المهمة عن طريق استيراد مكتبات بايثون الضرورية التي نحتاجها لهذه المهمة
</p>
import pandas as pd
import numpy as np
import cv2
import json
import os
import matplotlib.pyplot as plt
import random
import seaborn as sns
from keras.models import Sequential
from keras import optimizers
from keras import backend as K
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D, BatchNormalization
from sklearn.model_selection import train_test_split
from keras.preprocessing.image import ImageDataGenerator
directory = "../input/face-mask-detection-dataset/Medical mask/Medical mask/Medical Mask/annotations"
image_directory = "../input/face-mask-detection-dataset/Medical mask/Medical mask/Medical Mask/images"
df = pd.read_csv("../input/face-mask-detection-dataset/train.csv")
df_test = pd.read_csv("../input/face-mask-detection-dataset/submission.csv")
<p>
إنشاء دوال المساعد
سأبدأ هذه المهمة بإنشاء دالتين مساعدتين:
</p>
cvNet = cv2.dnn.readNetFromCaffe('weights.caffemodel')
def getJSON(filePathandName):
with open(filePathandName,'r') as f:
return json.load(f)
def adjust_gamma(image, gamma=1.0):
invGamma = 1.0 / gamma
table = np.array([((i / 255.0) ** invGamma) * 255 for i in np.arange(0, 256)])
return cv2.LUT(image.astype(np.uint8), table.astype(np.uint8))
<p>
- تسترد الدالة getJSON ملف json الذي يحتوي على بيانات الصندوق المحيط في مجموعة بيانات التدريب.
- تعد دالة Adjust_gamma عملية غير خطية تُستخدم لترميز وفك ترميز قيم luminance أو tristimulus في أنظمة الفيديو أو الصور الثابتة. ببساطة، يتم استخدامه لغرس القليل من الضوء في الصورة. إذا كانت gamma <1، فستتحول الصورة إلى الطرف الأغمق من الطيف وعندما تكون gamma> 1، سيكون هناك المزيد من الضوء في الصورة.
معالجة البيانات
الخطوة التالية الآن هي استكشاف بيانات JSON المقدمة للتدريب:
</p>
Jsonfiles=[]
for i in os.listdir(directory):
jsonfiles.append(getJSON(os.path.join(directory,i)))
jsonfiles[0]
{'FileName': '2349.png',
'NumOfAnno': 4,
'Annotations': [{'isProtected': False,
'ID': 193452793312540288,
'BoundingBox': [29, 69, 285, 343],
'classname': 'face_other_covering',
'Confidence': 1,
'Attributes': {}},
{'isProtected': False,
'ID': 545570408121800384,
'BoundingBox': [303, 99, 497, 341],
'classname': 'face_other_covering',
'Confidence': 1,
'Attributes': {}},
{'isProtected': False,
'ID': 339053397051370048,
'BoundingBox': [8, 71, 287, 373],
'classname': 'hijab_niqab',
'Confidence': 1,
'Attributes': {}},
{'isProtected': False,
'ID': 100482004994698944,
'BoundingBox': [296, 99, 525, 371],
'classname': 'hijab_niqab',
'Confidence': 1,
'Attributes': {}}]}
<p>
- يحتوي حقل التعليقات التوضيحية Annotations field على بيانات جميع الوجوه الموجودة في صورة معينة.
- توجد أسماء فئات مختلفة، لكن أسماء الفئات الحقيقية هي face_with_mask و face_no_mask.
</p>
df = pd.read_csv("train.csv")
df.head()
<p>
باستخدام القناع والتسميات non_mask، يتم استخراج بيانات الصندوق المحيط لملفات json. يتم استخراج وجوه صورة معينة وتخزينها في قائمة البيانات مع علامتها لعملية التعلم.
</p>
data = []
img_size = 124
mask = ['face_with_mask']
non_mask = ["face_no_mask"]
labels={'mask':0,'without mask':1}
for i in df["name"].unique():
f = i+".json"
for j in getJSON(os.path.join(directory,f)).get("Annotations"):
if j["classname"] in mask:
x,y,w,h = j["BoundingBox"]
img = cv2.imread(os.path.join(image_directory,i),1)
img = img[y:h,x:w]
img = cv2.resize(img,(img_size,img_size))
data.append([img,labels["mask"]])
if j["classname"] in non_mask:
x,y,w,h = j["BoundingBox"]
img = cv2.imread(os.path.join(image_directory,i),1)
img = img[y:h,x:w]
img = cv2.resize(img,(img_size,img_size))
data.append([img,labels["without mask"]])
random.shuffle(data)
p = []
for face in data:
if(face[1] == 0):
p.append("Mask")
else:
p.append("No Mask")
sns.countplot(p)
<p>
يخبرنا الرسم أعلاه أن عدد صور القناع> عدد الصور بدون قناع، لذا فهذه مجموعة بيانات غير متوازنة. ولكن نظرًا لأننا نستخدم نموذج SSD مُدرَّبًا مسبقًا، ومُدرَّبًا على اكتشاف الوجوه غير المقنعة، فإن هذا الاختلال في التوازن لن يكون مهمًا كثيرًا.
لكن دعونا نعيد تشكيل البيانات قبل تدريب الشبكة العصبية:
</p>
X = []
Y = []
for features,label in data:
X.append(features)
Y.append(label)
X = np.array(X)/255.0
X = X.reshape(-1,124,124,3)
Y = np.array(Y)
<p>
شبكة تدريب عصبية لاكتشاف قناع الوجه
الآن الخطوة التالية هي تدريب شبكة عصبية على مهمة اكتشاف قناع الوجه باستخدام التعلم العميق:
</p>
model = Sequential()
model.add(Conv2D(32, (3, 3), padding = "same", activation='relu', input_shape=(124,124,3)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dropout(0.5))
model.add(Dense(50, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam' ,metrics=['accuracy'])
xtrain,xval,ytrain,yval=train_test_split(X, Y,train_size=0.8,random_state=0)
featurewise_center=False,
samplewise_center=False,
featurewise_std_normalization=False,
samplewise_std_normalization=False,
zca_whitening=False,
rotation_range=15,
width_shift_range=0.1,
height_shift_range=0.1,
horizontal_flip=True,
vertical_flip=False)
datagen.fit(xtrain)
history = model.fit_generator(datagen.flow(xtrain, ytrain, batch_size=32),
steps_per_epoch=xtrain.shape[0]//32,
epochs=50,
verbose=1,
validation_data=(xval, yval))
<p>
اختبار النموذج
تحتوي مجموعة بيانات الاختبار على 1698 صورة ولتقييم النموذج، لذا التقطت عددًا قليلاً من الصور من مجموعة البيانات هذه نظرًا لعدم وجود علامات وجه face tags في مجموعة البيانات:
</p>
test_images = ['1114.png','1504.jpg', '0072.jpg','0012.jpg','0353.jpg','1374.jpg']
gamma = 2.0
fig = plt.figure(figsize = (14,14))
rows = 3
cols = 2
axes = []
assign = {'0':'Mask','1':"No Mask"}
for j,im in enumerate(test_images):
image = cv2.imread(os.path.join(image_directory,im),1)
image = adjust_gamma(image, gamma=gamma)
(h, w) = image.shape[:2]
blob = cv2.dnn.blobFromImage(cv2.resize(image, (300,300)), 1.0, (300, 300), (104.0, 177.0, 123.0))
cvNet.setInput(blob)
detections = cvNet.forward()
for i in range(0, detections.shape[2]):
try:
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
frame = image[startY:endY, startX:endX]
confidence = detections[0, 0, i, 2]
if confidence > 0.2:
im = cv2.resize(frame,(img_size,img_size))
im = np.array(im)/255.0
im = im.reshape(1,124,124,3)
result = model.predict(im)
if result>0.5:
label_Y = 1
else:
label_Y = 0
cv2.rectangle(image, (startX, startY), (endX, endY), (0, 0, 255), 2)
cv2.putText(image,assign[str(label_Y)] , (startX, startY-10), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (36,255,12), 2)
except:pass
axes.append(fig.add_subplot(rows, cols, j+1))
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.show()
<p>
من خلال تحليل الناتج أعلاه، يمكننا أن نلاحظ أن النظام بأكمله يعمل بشكل جيد مع الوجوه التي لها سيطرة مكانية spatial dominance. لكنها تفشل في حالة الصور التي تكون فيها الوجوه صغيرة وتشغل مساحة أقل في الصورة الإجمالية.
للحصول على أفضل النتائج، يمكن استخدام تقنيات مختلفة للمعالجة المسبقة للصور، أو يمكن إبقاء حد الثقة منخفضًا، أو يمكن للمرء تجربة أحجام blob مختلفة.
Hi, this is a comment.
To get started with moderating, editing, and deleting comments, please visit the Comments screen in the dashboard.