המשימה 'מסווג תמונות' מאפשרת לכם לסווג תמונות. אפשר להשתמש במשימה הזאת כדי להבין מה תמונה מייצגת בקבוצה של קטגוריות מוגדרות בזמן האימון. ההוראות האלה מראות איך להשתמש במסווג התמונות אפליקציות ל-iOS. דוגמת הקוד שמתוארת בהוראות אלה זמינה במכשירים הבאים: GitHub.
אפשר לראות את המשימה הזו באתר . עבור לקבלת מידע נוסף על היכולות, המודלים ואפשרויות התצורה של במשימה הזאת. סקירה כללית
קוד לדוגמה
קוד הדוגמה למשימות MediaPipe הוא יישום בסיסי של מסווג תמונות אפליקציה ל-iOS. בדוגמה, אנחנו משתמשים במצלמה של מכשיר iOS פיזי כדי: לסווג אובייקטים באופן קבוע, והם יכולים גם להשתמש בתמונות ובסרטונים הגלריה של המכשיר כדי לסווג אובייקטים באופן סטטי.
אפשר להשתמש באפליקציה כנקודת התחלה של אפליקציה משלך ל-iOS, או להתייחס אליה כשמשנים אפליקציה קיימת. הקוד לדוגמה של מסווג התמונות מתארח ב- GitHub.
להורדת הקוד
בהוראות הבאות מוסבר איך ליצור עותק מקומי של הדוגמה באמצעות כלי שורת הפקודה git.
כדי להוריד את הקוד לדוגמה:
משכפלים את מאגר ה-Git באמצעות הפקודה הבאה:
git clone https://github.com/google-ai-edge/mediapipe-samples
לחלופין, להגדיר את מכונת ה-Git שלך לשימוש בקופה עם היעדר תשלום, כדי רק הקבצים עבור האפליקציה לדוגמה של מסווג התמונות:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_classification/ios/
אחרי שתיצרו גרסה מקומית של הקוד לדוגמה, תוכלו להתקין את ספריית המשימות של MediaPipe, פותחים את הפרויקט באמצעות Xcode ומריצים את האפליקציה. עבור ההוראות מפורטות במדריך ההגדרה ל-iOS.
רכיבים מרכזיים
הקבצים הבאים מכילים את הקוד החיוני בדוגמה של מסווג התמונות יישום:
- ImageClassifierService.swift: הפעלת מסווג התמונות, טיפול בבחירת המודל והפעלת ההסקה על נתוני הקלט.
- CameraViewController.swift: הטמעה של ממשק המשתמש עבור מצב הקלט של פיד המצלמה בשידור חי והצגה חזותית של התוצאות.
- MediaLibraryViewController.swift הטמעה של ממשק המשתמש עבור מצב הקלט של קובץ תמונה וקובץ וידאו והצגת התוצאות באופן חזותי.
הגדרה
בקטע הזה מתוארים השלבים העיקריים להגדרת סביבת הפיתוח כדי להשתמש במסווג תמונות. לקבלת מידע כללי על הגדרת סביבת פיתוח לשימוש במשימות MediaPipe, כולל גרסת פלטפורמה מומלץ לעיין במדריך ההגדרה ל-iOS.
יחסי תלות
מסווג התמונות משתמש בספרייה MediaPipeTasksVision
, שחובה להתקין
באמצעות CocoaPods. הספרייה תואמת גם לאפליקציות Swift ו-Objective-C
ולא נדרשת הגדרה נוספת ספציפית לשפה.
הוראות להתקנת CocoaPods ב-macOS מפורטות במאמר CocoaPods
במדריך ההתקנה.
לקבלת הוראות ליצירת Podfile
עם ה-pods שדרושים
באפליקציה, קראו את המאמר שימוש
CocoaPods.
מוסיפים את הרצף של MediaPipeTasksVision ב-Podfile
באמצעות הקוד הבא:
target 'MyImageClassifierApp' do
use_frameworks!
pod 'MediaPipeTasksVision'
end
אם האפליקציה שלך כוללת יעדים לבדיקת יחידות, יש לעיין במדריך ההגדרה של
iOS למידע נוסף על ההגדרה
Podfile
.
דגם
למשימה של מסווג תמונות של MediaPipe נדרש מודל מאומן שתואם במשימה הזו. לקבלת מידע נוסף על המודלים הזמינים המאומנים עבור מסווג תמונות, אפשר לעיין בסקירה הכללית על המשימה מודלים .
בוחרים מודל ומורידים אותו, ומוסיפים אותו לספריית הפרויקט באמצעות Xcode. לקבלת הוראות להוספת קבצים לפרויקט Xcode, קראו את המאמר ניהול קבצים ותיקיות ב-Xcode. project.
משתמשים במאפיין BaseOptions.modelAssetPath
כדי לציין את הנתיב למודל
ב-App Bundle. בקטע הבא מופיע קוד לדוגמה.
יצירת המשימה
כדי ליצור את המשימה 'מסווג תמונות', אפשר להפעיל אחד מהמאתחלים שלה.
המאתחל ImageClassifier(options:)
מגדיר ערכים לאפשרויות תצורה
כולל מצב ריצה, לוקאל של שמות מוצגים, מספר תוצאות מקסימלי, רמת סמך
הסף, רשימת ההיתרים של הקטגוריות ורשימת הישויות שנחסמו.
אם אתם לא צריכים מסווג תמונות שאותחלו עם הגדרה מותאמת אישית
אפשר להשתמש במאתחל של ImageClassifier(modelPath:)
כדי ליצור
מסווג תמונות עם אפשרויות ברירת המחדל. מידע נוסף על הגדרה
אפשרויות נוספות, ראו סקירה כללית של ההגדרות.
במשימה של מסווג תמונות יש תמיכה ב-3 סוגים של נתוני קלט: תמונות סטילס וקובצי וידאו
בסטרימינג של וידאו בשידור חי. כברירת מחדל, ImageClassifier(modelPath:)
מאתחל
לתמונות סטילס. אם רוצים שהמשימה תופעל כדי לעבד סרטון
קבצים או שידורים חיים, יש להשתמש ב-ImageClassifier(options:)
כדי לציין
מצב ריצה של סרטון או שידור חי. במצב השידור החי נדרש גם
אפשרות הגדרה נוספת של imageClassifierLiveStreamDelegate
,
שמאפשר למסווג התמונות לספק תוצאות של סיווג תמונות
להאציל באופן אסינכרוני.
כדי לראות איך יוצרים את המשימה, צריך לבחור את הכרטיסייה שמתאימה למצב הריצה ולהריץ את ההסקה.
Swift
תמונה
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ImageClassifierOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .image options.maxResults = 5 let imageClassifier = try ImageClassifier(options: options)
וידאו
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ImageClassifierOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .video options.maxResults = 5 let imageClassifier = try ImageClassifier(options: options)
שידור חי
import MediaPipeTasksVision // Class that conforms to the `ImageClassifierLiveStreamDelegate` protocol and // implements the method that the image classifier calls once it // finishes performing classification on each input frame. class ImageClassifierResultProcessor: NSObject, ImageClassifierLiveStreamDelegate { func imageClassifier( _ imageClassifier: ImageClassifier, didFinishClassification result: ImageClassifierResult?, timestampInMilliseconds: Int, error: Error?) { // Process the image classifier result or errors here. } } let modelPath = Bundle.main.path( forResource: "model", ofType: "tflite") let options = ImageClassifierOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .liveStream options.maxResults = 5 // Assign an object of the class to the `imageClassifierLiveStreamDelegate` // property. let processor = ImageClassifierResultProcessor() options.imageClassifierLiveStreamDelegate = processor let imageClassifier = try ImageClassifier(options: options)
Objective-C
תמונה
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageClassifierOptions *options = [[MPPImageClassifierOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeImage; options.maxResults = 5; MPPImageClassifier *imageClassifier = [[MPPImageClassifier alloc] initWithOptions:options error:nil];
וידאו
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageClassifierOptions *options = [[MPPImageClassifierOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeVideo; options.maxResults = 5; MPPImageClassifier *imageClassifier = [[MPPImageClassifier alloc] initWithOptions:options error:nil];
שידור חי
@import MediaPipeTasksVision; // Class that conforms to the `MPPImageClassifierLiveStreamDelegate` protocol // and implements the method that the image classifier calls once it finishes // performing classification on each input frame. @interface APPImageClassifierResultProcessor : NSObject@end @implementation APPImageClassifierResultProcessor - (void)imageClassifier:(MPPImageClassifier *)imageClassifier didFinishClassificationWithResult:(MPPImageClassifierResult *)imageClassifierResult timestampInMilliseconds:(NSInteger)timestampInMilliseconds error:(NSError *)error { // Process the image classifier result or errors here. } @end NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageClassifierOptions *options = [[MPPImageClassifierOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeLiveStream; options.maxResults = 5; // Assign an object of the class to the `imageClassifierLiveStreamDelegate` // property. APPImageClassifierResultProcessor *processor = [APPImageClassifierResultProcessor new]; options.imageClassifierLiveStreamDelegate = processor; MPPImageClassifier *imageClassifier = [[MPPImageClassifier alloc] initWithOptions:options error:nil];
אפשרויות תצורה
המשימה הזו כוללת את אפשרויות ההגדרה הבאות לאפליקציות ל-iOS:
שם האפשרות | תיאור | טווח ערכים | ערך ברירת מחדל |
---|---|---|---|
runningMode |
מגדיר את מצב הריצה של המשימה. יש שלושה סוגים
מצבים: IMAGE: המצב לקלט של תמונה יחידה. סרטון: המצב של פריימים מפוענחים בסרטון. LIVE_STREAM: המצב לשידור חי של קלט נתונים ממצלמה, במצב הזה, resultListener חייב להיות נשלחה קריאה כדי להגדיר אוזן כדי לקבל תוצאות באופן אסינכרוני. |
{RunningMode.image, RunningMode.video, RunningMode.liveStream } |
RunningMode.image |
displayNamesLocale |
מגדיר את השפה של תוויות שישמשו לשמות לתצוגה שסופקו
של מודל המשימה, אם יש כאלה. ברירת המחדל היא en עבור
אנגלית. אפשר להוסיף תוויות שמותאמות לשוק המקומי למטא-נתונים של מודל מותאם אישית
באמצעות TensorFlow Lite Metadata Writer API |
קוד שפה | en |
maxResults |
מגדיר את המספר המקסימלי האופציונלי של תוצאות סיווג מובילות ל- החזרה. אם < 0, כל התוצאות הזמינות יוחזרו. | מספרים חיוביים כלשהם | -1 |
scoreThreshold |
הגדרת סף הציון של התחזית שמבטל את הסף שצוין ב את המטא-נתונים של המודל (אם יש). תוצאות מתחת לערך הזה נדחות. | כל מספר ממשי (float) | לא מוגדר |
categoryAllowlist |
מגדיר את הרשימה האופציונלית של שמות קטגוריות מותרות. אם השדה לא ריק,
תוצאות הסיווג שבהן שם הקטגוריה לא נמצא בקבוצה הזו יהיו
מסונן. המערכת מתעלמת משמות קטגוריות כפולים או לא ידועים.
האפשרות הזו בלעדית למשתמשי categoryDenylist ומשתמשים
ושניהם יובילו לשגיאה. |
כל מחרוזת | לא מוגדר |
categoryDenylist |
מגדיר את הרשימה האופציונלית של שמות קטגוריות שאינם מותרים. אם המיקום
לא ריקות, תוצאות סיווג שבהן שם הקטגוריה נמצא בקבוצה זו יסוננו
החוצה. המערכת מתעלמת משמות קטגוריות כפולים או לא ידועים. האפשרות הזו מקבילה
בלעדי ל-categoryAllowlist ושימוש בשתי התוצאות עלול לגרום לשגיאה. |
כל מחרוזת | לא מוגדר |
resultListener |
מגדיר את אוזן התוצאות לקבל את תוצאות הסיווג
באופן אסינכרוני כש'סיווג התמונות' נמצא בשידור החי
במצב תצוגה. אפשר להשתמש באפשרות הזו רק כשמצב הריצה מוגדר ל-LIVE_STREAM |
לא רלוונטי | לא מוגדר |
הגדרות השידור החי
כשמצב הרצה מוגדר כשידור חי, מסווג התמונות דורש
אפשרות הגדרה נוספת של imageClassifierLiveStreamDelegate
,
שמאפשר למסווג להציג תוצאות סיווג באופן אסינכרוני.
בעל הגישה מיישם את
imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:)
, שהיא קוראת ל'מסווג התמונות' אחרי עיבוד הסיווג
תוצאות לכל פריים.
שם האפשרות | תיאור | טווח ערכים | ערך ברירת מחדל |
---|---|---|---|
imageClassifierLiveStreamDelegate |
מאפשר למסווג התמונות לקבל תוצאות סיווג באופן אסינכרוני
במצב סטרימינג בשידור חי. המחלקה שהמופע שלה מוגדר לנכס הזה חייבת
להטמיע את
imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:)
. |
לא רלוונטי | לא מוגדר |
הכנת נתונים
צריך להמיר את תמונת הקלט או המסגרת לאובייקט MPImage
לפני
ומעבירים אותה למסווג התמונות. ב-MPImage
יש תמיכה בסוגים שונים של קובצי תמונה ב-iOS
ויכולים להשתמש בהם בכל מצב ריצה לצורך הסקת מסקנות. לקבלת מידע נוסף
מידע על MPImage
, מתייחס
MPImage API
צריך לבחור פורמט תמונה ל-iOS בהתאם לתרחיש לדוגמה שלכם ולמצב הריצה
מחייב.MPImage
מקבל את UIImage
, CVPixelBuffer
,
CMSampleBuffer
פורמטים של תמונות ל-iOS.
UIImage
הפורמט UIImage
מתאים במיוחד למצבי הריצה הבאים:
תמונות: תמונות מ-App Bundle, מגלריית משתמשים או ממערכת קבצים בפורמט אפשר להמיר
UIImage
תמונות לאובייקטMPImage
.סרטונים: משתמשים ב-AVAssetImageGenerator כדי לחלץ פריימים של וידאו CGImage וממירים אותן ל-
UIImage
תמונות.
Swift
// Load an image on the user's device as an iOS `UIImage` object. // Convert the `UIImage` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(uiImage: image)
Objective-C
// Load an image on the user's device as an iOS `UIImage` object. // Convert the `UIImage` object to a MediaPipe's Image object having the default // orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
הדוגמה מאתחלת MPImage
עם ברירת המחדל
UIImage.Orientation.Up
לכיוון מסוים. אפשר לאתחל MPImage
עם כל אחד מהפורמטים הנתמכים
UIImage.Orientation
ערכים. מסווג התמונות אינו תומך בכיוונים משוכפלים כמו .upMirrored
.downMirrored
, .leftMirrored
, .rightMirrored
.
למידע נוסף על UIImage
, יש לעיין ב-UIImage Apple Developer
מסמכים.
CVPixelBuffer
הפורמט CVPixelBuffer
מתאים מאוד לאפליקציות שיוצרות פריימים
ולהשתמש ב-CoreImage של iOS
לעיבוד טקסט.
הפורמט CVPixelBuffer
מתאים במיוחד למצבי הריצה הבאים:
תמונות: אפליקציות שיוצרות
CVPixelBuffer
תמונות לאחר עיבוד מסוים באמצעות ה-frameworkCoreImage
של iOS, ניתן לשלוח אל מסווג התמונות מצב הרצת התמונות.סרטונים: ניתן להמיר פריימים של וידאו לפורמט
CVPixelBuffer
עבור מתבצע עיבוד ולאחר מכן נשלחים למסווג התמונות במצב וידאו.בשידור חי: אפליקציות שמשתמשות במצלמת iOS ליצירת פריימים עשויים לעבור המרה בפורמט
CVPixelBuffer
לעיבוד לפני השליחה מסווג תמונות במצב שידור חי.
Swift
// Obtain a CVPixelBuffer. // Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(pixelBuffer: pixelBuffer)
Objective-C
// Obtain a CVPixelBuffer. // Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the // default orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
כדי לקבל מידע נוסף על CVPixelBuffer
, אפשר לעיין ב-CVPixelBuffer Apple
מפתחי המשחק
מסמכים.
CMSampleBuffer
הפורמט CMSampleBuffer
מאחסן דוגמאות מדיה מסוג מדיה אחיד,
הוא גבוה מאוד למצב ההרצה של השידור החי. הפריימים בשידור חי ממצלמות iOS
מועברים באופן אסינכרוני בפורמט CMSampleBuffer
על ידי iOS
AVCaptureVideoDataOutput.
Swift
// Obtain a CMSampleBuffer. // Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(sampleBuffer: sampleBuffer)
Objective-C
// Obtain a `CMSampleBuffer`. // Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the // default orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithSampleBuffer:sampleBuffer error:nil];
מידע נוסף על CMSampleBuffer
זמין ב-CMSampleBuffer Apple
מפתחי המשחק
מסמכים.
הרצת המשימה
כדי להפעיל את מסווג התמונות, צריך להשתמש ב-method classify()
שספציפית להקצאה
מצב ריצה:
- תמונת סטילס:
classify(image:)
- סרטון:
classify(videoFrame:timestampInMilliseconds:)
- שידור חי:
classifyAsync(image:timestampInMilliseconds:)
מסווג התמונות מחזיר את הקטגוריות האפשריות של האובייקט בתוך קלט תמונה או מסגרת.
דוגמאות הקוד הבאות מראות דוגמאות בסיסיות להרצת מסווג התמונות ב: מצבי הריצה השונים הבאים:
Swift
תמונה
let result = try imageClassifier.classify(image: image)
וידאו
let result = try imageClassifier.classify( videoFrame: image, timestampInMilliseconds: timestamp)
שידור חי
try imageClassifier.classifyAsync( image: image, timestampInMilliseconds: timestamp)
Objective-C
תמונה
MPPImageClassifierResult *result = [imageClassifier classifyImage:image error:nil];
וידאו
MPPImageClassifierResult *result = [imageClassifier classifyVideoFrame:image timestampInMilliseconds:timestamp error:nil];
שידור חי
BOOL success = [imageClassifier classifyAsyncImage:image timestampInMilliseconds:timestamp error:nil];
בדוגמת הקוד של מסווג התמונות אפשר לראות את ההטמעות של כל אחד מהמצבים האלה
בצורה מפורטת יותר classify(image:)
,
classify(videoFrame:timestampInMilliseconds:)
, וגם
classifyAsync(image:timestampInMilliseconds:)
. הקוד לדוגמה מאפשר
המשתמש יצטרך לעבור בין מצבי עיבוד שייתכן שהם לא נדרשים לשימוש שלך
מותאמת אישית.
שימו לב לנקודות הבאות:
כשמפעילים במצב וידאו או במצב שידור חי, צריך גם לספק את הפרטים הבאים: חותמת הזמן של מסגרת הקלט במשימה של מסווג התמונות.
בהפעלה במצב תמונה או וידאו, המשימה 'מסווג תמונות' חוסמת את את ה-thread הנוכחי עד לסיום העיבוד של תמונת הקלט או המסגרת. שפת תרגום לא לחסום את השרשור הנוכחי, צריך לבצע את העיבוד ברקע שרשור באמצעות iOS שליחה או NSOperation של מסגרות.
כשפועלים במצב שידור חי, המשימה 'מסווג תמונות' חוזרת באופן מיידי והיא לא חוסמת את השרשור הנוכחי. היא מפעילה את
imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:)
עם תוצאת הסיווג לאחר העיבוד של כל מסגרת קלט. מסווג התמונות מפעיל את השיטה הזו באופן אסינכרוני על סדרה ייעודית תור השליחה. להצגת תוצאות בממשק המשתמש, יש לשלוח את יוצגו לתור הראשי אחרי עיבוד התוצאות. אם מתבצעת קריאה לפונקציהclassifyAsync
כשיש עומס במשימה של מסווג התמונות אם מתבצע עיבוד של פריים אחר, מסווג התמונות מתעלם ממסגרת הקלט החדשה.
טיפול בתוצאות והצגתן
כשמריצים את ההסקה, המשימה 'מסווג תמונות' מחזירה
אובייקט ImageClassifierResult
שמכיל את רשימת הקטגוריות האפשריות
לאובייקטים בתמונה או במסגרת הקלט.
בדוגמה הבאה אפשר לראות את נתוני הפלט מהמשימה:
ImageClassifierResult:
Classifications #0 (single classification head):
head index: 0
category #0:
category name: "/m/01bwb9"
display name: "Passer domesticus"
score: 0.91406
index: 671
category #1:
category name: "/m/01bwbt"
display name: "Passer montanus"
score: 0.00391
index: 670
התוצאה הזו התקבלה באמצעות הפעלה של Bird Classifier ב:
הקוד לדוגמה של מסווג התמונות מדגים איך להציג את הסיווג של התוצאות שהוחזרו מהמשימה, ראו קוד דוגמה לקבלת פרטים.