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