استخدام Webots و MediaPipe للتحكم في حركة الروبوت بواسطة وضعية الرأس

 

استخدام Webots و MediaPipe للتحكم في حركة الروبوت بواسطة وضعية الرأس



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


من خلال الاستفادة من أدوات مثل Webots لمحاكاة الروبوت و MediaPipe للكشف عن معالم الوجه في الوقت الفعلي، من الممكن إنشاء نظام حيث يتحكم اتجاه رأس المستخدم في حركة الروبوت. 


تشرح هذه المقالة كيفية بناء مثل هذا النظام، مع توضيح تفاصيل تكامل هذه التقنيات.


مقدمة إلى Webbots وMediaPipe

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


MediaPipe هو إطار عمل طورته Google لبناء خطوط أنابيب تعلم الآلة متعددة الوسائط. تضمن حلولًا متقدمة لمهام مثل اكتشاف الوجه، تتبع اليد وغيرها. 


وحدة Face Mesh في MediaPipe مفيدة بشكل خاص في التقاط معلمات الوجه في الوقت الفعلي، والتي يمكن استخدامها لتقدير اتجاه رأس الشخص.


نبذة عن النظام

الهدف هو إنشاء نظام حيث تتحكم حركات رأس المستخدم، التي يتم التقاطها من خلال كاميرا الويب، في حركة الروبوت المحاكى في Webots.


توضح الخطوات التالية العمليات :

  1. تهيئة الروبوت في Webots : قم بإعداد نموذج الروبوت ومحركاته (المحركات).
  2. التقاط الفيديو باستخدام OpenCV : استخدم مكتبة OpenCV لالتقاط فيديو مباشر من كاميرا الويب.
  3. اكتشاف معالم الوجه باستخدام MediaPipe : قم بمعالجة إطارات الفيديو لاكتشاف معالم الوجه وتقدير وضعية الرأس.
  4. التحكم في حركة الروبوت : قم بترجمة وضعية الرأس المقدرة إلى أوامر حركة للروبوت.

التنفيذ خطوة بخطوة

  1. تهيئة الروبوت في Webbots

ابدأ بإنشاء محاكاة روبوت جديد في Webots 


اضبط هذه المحركات على وضع التحكم في السرعة، مما يسمح لك بالتحكم في سرعتها مباشرة.

from controller import Robot

robot = Robot()

timestep = int(robot.getBasicTimeStep())

LFmotor = robot.getDevice('front left wheel')
RFmotor = robot.getDevice('front right wheel')
LBmotor = robot.getDevice('back left wheel')
RBmotor = robot.getDevice('back right wheel')

LFmotor.setPosition(float("inf"))
RFmotor.setPosition(float("inf"))
LBmotor.setPosition(float("inf"))
RBmotor.setPosition(float("inf"))

# ضبط سرعة المحركات
speed = 6



  1. تعريف وظائف الحركة

قم بتعريف وظائف للتحكم في حركة الروبوت بناءً على السرعة والاتجاه.

def moveForward():
LFmotor.setVelocity(speed)
RFmotor.setVelocity(speed)
LBmotor.setVelocity(speed)
RBmotor.setVelocity(speed)

def moveBackward():
LFmotor.setVelocity(-speed)
RFmotor.setVelocity(-speed)
LBmotor.setVelocity(-speed)
RBmotor.setVelocity(-speed)

def moveLeftward():
LFmotor.setVelocity(-speed)
RFmotor.setVelocity(speed)
LBmotor.setVelocity(-speed)
RBmotor.setVelocity(speed)

def moveRightward():
LFmotor.setVelocity(speed)
RFmotor.setVelocity(-speed)
LBmotor.setVelocity(speed)
RBmotor.setVelocity(-speed)



  1. إعداد MediaPipe لاكتشاف العلامات الوجهية

قم بتهيئة وحدة Face Mesh في MediaPipe لاكتشاف معلمات الوجه في إطارات الفيديو التي يتم التقاطها من كاميرا الويب.


import cv2
import mediapipe as mp
import numpy as np
import time

mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(min_detection_confidence=0.5, min_tracking_confidence=0.5)

mp_drawing = mp.solutions.drawing_utils
drawing_spec = mp_drawing.DrawingSpec(thickness=1, circle_radius=1)

cap = cv2.VideoCapture(0)


  1. معالجة إطارات الفيديو وتقدير وضعية الرأس

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



while cap.isOpened():
while robot.step(timestep) != -1:
success, image = cap.read()
start = time.time()
image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)
image.flags.writeable = False
results = face_mesh.process(image)
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
img_h, img_w, img_c = image.shape
face_3d = []
face_2d = []

if results.multi_face_landmarks:
for face_landmarks in results.multi_face_landmarks:
for idx, lm in enumerate(face_landmarks.landmark):
if idx == 33 أو idx == 263 أو idx == 1 أو idx == 61 أو idx == 291 أو idx == 199:
if idx == 1:
nose_2d = (lm.x * img_w, lm.y * img_h)
nose_3d = (lm.x * img_w, lm.y * img_h, lm.z * 3000)
x, y = int(lm.x * img_w), int(lm.y * img_h)
face_2d.append([x, y])
face_3d.append([x, y, lm.z])

face_2d = np.array(face_2d, dtype=np.float64)
face_3d = np.array(face_3d, dtype=np.float64)
focal_length = 1 * img_w
cam_matrix = np.array([[focal_length, 0, img_h / 2],
[0, focal_length, img_w / 2],
[0, 0, 1]])
dist_matrix = np.zeros((4, 1), dtype=np.float64)
success, rot_vec, trans_vec = cv2.solvePnP(face_3d, face_2d, cam_matrix, dist_matrix)
rmat, jac = cv2.Rodrigues(rot_vec)
angles, mtxR, mtxQ, Qx, Qy, Qz = cv2.RQDecomp3x3(rmat)
x = angles[0] * 360
y = angles[1] * 360
z = angles[2] * 360



  1. التحكم في الروبوت بناءً على وضعية الرأس

تمثيل وضعية الرأس إلى أوامر حركة للروبوت.




if y < -10:
text = "النظر إلى اليسار"
moveLeftward()
elif y > 10:
text = "النظر إلى اليمين"
moveRightward()
elif x < -10:
text = "النظر إلى الأسفل"
elif x > 10:
text = "النظر إلى الأعلى"
moveBackward()
else:
text = "التحرك للأمام"
moveForward()


  1. عرض النتائج

تم استخدام webots للمحاكاة 




للحصول على الكود كامل  اضغط هنا 



AHMED A. A. ALFARRA


تعليقات

المشاركات الشائعة من هذه المدونة

التعرف على الوجوه باستخدام Python

التحكم بالفأرة بالفم باستخدام OpenCV و Mediapipe و PyAutoGUI