إنشاء تطبيق ويب مخصّص لرصد العناصر باستخدام MediaPipe

1. قبل البدء

تتيح لك حلول MediaPipe تطبيق حلول تعلُّم الآلة على تطبيقاتك. وتوفّر هذه الميزة إطار عمل يتيح لك ضبط مسارات معالجة مُعدّة مسبقًا توفّر للمستخدمين نتائج فورية وجذابة ومفيدة. يمكنك أيضًا تخصيص هذه الحلول باستخدام Model Maker لتعديل النماذج التلقائية.

يُعدّ رصد الأجسام أحد مهام الرؤية بالذكاء الاصطناعي (AI) المتعددة التي تقدّمها حلول MediaPipe. تتوفّر "مهام MediaPipe" لنظام التشغيل Android وPython والويب.

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

المُعطيات

  • كيفية دمج مهمة رصد الأجسام في تطبيق ويب باستخدام مهام MediaPipe

ما ستُنشئه

المتطلبات

  • حساب على CodePen
  • جهاز مزوّد بمتصفّح ويب
  • معرفة أساسية بلغات JavaScript وCSS وHTML

2. الإعداد

يُشغِّل هذا الرمز البرمجي في CodePen، وهي بيئة تطوير اجتماعية تتيح لك كتابة الرموز البرمجية في المتصفّح والتحقّق من النتائج أثناء الإنشاء.

لإكمال عملية الإعداد، يُرجى اتّباع الخطوات التالية:

  1. في حسابك على CodePen، انتقِل إلى CodePen هذا. يمكنك استخدام هذا الرمز كقاعدة بدء لإنشاء أداة رصد الأجسام الخاصة بك.
  2. في أسفل CodePen في قائمة التنقّل، انقر على Fork (إنشاء نسخة) لإنشاء نسخة من الرمز البرمجي الأوّلي.

قائمة التنقّل في CodePen حيث يقع زر Fork

  1. في علامة التبويب JS، انقر على سهم الموسّع b15acb07e6357dce.png، ثم اختَر تكبير محرِّر JavaScript. يمكنك تعديل العمل في علامة التبويب JS فقط في هذا الدليل التعليمي حول الرموز البرمجية، لذا لا تحتاج إلى الاطّلاع على علامتَي التبويب HTML أو CSS.

مراجعة تطبيق التفعيل

  1. في لوحة المعاينة، لاحظ أنّ هناك صورتَين لكلبين وخيارًا لتشغيل كاميرا الويب. تم تدريب النموذج الذي تستخدمه في هذا الدليل التعليمي على الكلاب الثلاثة المعروضة في الصورتَين.

معاينة تطبيق الويب من الرمز المبدئي

  1. في علامة التبويب JS، لاحظ أنّ هناك العديد من التعليقات في الرمز البرمجي. على سبيل المثال، يمكنك العثور على التعليق التالي في السطر 15:
// Import the required package.

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

3- استيراد حزمة "مهام الرؤية" في MediaPipe وإضافة المتغيّرات المطلوبة

  1. في علامة التبويب JS، استورِد حزمة MediaPipe tasks-vision:
// Import the required package.
​​import { ObjectDetector, FilesetResolver, Detection } from "https://cdn.skypack.dev/@mediapipe/tasks-vision@latest";

يستخدم هذا الرمز البرمجي شبكة توصيل المحتوى (CDN) في Skypack لاستيراد الحزمة. لمزيد من المعلومات حول كيفية استخدام Skypack مع CodePen، يُرجى الاطّلاع على مقالة Skypack + CodePen.

في مشاريعك، يمكنك استخدام Node.js مع npm أو أداة إدارة الحِزم أو شبكة توصيل المحتوى (CDN) التي تختارها. لمزيد من المعلومات عن الحزمة المطلوبة التي يجب تثبيتها، يُرجى الاطّلاع على حِزم JavaScript.

  1. يمكنك تحديد متغيّرات لبرنامج رصد الأجسام ووضع التشغيل:
// Create required variables.
let objectDetector = null;
let runningMode = "IMAGE";

المتغيّر runningMode هو سلسلة يتم ضبطها على القيمة "IMAGE" عند رصد الأجسام في الصور أو القيمة "VIDEO" عند رصد الأجسام في الفيديو.

4. بدء أداة رصد الأجسام

  • لبدء أداة رصد الأجسام، أضِف الرمز البرمجي التالي بعد التعليق ذي الصلة في علامة التبويب JS:
// Initialize the object detector.
async function initializeObjectDetector() {
  const visionFilesetResolver = await FilesetResolver.forVisionTasks(
    "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm"
  );
  objectDetector = await ObjectDetector.createFromOptions(visionFilesetResolver, {
    baseOptions: {
      modelAssetPath: "https://storage.googleapis.com/mediapipe-assets/dogs.tflite"
    },
    scoreThreshold: 0.3,
    runningMode: runningMode
  });
}
initializeObjectDetector();

تحدِّد طريقة FilesetResolver.forVisionTasks() موقع ملف WebAssembly (Wasm) الثنائي للمهمة.

تنشئ طريقة ObjectDetector.createFromOptions() مثيلًا لأداة رصد الأجسام. يجب تقديم مسار إلى النموذج المستخدَم للرصد. في هذه الحالة، تتم استضافة نموذج رصد الكلاب على Cloud Storage.

تم ضبط السمة scoreThreshold على القيمة 0.3. وهذا يعني أنّ النموذج يعرض نتائج لأيّ كائن يتم رصده بمستوى ثقة يبلغ% 30 أو أكثر. يمكنك ضبط هذا الحدّ الأدنى ليناسب احتياجات تطبيقك.

يتم ضبط السمة runningMode عند بدء تشغيل عنصر ObjectDetector. ويمكنك تغيير هذا الخيار وغيره من الخيارات حسب الحاجة لاحقًا.

5- تنفيذ التوقّعات على الصور

  • لتنفيذ التوقّعات على الصور، انتقِل إلى الدالة handleClick() ثم أضِف الرمز التالي إلى نص الدالة:
// Verify object detector is initialized and choose the correct running mode.
if (!objectDetector) {
    alert("Object Detector still loading. Please try again");
    return;
  }

  if (runningMode === "VIDEO") {
    runningMode = "IMAGE";
    await objectDetector.setOptions({ runningMode: runningMode });
  }

تحدِّد هذه التعليمات البرمجية ما إذا تمّت بدء ميزة رصد الأجسام وتأكّد من ضبط وضع التشغيل للصور.

رصد الأجسام

  • لرصد الأجسام في الصور، أضِف الرمز البرمجي التالي إلى نص الدالة handleClick():
// Run object detection.
  const detections = objectDetector.detect(event.target);

يتضمّن المقتطف التالي من التعليمات البرمجية مثالاً على بيانات الإخراج من هذه المهمة:

ObjectDetectionResult:
 Detection #0:
  Box: (x: 355, y: 133, w: 190, h: 206)
  Categories:
   index       : 17
   score       : 0.73828
   class name  : aci
 Detection #1:
  Box: (x: 103, y: 15, w: 138, h: 369)
  Categories:
   index       : 17
   score       : 0.73047
   class name  : tikka

معالجة التنبؤات وعرضها

  1. في نهاية نص الدالة handleClick()، استدِع الدالة displayImageDetections():
// Call the displayImageDetections() function.
displayImageDetections(detections, event.target);
  1. في نص الدالة displayImageDetections()، أضِف الرمز البرمجي التالي لعرض نتائج رصد الأجسام:
// Display object detection results.
  
  const ratio = resultElement.height / resultElement.naturalHeight;

  for (const detection of result.detections) {
    // Description text
    const p = document.createElement("p");
    p.setAttribute("class", "info");
    p.innerText =
      detection.categories[0].categoryName +
      " - with " +
      Math.round(parseFloat(detection.categories[0].score) * 100) +
      "% confidence.";
    // Positioned at the top-left of the bounding box.
    // Height is that of the text.
    // Width subtracts text padding in CSS so that it fits perfectly.
    p.style =
      "left: " +
      detection.boundingBox.originX * ratio +
      "px;" +
      "top: " +
      detection.boundingBox.originY * ratio +
      "px; " +
      "width: " +
      (detection.boundingBox.width * ratio - 10) +
      "px;";
    const highlighter = document.createElement("div");
    highlighter.setAttribute("class", "highlighter");
    highlighter.style =
      "left: " +
      detection.boundingBox.originX * ratio +
      "px;" +
      "top: " +
      detection.boundingBox.originY * ratio +
      "px;" +
      "width: " +
      detection.boundingBox.width * ratio +
      "px;" +
      "height: " +
      detection.boundingBox.height * ratio +
      "px;";

    resultElement.parentNode.appendChild(highlighter);
    resultElement.parentNode.appendChild(p);
  }

تعرِض هذه الدالة مربّعات محيطة فوق الأجسام التي يتم رصدها في الصور. ويزيل هذا الخيار أي تمييز سابق، ثم ينشئ علامات <p> ويعرضها لتمييز كل عنصر يتم رصده.

اختبار التطبيق

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

لاختبار التطبيق، اتّبِع الخطوات التالية:

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

معاينة لتطبيق الويب مع مربّعات حدودية فوق الكلاب التي تم رصدها في الصور

6- تنفيذ التوقّعات على فيديو كاميرا ويب مباشر

رصد الأجسام

  • لرصد الأجسام في فيديو كاميرا ويب مباشر، انتقِل إلى الدالة predictWebcam() ثم أضِف الرمز البرمجي التالي إلى نص الدالة:
// Run video object detection.
  // If image mode is initialized, create a classifier with video runningMode.
  if (runningMode === "IMAGE") {
    runningMode = "VIDEO";
    await objectDetector.setOptions({ runningMode: runningMode });
  }
  let nowInMs = performance.now();

  // Detect objects with the detectForVideo() method.
  const result = await objectDetector.detectForVideo(video, nowInMs);

  displayVideoDetections(result.detections);

تستخدم ميزة "اكتشاف الأجسام في الفيديو" الأساليب نفسها بغض النظر عمّا إذا كنت تُجري الاستنتاج على بيانات البث أو فيديو كامل. تشبه طريقة detectForVideo() طريقة detect() المستخدَمة للصور، ولكنها تتضمّن مَعلمة إضافية للطابع الزمني المرتبط بالإطار الحالي. تُجري الدالة عملية الكشف مباشرةً، لذا عليك ضبط الوقت الحالي بصفته الطابع الزمني.

معالجة التنبؤات وعرضها

  • لمعالجة نتائج الكشف وعرضها، انتقِل إلى الدالة displayVideoDetections() ثم أضِف الرمز التالي إلى نص الدالة:
//  Display video object detection results.
  for (let child of children) {
    liveView.removeChild(child);
  }
  children.splice(0);

  // Iterate through predictions and draw them to the live view.
  for (const detection of result.detections) {
    const p = document.createElement("p");
    p.innerText =
      detection.categories[0].categoryName +
      " - with " +
      Math.round(parseFloat(detection.categories[0].score) * 100) +
      "% confidence.";
    p.style =
      "left: " +
      (video.offsetWidth -
        detection.boundingBox.width -
        detection.boundingBox.originX) +
      "px;" +
      "top: " +
      detection.boundingBox.originY +
      "px; " +
      "width: " +
      (detection.boundingBox.width - 10) +
      "px;";

    const highlighter = document.createElement("div");
    highlighter.setAttribute("class", "highlighter");
    highlighter.style =
      "left: " +
      (video.offsetWidth -
        detection.boundingBox.width -
        detection.boundingBox.originX) +
      "px;" +
      "top: " +
      detection.boundingBox.originY +
      "px;" +
      "width: " +
      (detection.boundingBox.width - 10) +
      "px;" +
      "height: " +
      detection.boundingBox.height +
      "px;";

    liveView.appendChild(highlighter);
    liveView.appendChild(p);

    // Store drawn objects in memory so that they're queued to delete at next call.
    children.push(highlighter);
    children.push(p);
  }
}

يزيل هذا الرمز أي تمييز سابق، ثمّ ينشئ علامات <p> ويعرضها لتمييز كلّ جسم يتم رصده.

اختبار التطبيق

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

لاختبار التطبيق، اتّبِع الخطوات التالية:

  1. نزِّل صورة كلب على هاتفك.
  2. في جزء المعاينة، انقر على تفعيل كاميرا الويب.
  3. إذا عرض المتصفّح مربّع حوار يطلب منك منح إذن الوصول إلى كاميرا الويب، امنح الإذن.
  4. احمل صورة الكلب على هاتفك أمام كاميرا الويب. يعرض مربّع الحدود اسم الكلب ومستوى ثقة النموذج.
  5. إذا لم يكن هناك مربّع حدود، افتح "أدوات مطوّري البرامج في Chrome"، ثمّ تحقّق من لوحة وحدة التحكّم بحثًا عن أخطاء أو راجِع الخطوات السابقة للتأكّد من أنّك لم تفوت أيّ شيء.

مربّع حدود فوق صورة كلب يتم عرضه على كاميرا ويب مباشرة

7- تهانينا

تهانينا! أنشأت تطبيق ويب يرصد الأجسام في الصور. لمزيد من المعلومات، يمكنك الاطّلاع على إصدار كامل من التطبيق على CodePen.

مزيد من المعلومات