1. לפני שמתחילים
פתרונות MediaPipe מאפשרים לכם להחיל פתרונות של למידת מכונה (ML) על האפליקציות שלכם. הוא מספק מסגרת שמאפשרת להגדיר צינורות עיבוד מוכנים מראש שמספקים למשתמשים פלט מיידי, מעניין ושימושי. אפשר אפילו להתאים אישית את הפתרונות האלה באמצעות Model Maker כדי לעדכן את מודלי ברירת המחדל.
זיהוי אובייקטים הוא אחת ממשימות הראייה של ML שמוצעות ב-MediaPipe Solutions. MediaPipe Tasks זמין ל-Android, ל-Python ולאינטרנט.
ב-codelab הזה מוסיפים זיהוי אובייקטים לאפליקציית אינטרנט כדי לזהות כלבים בתמונות ובסרטון ממצלמת אינטרנט בזמן אמת.
מה תלמדו
- איך משלבים משימה של זיהוי אובייקטים באפליקציית אינטרנט באמצעות MediaPipe Tasks.
מה תפַתחו
- אפליקציית אינטרנט שמזהה את נוכחותם של כלבים. אפשר גם להתאים אישית מודל לזיהוי של סוג אובייקטים לפי בחירתכם באמצעות MediaPipe Model Maker.
הדרישות
- חשבון ב-CodePen
- מכשיר עם דפדפן אינטרנט
- ידע בסיסי ב-JavaScript, ב-CSS וב-HTML
2. להגדרה
ב-Codelab הזה הקוד מורץ ב-CodePen,סביבת פיתוח חברתית שמאפשרת לכתוב קוד בדפדפן ולבדוק את התוצאות תוך כדי בנייה.
כדי להשלים את ההגדרה, צריך לבצע את השלבים הבאים:
- בחשבון CodePen, עוברים אל CodePen. משתמשים בקוד הזה כבסיס ליצירת גלאי אובייקטים משלכם.
- בתפריט הניווט בחלק התחתון של CodePen, לוחצים על Fork כדי ליצור עותק של קוד לתחילת הדרך.

- בכרטיסייה JS, לוחצים על החץ להרחבה
ובוחרים באפשרות Maximize JavaScript editor (הגדלת עורך JavaScript). ב-Codelab הזה עורכים את העבודה רק בכרטיסייה JS, כך שלא צריך לראות את הכרטיסיות HTML או CSS.
בדיקת האפליקציה לתחילת הדרך
- בחלונית התצוגה המקדימה, שימו לב שיש שתי תמונות של כלבים ואפשרות להפעיל את מצלמת האינטרנט. המודל שבו משתמשים במדריך הזה אומן על שלושת הכלבים שמוצגים בשתי התמונות.

- בכרטיסיית ה-JS, אפשר לראות שיש כמה הערות לאורך הקוד. לדוגמה, התגובה הבאה מופיעה בשורה 15:
// Import the required package.
התגובות האלה מציינות איפה צריך להוסיף קטעי קוד.
3. מייבאים את חבילת MediaPipe tasks-vision ומוסיפים את המשתנים הנדרשים
- בכרטיסייה 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
עיבוד והצגת תחזיות
- בסוף גוף הפונקציה
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 ובודקים אם יש שגיאות בחלונית Console, או בודקים את השלבים הקודמים כדי לוודא שלא פספסתם משהו.

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 ובודקים אם יש שגיאות בחלונית Console, או בודקים את השלבים הקודמים כדי לוודא שלא פספסתם משהו.

7. מזל טוב
מעולה! יצרתם אפליקציית אינטרנט שמזהה אובייקטים בתמונות. מידע נוסף זמין בגרסה המלאה של האפליקציה ב-CodePen.