สร้างเว็บแอปตรวจจับออบเจ็กต์ที่กำหนดเองด้วย MediaPipe

1. ก่อนเริ่มต้น

MediaPipe Solutions ให้คุณนำโซลูชันแมชชีนเลิร์นนิง (ML) ไปใช้กับแอป ซึ่งมีเฟรมเวิร์กที่ช่วยให้คุณกำหนดค่าไปป์ไลน์การประมวลผลที่สร้างไว้ล่วงหน้าซึ่งจะให้ผลลัพธ์ที่เป็นประโยชน์ น่าสนใจ และมีประโยชน์แก่ผู้ใช้ได้ทันที และยังปรับแต่งโซลูชันเหล่านี้ได้ด้วยเครื่องสร้างแบบจำลองเพื่ออัปเดตโมเดลเริ่มต้น

การตรวจจับออบเจ็กต์เป็นหนึ่งในงานด้านการมองเห็น ML หลายร��ยการที่โซลูชัน MediaPipe มีให้ MediaPipe Tasks พร้อมใช้งานใน Android, Python และเว็บ

ใน Codelab นี้ คุณเพิ่มการตรวจจับวัตถุลงในเว็บแอปเพื่อตรวจหาสุนัขในรูปภาพและวิดีโอสดจากเว็บแคม

สิ่งที่คุณจะได้เรียนรู้

  • วิธีรวมงานการตรวจจับออบเจ็กต์ในเว็บแอปด้วย MediaPipe Tasks

สิ่งที่คุณจะสร้าง

  • เว็บแอปที่ตรวจจับการมีสุนัขอยู่ คุณสามารถปรับแต่งโมเดลเพื่อตรวจหาคลาสของวัตถุที่ต้องการได้ด้วยเครื่องสร้างโมเดล MediaPipe

สิ่งที่ต้องมี

  • บัญชี CodePen
  • อุปกรณ์ที่มีเว็บเบราว์เซอร์
  • ความรู้พื้นฐานเกี่ยวกับ JavaScript, CSS และ HTML

2. ตั้งค่า

Codelab นี้จะเรียกใช้โค้ดของคุณใน CodePen ซึ่งเป็นสภาพแวดล้อมการพัฒนาโซเชียลที่ให้คุณเขียนโค้ดในเบราว์เซอร์และตรวจสอบผลลัพธ์ขณะสร้าง

โปรดทำตามขั้นตอนต่อไปนี้เพื่อตั้งค่า

  1. ในบัญชี CodePen ให้ไปที่ CodePen นี้ คุณใช้โค้ดนี้เป็นฐานเริ่มต้นในการสร้างตัวตรวจจับออบเจ็กต์ของคุณเอง
  2. คลิก Fork ที่ด้านล่างของ CodePen ในเมนูการนำทางเพื่อทําสําเนาโค้ดเริ่มต้น

เมนูการนำทางใน CodePen ที่มีปุ่ม "แยก" อยู่

  1. ในแท็บ JS ให้คลิกล��กศรตัวขยาย b15acb07e6357dce.png แล้วเลือกเพิ่มตัวแก้ไข JavaScript สูงสุด คุณจะแก้ไขงานได้เฉพาะในแท็บ JS สำหรับ Codelab นี้ จึงไม่จำเป็นต้องเห็นแท็บ HTML หรือ CSS

ตรวจสอบแอปเริ่มต้น

  1. ในแผงแสดงตัวอย่าง โปรดสังเกตว่ามีรูปภาพสุนัข 2 ภาพและตัวเลือกเพื่อเรียกใช้เว็บแคม โมเดลที่คุณใช้ในบทแนะนำนี้ได้รับการฝึกกับสุนัข 3 ตัวที่แสดงในรูปภาพ 2 รูป

ตัวอย่างของเว็บแอปจากโค้ดเริ่มต้น

  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, Package Manager หรือ 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

ดูข้อมูลเพิ่มเติม