המשימה MediaPipe Image Generator (מחולל תמונות) מאפשרת ליצור תמונות על סמך הנחיית טקסט. במשימה הזו נעשה שימוש במודל טקסט לתמונה כדי ליצור תמונות באמצעות טכניקות דיפוזיה.
המשימה מקבלת הנחיית טקסט כקלט, יחד עם תמונה אופציונלית של תנאי שהמודל יכול לשפר ולהשתמש בה כהפניה ליצירה. הכלי ליצירת תמונות יכול גם ליצור תמונות על סמך מושגים ספציפיים שסופקו למודל במהלך האימון או האימון מחדש. מידע נוסף זמין במאמר בנושא התאמה אישית באמצעות LoRA.
דוגמת הקוד שמתוארת בהוראות האלה זמינה ב-GitHub. מידע נוסף על היכולות, המודלים ואפשרויות ההגדרה של המשימה הזו זמין במאמר סקירה כללית.
קוד לדוגמה
קוד הדוגמה של MediaPipe Tasks הוא הטמעה בסיסית של אפליקציה ליצירת תמונות ל-Android. אתם יכולים להשתמש באפליקציה כנקודת התחלה לאפליקציית Android משלכם, או להיעזר בה כשאתם משנים אפליקציה קיימת. קוד הדוגמה של מחולל התמונות מתארח ב-GitHub.
הורדת הקוד
בהוראות הבאות מוסבר איך ליצור עותק מקומי של קוד הדוגמה באמצעות כלי שורת הפקודה git.
כדי להוריד את הקוד לדוגמה:
- משכפלים את מאגר ה-Git באמצעות הפקודה הבאה:
git clone https://github.com/google-ai-edge/mediapipe-samples
- אפשר גם להגדיר את מופע ה-git כך שישתמש ב-sparse checkout, כדי שיהיו לכם רק הקבצים של אפליקציית הדוגמה Image Generator:
cd mediapipe-samples git sparse-checkout init --cone git sparse-checkout set examples/image_generation/android
אחרי שיוצרים גרסה מקומית של קוד הדוגמה, אפשר לייבא את הפרויקט ל-Android Studio ולהריץ את האפליקציה. הוראות מופיעות במדריך ההגדרה ל-Android.
רכיבים מרכזיים
הקבצים הבאים מכילים את הקוד החשוב לדוגמה הזו של אפליקציה ליצירת תמונות:
- ImageGenerationHelper.kt: מאתחל את המשימה ומטפל ביצירת התמונה.
- DiffusionActivity.kt: יצירת תמונות כשתוספים או משקלים של LoRA לא מופעלים.
- PluginActivity.kt: מיישם את מודלים של פלאגינים, שמאפשרים למשתמשים לספק תמונה של תנאי כקלט.
- LoRAWeightActivity.kt: ניגש למשקלי LoRA ומטפל בהם. המשקלים האלה משמשים להתאמה אישית של מודלים בסיסיים ומאפשרים להם ליצור תמונות של מושגים ספציפיים.
הגדרה
בקטע הזה מתוארים השלבים העיקריים להגדרת סביבת הפיתוח ופרויקטים של קוד במיוחד לשימוש בכלי ליצירת תמונות. מידע כללי על הגדרת סביבת הפיתוח לשימוש במשימות MediaPipe, כולל דרישות לגבי גרסת הפלטפורמה, מופיע במדריך ההגדרה ל-Android.
תלויות
המשימה Image Generator (מחולל תמונות) משתמשת בספרייה com.google.mediapipe:tasks-vision-image-generator. מוסיפים את התלות הזו לקובץ build.gradle של אפליקציית Android:
dependencies {
implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'
}
במכשירים עם Android 12 (API 31) ומעלה, מוסיפים את התלות בספריית OpenCL המקורית. מידע נוסף זמין במאמר בנושא התג uses-native-library.
מוסיפים את התגים הבאים uses-native-library לקובץ AndroidManifest.xml:
<uses-native-library android:name="libOpenCL.so" android:required="false" />
<uses-native-library android:name="libOpenCL-car.so" android:required="false"/>
<uses-native-library android:name="libOpenCL-pixel.so" android:required="false" />
דגם
כדי להשתמש במשימה MediaPipe Image Generator, צריך מודל בסיסי מאומן שתואם למשימה הזו. אחרי שמורידים מודל, מתקינים את התלות הנדרשת וממירים את המודל לפורמט מתאים. לאחר מכן, מעבירים את המודל שהומר למכשיר Android.
מידע נוסף על מודלים מאומנים שזמינים בכלי ליצירת תמונות מופיע בקטע מודלים במאמר בנושא סקירת המשימות.
הורדת מודל בסיסי
כדי להשתמש בכלי ליצירת תמונות, מודל הבסיס צריך להתאים לפורמט המודל stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only, על סמך המודל הבא:
stable-diffusion-v1-5/stable-diffusion-v1-5 EMA-only.
התקנה של יחסי תלות והמרת המודל
$ pip install torch typing_extensions numpy Pillow requests pytorch_lightning absl-py
מריצים את הסקריפט convert.py:
$ python3 convert.py --ckpt_path <ckpt_path> --output_path <output_path>
העברת המודל שהומר למכשיר
מעבירים את התוכן של התיקייה <output_path> למכשיר Android.
$ adb shell rm -r /data/local/tmp/image_generator/ # Remove any previously loaded weights
$ adb shell mkdir -p /data/local/tmp/image_generator/
$ adb push <output_path>/. /data/local/tmp/image_generator/bins
הורדת מודלים של פלאגינים והוספת משקלים של LoRA (אופציונלי)
אם אתם מתכוונים להשתמש במודל פלאגין, כדאי לבדוק אם צריך להוריד את המודל. בתוספים שנדרש בהם מודל נוסף, המודלים של התוסף צריכים להיות כלולים ב-APK או להורדה לפי דרישה. מודלים של תוספים הם קלים יחסית (כ-23MB) ואפשר לצרף אותם ישירות ל-APK. עם זאת, מומלץ להוריד מודלים של תוספים לפי דרישה.
אם התאמתם מודל באמצעות LoRA, תוכלו להוריד אותו לפי דרישה. מידע נוסף זמין במאמר בנושא משקלים של LoRA במודל של פלאגין.
יצירת המשימה
המשימה MediaPipe Image Generator משתמשת בפונקציה createFromOptions() כדי להגדיר את המשימה. הפונקציה createFromOptions() מקבלת ערכים לאפשרויות ההגדרה. מידע נוסף על אפשרויות ההגדרה זמין במאמר אפשרויות הגדרה.
אפשרויות הגדרה
אלה אפשרויות ההגדרה של המשימה הזו לאפליקציות ל-Android:
| שם האפשרות | תיאור | טווח ערכים |
|---|---|---|
imageGeneratorModelDirectory |
ספריית מודל גנרטור התמונות שבה מאוחסנים משקלי המודל. | PATH |
loraWeightsFilePath |
ההגדרה קובעת את הנתיב לקובץ המשקלים של LoRA. אופציונלי ורלוונטי רק אם המודל עבר התאמה אישית באמצעות LoRA. | PATH |
errorListener |
הגדרת פונקציית event listener אופציונלית לשגיאות. | N/A |
המשימה תומכת גם במודלים של תוספים, שמאפשרים למשתמשים לכלול תמונות של תנאים בקלט של המשימה. המודל הבסיסי יכול להגדיל את התמונות האלה ולהשתמש בהן כהפניה ליצירה. תמונות התנאים יכולות להיות נקודות ציון בפנים, קווי מתאר של קצוות והערכות עומק. המודל משתמש בהן כהקשר ומידע נוספים ליצירת תמונות.
כשמוסיפים מודל פלאגין למודל הבסיס, צריך גם להגדיר את אפשרויות הפלאגין. הפלאגין Face landmark משתמש ב-faceConditionOptions, הפלאגין Canny edge משתמש ב-edgeConditionOptions והפלאגין Depth משתמש ב-depthConditionOptions.
אפשרויות של זיהוי קצוות
מגדירים את האפשרויות הבאות ב-edgeConditionOptions.
| שם האפשרות | תיאור | טווח ערכים | ערך ברירת מחדל |
|---|---|---|---|
threshold1 |
הסף הראשון להליך ההיסטרזיס. | Float |
100 |
threshold2 |
הסף השני להליך ההיסטרזיס. | Float |
200 |
apertureSize |
גודל הצמצם של אופרטור סובל. הטווח הטיפוסי הוא בין 3 ל-7. | Integer |
3 |
l2Gradient |
האם נעשה שימוש בנורמת L2 כדי לחשב את גודל הגרדיאנט של התמונה, במקום בנורמת L1 שמוגדרת כברירת מחדל. | BOOLEAN |
False |
EdgePluginModelBaseOptions |
האובייקט BaseOptions שמגדיר את הנתיב למודל של הפלאגין. |
אובייקט BaseOptions |
N/A |
מידע נוסף על אפשרויות ההגדרה האלה זמין במאמר בנושא גלאי קצוות של קאני.
אפשרויות של נקודות ציון בפנים
מגדירים את האפשרויות הבאות ב-faceConditionOptions.
| שם האפשרות | תיאור | טווח ערכים | ערך ברירת מחדל |
|---|---|---|---|
minFaceDetectionConfidence |
ציון הסמך המינימלי לזיהוי הפנים כדי שהזיהוי ייחשב כמוצלח. | Float [0.0,1.0] |
0.5 |
minFacePresenceConfidence |
ציון הוודאות המינימלי של נוכחות פנים בזיהוי נקודות ציון בפנים. | Float [0.0,1.0] |
0.5 |
faceModelBaseOptions |
אובייקט BaseOptions שמגדיר את הנתיב של המודל שיוצר את תמונת התנאי. |
אובייקט BaseOptions |
N/A |
FacePluginModelBaseOptions |
האובייקט BaseOptions שמגדיר את הנתיב למודל של הפלאגין. |
אובייקט BaseOptions |
N/A |
מידע נוסף על אופן הפעולה של אפשרויות ההגדרה האלה זמין במאמר בנושא משימת זיהוי נקודות ציון בפנים.
אפשרויות עומק
מגדירים את האפשרויות הבאות ב-depthConditionOptions.
| שם האפשרות | תיאור | טווח ערכים | ערך ברירת מחדל |
|---|---|---|---|
depthModelBaseOptions |
אובייקט BaseOptions שמגדיר את הנתיב של המודל שיוצר את תמונת התנאי. |
אובייקט BaseOptions |
N/A |
depthPluginModelBaseOptions |
האובייקט BaseOptions שמגדיר את הנתיב למודל של הפלאגין. |
אובייקט BaseOptions |
N/A |
יצירה באמצעות מודל הבסיס בלבד
val options = ImageGeneratorOptions.builder()
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
יצירה באמצעות פלאגינים
אם אתם מחילים מודל אופציונלי של תוסף, אתם צריכים להגדיר את אפשרויות הבסיס של מודל התוסף באמצעות setPluginModelBaseOptions. אם מודל הפלאגין דורש הורדה של מודל נוסף כדי ליצור את תמונת התנאי, מציינים את הנתיב ב-BaseOptions.
נקודת ציון בפנים
val options = ImageGeneratorOptions.builder()
.setImageGeneratorModelDirectory(modelPath)
.build()
val faceModelBaseOptions = BaseOptions.builder()
.setModelAssetPath("face_landmarker.task")
.build()
val facePluginModelBaseOptions = BaseOptions.builder()
.setModelAssetPath("face_landmark_plugin.tflite")
.build()
val faceConditionOptions = FaceConditionOptions.builder()
.setFaceModelBaseOptions(faceModelBaseOptions)
.setPluginModelBaseOptions(facePluginModelBaseOptions)
.setMinFaceDetectionConfidence(0.3f)
.setMinFacePresenceConfidence(0.3f)
.build()
val conditionOptions = ConditionOptions.builder()
.setFaceConditionOptions(faceConditionOptions)
.build()
imageGenerator =
ImageGenerator.createFromOptions(context, options, conditionOptions)
Canny Edge
val options = ImageGeneratorOptions.builder()
.setImageGeneratorModelDirectory(modelPath)
.build()
val edgePluginModelBaseOptions = BaseOptions.builder()
.setModelAssetPath("canny_edge_plugin.tflite")
.build()
val edgeConditionOptions = EdgeConditionOptions.builder()
.setThreshold1(100.0f)
.setThreshold2(100.0f)
.setApertureSize(3)
.setL2Gradient(false)
.setPluginModelBaseOptions(edgePluginModelBaseOptions)
.build()
val conditionOptions = ConditionOptions.builder()
.setEdgeConditionOptions(edgeConditionOptions)
.build()
imageGenerator =
ImageGenerator.createFromOptions(context, options, conditionOptions)
עומק
val options = ImageGeneratorOptions.builder()
.setImageGeneratorModelDirectory(modelPath)
.build()
val depthModelBaseOptions = BaseOptions.builder()
.setModelAssetPath("depth_model.tflite")
.build()
val depthPluginModelBaseOptions = BaseOptions.builder()
.setModelAssetPath("depth_plugin.tflite")
.build()
val depthConditionOptions =
ConditionOptions.DepthConditionOptions.builder()
.setDepthModelBaseOptions(depthModelBaseOptions)
.setPluginModelBaseOptions(depthPluginModelBaseOptions)
.build()
val conditionOptions = ConditionOptions.builder()
.setDepthConditionOptions(depthConditionOptions)
.build()
imageGenerator =
ImageGenerator.createFromOptions(context, options, conditionOptions)
יצירה באמצעות משקלים של LoRA
אם אתם כוללים משקלים של LoRA, צריך להשתמש בפרמטר loraWeightsFilePath כדי להפנות למיקום הנתיב.
val options = ImageGeneratorOptions.builder()
.setLoraWeightsFilePath(weightsPath)
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
הכנת הנתונים
הכלי ליצירת תמונות מקבל את הקלט הבא:
- prompt (חובה): הנחיית הטקסט שמתארת את התמונה שרוצים ליצור.
- iterations (חובה): מספר האיטרציות הכולל ליצירת התמונה. A נקודת התחלה טובה היא 20.
- seed (חובה): ערך ה-seed האקראי שמשמש במהלך יצירת התמונה.
- תמונה של מצב (אופציונלי): התמונה שהמודל משתמש בה כהפניה ליצירה. רלוונטי רק כשמשתמשים במודל פלאגין.
- condition type (אופציונלי): סוג מודל הפלאגין שמשמש את המשימה. רלוונטי רק כשמשתמשים במודל פלאגין.
קלט עם המודל הבסיסי בלבד
fun setInput(prompt: String, iteration: Int, seed: Int) {
imageGenerator.setInputs(prompt, iteration, seed)
}
קלט באמצעות פלאגינים
אם אתם משתמשים במודל פלאגין אופציונלי, אתם צריכים להשתמש גם בפרמטר conditionType כדי לבחור את מודל הפלאגין ובפרמטר sourceConditionImage כדי ליצור את תמונת התנאי.
| שם האפשרות | תיאור | ערך |
|---|---|---|
conditionType |
מודל הפלאגין שמוחל על מודל הבסיס. | {"FACE", "EDGE", "DEPTH"} |
sourceConditionImage |
תמונת המקור שמשמשת ליצירת תמונת התנאי. | אובייקט MPImage |
אם אתם משתמשים במודל של פלאגין, אתם יכולים להשתמש ב-createConditionImage כדי ליצור את תמונת המצב:
fun createConditionImage(
inputImage: MPImage,
conditionType: ConditionType
): Bitmap {
val result =
imageGenerator.createConditionImage(inputImage, conditionType)
return BitmapExtractor.extract(result)
}
אחרי שיוצרים את תמונת התנאי, כוללים אותה כקלט יחד עם ההנחיה, ערך ה-seed ומספר האיטרציות.
imageGenerator.setInputs(
prompt,
conditionalImage,
conditionType,
iteration,
seed
)
קלט עם משקלים של LoRA
אם אתם משתמשים במשקלים של LoRA, ודאו שהטוקן נמצא בהנחיית הטקסט אם אתם רוצים ליצור תמונה עם הקונספט הספציפי שמיוצג על ידי המשקלים.
fun setInput(prompt: String, iteration: Int, seed: Int) {
imageGenerator.setInputs(prompt, iteration, seed)
}
הרצת המשימה
משתמשים בשיטה generate() כדי ליצור תמונה באמצעות הקלט שסופק בקטע הקודם. כך נוצרת תמונה אחת.
יצירה באמצעות מודל הבסיס בלבד
fun generate(prompt: String, iteration: Int, seed: Int): Bitmap {
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap
}
יצירה באמצעות תוספים
fun generate(
prompt: String,
inputImage: MPImage,
conditionType: ConditionType,
iteration: Int,
seed: Int
): Bitmap {
val result = imageGenerator.generate(
prompt,
inputImage,
conditionType,
iteration,
seed
)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap
}
יצירה באמצעות משקלים של LoRA
תהליך יצירת התמונות באמצעות מודל שעבר התאמה אישית עם משקלי LoRA דומה לתהליך עם מודל בסיסי רגיל. מוודאים שהאסימון כלול בהנחיה ומריצים את אותו קוד.
fun generate(prompt: String, iteration: Int, seed: Int): Bitmap {
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap
}
יצירה איטרטיבית
הכלי ליצירת תמונות יכול גם להפיק את התמונות הביניים שנוצרו במהלך כל איטרציה, כפי שמוגדר בפרמטר הקלט iterations. כדי לראות את התוצאות האלה, צריך לקרוא לשיטה setInputs ואז לקרוא לשיטה execute() כדי להריץ כל שלב. מגדירים את הפרמטר showResult לערך true כדי להציג את התוצאות הזמניות.
fun execute(showResult: Boolean): Bitmap {
val result = imageGenerator.execute(showResult)
val bitmap =
BitmapExtractor.extract(result.generatedImage())
return bitmap
}
טיפול בתוצאות והצגתן
הכלי ליצירת תמונות מחזיר ImageGeneratorResult, שכולל את התמונה שנוצרה, חותמת זמן של שעת הסיום והתמונה המותנית אם היא סופקה כקלט.
val bitmap = BitmapExtractor.extract(result.generatedImage())
התמונה הבאה נוצרה מהקלט הבא, באמצעות מודל בסיסי בלבד.
קלטים:
- הנחיה: "דביבון מצויר וצבעוני עם כובע רחב שוליים רפוי, מחזיק מקל והולך ביער, אנימציה, צילום משלושה רבעים, ציור"
- ערך הבסיס: 312687592
- Iterations: 20
תמונה שנוצרה על ידי AI: