یک برنامه وب شناسایی شی سفارشی با MediaPipe ایجاد کنید

۱. قبل از شروع

MediaPipe Solutions به شما امکان می‌دهد راه‌حل‌های یادگیری ماشینی (ML) را در برنامه‌های خود اعمال کنید. این نرم‌افزار چارچوبی را ارائه می‌دهد که به شما امکان می‌دهد خطوط پردازش از پیش ساخته شده را پیکربندی کنید که خروجی فوری، جذاب و مفید را به کاربران ارائه می‌دهند. شما حتی می‌توانید این راه‌حل‌ها را با Model Maker سفارشی کنید تا مدل‌های پیش‌فرض را به‌روزرسانی کنید.

تشخیص اشیا یکی از چندین وظیفه بینایی ماشین است که MediaPipe Solutions ارائه می‌دهد. MediaPipe Tasks برای اندروید، پایتون و وب در دسترس است.

در این آزمایشگاه کد، شما تشخیص اشیا را به یک برنامه وب اضافه می‌کنید تا سگ‌ها را در تصاویر و یک ویدیوی وب‌کم زنده تشخیص دهد.

آنچه یاد خواهید گرفت

  • نحوه گنجاندن یک وظیفه تشخیص شیء در یک برنامه وب با MediaPipe Tasks .

آنچه خواهید ساخت

  • یک برنامه وب که حضور سگ‌ها را تشخیص می‌دهد. همچنین می‌توانید با استفاده از MediaPipe Model Maker، یک مدل را برای تشخیص دسته‌ای از اشیاء دلخواه خود سفارشی کنید.

آنچه نیاز دارید

  • یک حساب کاربری CodePen
  • دستگاهی با مرورگر وب
  • آشنایی اولیه با جاوا اسکریپت، CSS و HTML

۲. آماده شوید

این آزمایشگاه کد، کد شما را در CodePen اجرا می‌کند، یک محیط توسعه اجتماعی که به شما امکان می‌دهد کد را در مرورگر بنویسید و نتایج را هنگام ساخت بررسی کنید.

برای راه‌اندازی، این مراحل را دنبال کنید:

  1. در حساب CodePen خود، به این CodePen بروید. شما از این کد به عنوان پایه شروع برای ایجاد آشکارساز شیء خود استفاده می‌کنید.
  2. در پایین CodePen در منوی ناوبری، روی Fork کلیک کنید تا یک کپی از کد اولیه ایجاد شود.

منوی ناوبری در CodePen که دکمه Fork در آن قرار دارد

  1. در تب JS ، روی کلیک کنید b15acb07e6357dce.png روی فلش بسط‌دهنده کلیک کنید و سپس ویرایشگر جاوا اسکریپت را به حداکثر برسانید. شما فقط کار را در برگه JS برای این آزمایشگاه کد ویرایش می‌کنید، بنابراین نیازی به دیدن برگه‌های HTML یا CSS ندارید.

بررسی برنامه اولیه

  1. در پنل پیش‌نمایش، توجه کنید که دو تصویر از سگ‌ها و گزینه‌ای برای اجرای وب‌کم شما وجود دارد. مدلی که در این آموزش استفاده می‌کنید، بر اساس سه سگ نمایش داده شده در دو تصویر آموزش داده شده است.

پیش‌نمایشی از برنامه وب از کد اولیه

  1. در تب JS ، توجه کنید که چندین کامنت در سراسر کد وجود دارد. برای مثال، می‌توانید کامنت زیر را در خط ۱۵ پیدا کنید:
// Import the required package.

این کامنت‌ها نشان می‌دهند که باید قطعه کدها را کجا وارد کنید.

۳. بسته‌ی MediaPipe tasks-vision را وارد کنید و متغیرهای مورد نیاز را اضافه کنید.

  1. در تب JS ، بسته‌ی MediaPipe tasks-vision را وارد کنید:
// Import the required package.
​​import { ObjectDetector, FilesetResolver, Detection } from "https://cdn.skypack.dev/@mediapipe/tasks-vision@latest";

این کد از شبکه تحویل محتوای Skypack (CDN) برای وارد کردن بسته استفاده می‌کند. برای اطلاعات بیشتر در مورد نحوه استفاده از Skypack با CodePen، به Skypack + CodePen مراجعه کنید.

در پروژه‌های خود، می‌توانید از Node.js به همراه npm یا package manager یا CDN مورد نظر خود استفاده کنید. برای اطلاعات بیشتر در مورد بسته مورد نیاز برای نصب، به بخش بسته‌های جاوا اسکریپت مراجعه کنید.

  1. متغیرهایی را برای آشکارساز شیء و حالت اجرا تعریف کنید:
// Create required variables.
let objectDetector = null;
let runningMode = "IMAGE";

متغیر runningMode رشته‌ای است که هنگام تشخیص اشیاء در تصاویر، مقدار آن "IMAGE" و هنگام تشخیص اشیاء در ویدیو، مقدار آن "VIDEO" تنظیم می‌شود.

۴. مقداردهی اولیه آشکارساز شیء

  • برای مقداردهی اولیه‌ی آشکارساز شیء، کد زیر را بعد از کامنت مربوطه در تب 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 تنظیم شده است. این بدان معناست که مدل نتایج را برای هر شیء شناسایی شده با سطح اطمینان ۳۰٪ یا بیشتر برمی‌گرداند. می‌توانید این آستانه را متناسب با نیازهای برنامه خود تنظیم کنید.

ویژگی runningMode هنگام مقداردهی اولیه شیء ObjectDetector تنظیم می‌شود. می‌توانید این گزینه و سایر گزینه‌ها را در صورت نیاز بعداً تغییر دهید.

۵. پیش‌بینی‌ها را روی تصاویر اجرا کنید

  • برای اجرای پیش‌بینی‌ها روی تصاویر، به تابع 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 DevTools را باز کنید و سپس پنل Console را برای خطاها بررسی کنید یا مراحل قبلی را مرور کنید تا مطمئن شوید چیزی را از قلم نینداخته‌اید.

پیش‌نمایشی از برنامه وب با کادرهای محصورکننده روی سگ‌های شناسایی‌شده در تصاویر

۶. پیش‌بینی‌ها را روی یک ویدیوی وب‌کم زنده اجرا کنید

تشخیص اشیاء

  • برای تشخیص اشیاء در یک ویدیوی وب‌کم زنده، به تابع 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 DevTools را باز کنید و سپس پنل Console را برای خطاها بررسی کنید یا مراحل قبلی را مرور کنید تا مطمئن شوید چیزی را از قلم نینداخته‌اید.

یک کادر محصورکننده روی تصویر سگی که در مقابل یک وب‌کم زنده نگه داشته شده است

۷. تبریک

تبریک! شما یک برنامه وب ساختید که اشیاء را در تصاویر تشخیص می‌دهد. برای کسب اطلاعات بیشتر، نسخه کامل برنامه را در CodePen مشاهده کنید.

بیشتر بدانید