1. ก่อนเริ่มต้น
MediaPipe Solutions ให้คุณนำโซลูชันแมชชีนเลิร์นนิง (ML) ไปใช้กับแอป ซึ่งมีเฟรมเวิร์กที่ช่วยให้คุณกำหนดค่าไปป์ไลน์การประมวลผลที่สร้างไว้ล่วงหน้าซึ่งจะให้ผลลัพธ์ที่เป็นประโยชน์ น่าสนใจ และมีประโยชน์แก่ผู้ใช้ได้ทันที และยังปรับแต่งโซลูชันเหล่านี้ได้ด้วยเครื่องสร้างแบบจำลองเพื่ออัปเดตโมเดลเริ่มต้น
การตรวจจับออบเจ็กต์เป็นหนึ่งในงานด้านการมองเห็น ML หลายร��ยการที่โซลูชัน MediaPipe มีให้ MediaPipe Tasks พร้อมใช้งานใน Android, Python และเว็บ
ใน Codelab นี้ คุณเพิ่มการตรวจจับวัตถุลงในเว็บแอปเพื่อตรวจหาสุนัขในรูปภาพและวิดีโอสดจากเว็บแคม
สิ่งที่คุณจะได้เรียนรู้
- วิธีรวมงานการตรวจจับออบเจ็กต์ในเว็บแอปด้วย MediaPipe Tasks
สิ่งที่คุณจะสร้าง
- เว็บแอปที่ตรวจจับการมีสุนัขอยู่ คุณสามารถปรับแต่งโมเดลเพื่อตรวจหาคลาสของวัตถุที่ต้องการได้ด้วยเครื่องสร้างโมเดล MediaPipe
สิ่งที่ต้องมี
- บัญชี CodePen
- อุปกรณ์ที่มีเว็บเบราว์เซอร์
- ความรู้พื้นฐานเกี่ยวกับ JavaScript, CSS และ HTML
2. ตั้งค่า
Codelab นี้จะเรียกใช้โค้ดของคุณใน CodePen ซึ่งเป็นสภาพแวดล้อมการพัฒนาโซเชียลที่ให้คุณเขียนโค้ดในเบราว์เซอร์และตรวจสอบผลลัพธ์ขณะสร้าง
โปรดทำตามขั้นตอนต่อไปนี้เพื่อตั้งค่า
- ในบัญชี CodePen ให้ไปที่ CodePen นี้ คุณใช้โค้ดนี้เป็นฐานเริ่มต้นในการสร้างตัวตรวจจับออบเจ็กต์ของคุณเอง
- คลิก Fork ที่ด้านล่างของ CodePen ในเมนูการนำทางเพื่อทําสําเนาโค้ดเริ่มต้น
- ในแท็บ JS ให้คลิกล��กศรตัวขยาย แล้วเลือกเพิ่มตัวแก้ไข JavaScript สูงสุด คุณจะแก้ไขงานได้เฉพาะในแท็บ JS สำหรับ Codelab นี้ จึงไม่จำเป็นต้องเห็นแท็บ HTML หรือ CSS
ตรวจสอบแอปเริ่มต้น
- ในแผงแสดงตัวอย่าง โปรดสังเกตว่ามีรูปภาพสุนัข 2 ภาพและตัวเลือกเพื่อเรียกใช้เว็บแคม โมเดลที่คุณใช้ในบทแนะนำนี้ได้รับการฝึกกับสุนัข 3 ตัวที่แสดงในรูปภาพ 2 รูป
- ในแท็บ JS คุณจะสังเกตเห็นว่ามีความคิดเห็นหลายรายการตลอดทั้งโค้ด เช่น คุณจะเห็นความคิดเห็นต่อไปนี้ในบรรทัดที่ 15
// Import the required package.
ความคิดเห็นเหล่านี้จะระบุตำแหน่งที่คุณจำเป็นต้องแทรกข้อมูลโค้ด
3. นำเข้าแพ็กเกจงาน MediaPipe และเพิ่มตัวแปรที่จำเป็น
- ในแท็บ 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
- ประกาศตัวแปรสำหรับตัวตรวจจับวัตถุและโหมดการทำงาน ดังนี้
// 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
ประมวลผลและแสดงการคาดคะเน
- ที่ตอนท้ายของส่วนเนื้อหาของฟังก์ชัน
handleClick()
ให้เรียกฟังก์ชันdisplayImageDetections()
ดังนี้
// Call the displayImageDetections() function.
displayImageDetections(detections, event.target);
- ในเนื้อหาของฟังก์ชัน
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 แผงแสดงตัวอย่างจะรีเฟรชโดยอัตโนมัติเมื่อบันทึก หากเปิดใช้การบันทึกอัตโนมัติอยู่ แอปน่าจะรีเฟรชแล้ว แต่เราขอแนะนำให้รีเฟรชอีกครั้ง
หากต้องการทดสอบแอป ให้ทำตามขั้นตอนต่อไปนี้
- ในแผงแสดงตัวอย่าง ให้คลิกรูปภาพแต่ละรูปเพื่อดูการคาดการณ์ กรอบล้อมรอบจะแสดงชื่อสุนัขพร้อมระดับความเชื่อมั่นของโมเดล
- หากไม่มีกรอบล้อมรอบ ให้เปิดเครื่องมือสำหรับนักพัฒนาเว็บใน 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>
เพื่อไฮไลต์ออบเจ็กต์แต่ละรายการที่ตรวจพบ
ทดสอบแอป
หากต้องการทดสอบการตรวจจับวัตถุแบบเรียลไทม์ การมีรูปภาพสุนัขตัวใดตัวหนึ่งที่ได้รับการฝึกโมเดลจะช่วยได้
หากต้องการทดสอบแอป ให้ทำตามขั้นตอนต่อไปนี้
- ดาวน์โหลดรูปสุนัขลงในโทรศัพท์
- ในแผงแสดงตัวอย่าง ให้คลิกเปิดใช้เว็บแคม
- หากเบราว์เซอร์แสดงกล่องโต้ตอบที่ขอให้คุณให้สิทธิ์เข้าถึงเว็บแคม โปรดให้สิทธิ์
- ถือภาพสุนัขในโทรศัพท์หน้าเว็บแคม กรอบล้อมรอบจะแสดงชื่อของสุนัขและระดับความมั่นใจของโมเดลนั้น
- หากไม่มีกรอบล้อมรอบ ให้เปิดเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome แล้วตรวจสอบข้อผิดพลาดที่แผงคอนโซลหรือตรวจสอบขั้นตอนก่อนหน้านี้เพื่อให้แน่ใจว่าคุณไม่พลาดข้อมูลใดไป
7. ขอแสดงความยินดี
ยินดีด้วย คุณได้สร้างเว็บแอปที่ตรวจหาวัตถุในรูปภาพ ดูข้อมูลเพิ่มเติมได้ในแอปเวอร์ชันสมบูรณ์ใน CodePen