1. مقدمه
MediaPipe چیست؟
MediaPipe Solutions به شما امکان می دهد راه حل های یادگیری ماشینی (ML) را در برنامه های خود اعمال کنید. این یک چارچوب برای پیکربندی خطوط لوله پردازش از پیش ساخته شده است که خروجی فوری، جذاب و مفید را به کاربران ارائه می دهد. حتی می توانید بسیاری از این راه حل ها را با MediaPipe Model Maker سفارشی کنید تا مدل های پیش فرض را به روز کنید.
تولید متن به تصویر یکی از چندین کار ML است که MediaPipe Solutions ارائه می کند.
در این Codelab، شما با یک برنامه اندرویدی عمدتاً ساده شروع میکنید، سپس چندین مرحله را طی میکنید تا زمانی که بتوانید تصاویر جدید را مستقیماً در دستگاه Android خود ایجاد کنید.
چیزی که یاد خواهید گرفت
- نحوه اجرای تولید متن به تصویر در حال اجرا به صورت محلی در یک برنامه اندروید با MediaPipe Tasks .
آنچه شما نیاز دارید
- نسخه نصب شده اندروید استودیو (این کد لبه با Android Studio Giraffe نوشته و تست شده است).
- یک دستگاه اندرویدی با حداقل 8 گیگابایت رم.
- دانش اولیه توسعه اندروید و توانایی اجرای اسکریپت از پیش نوشته شده پایتون.
2. MediaPipe Tasks را به برنامه اندروید اضافه کنید
برنامه شروع اندروید را دانلود کنید
این کد لبه با یک نمونه از پیش ساخته شده متشکل از رابط کاربری شروع می شود که برای نسخه اصلی تولید تصویر استفاده می شود. می توانید آن برنامه شروع را در مخزن رسمی MediaPipe Samples در اینجا بیابید. با کلیک روی Code > Download ZIP، مخزن را کلون کنید یا فایل فشرده را دانلود کنید.
برنامه را به اندروید استودیو وارد کنید
- اندروید استودیو را باز کنید.
- از صفحه خوش آمدید به Android Studio ، در گوشه بالا سمت راست گزینه Open را انتخاب کنید.
- به جایی که مخزن را شبیه سازی یا دانلود کرده اید بروید و پوشه codelabs/image_generation_basic/android/start را باز کنید.
- در این مرحله برنامه نباید کامپایل شود زیرا هنوز وابستگی MediaPipe Tasks را وارد نکرده اید.
با رفتن به فایل build.gradle و پایین رفتن به // مرحله 1 - افزودن وابستگی، برنامه را تعمیر و اجرا خواهید کرد. از آنجا، خط زیر را وارد کنید و سپس دکمه Sync Now را که در بنر بالای Android Studio ظاهر می شود، بزنید.
// Step 1 - Add dependency
implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'
پس از اتمام همگامسازی، با کلیک بر روی فلش اجرای سبز، بررسی کنید که همه چیز به درستی باز و نصب شده باشد ( ) در سمت راست بالای Android Studio. باید برنامه را در صفحه ای با دو دکمه رادیویی و دکمه ای با برچسب INITIALIZE باز کنید. اگر روی آن دکمه کلیک کنید، باید بلافاصله به یک UI جداگانه متشکل از یک پیام متنی و گزینه های دیگر در کنار دکمه ای با برچسب GENERATE منتقل شوید.
متأسفانه این میزان برنامه شروع کننده است، بنابراین وقت آن است که یاد بگیرید چگونه این برنامه را به پایان می رسانید و شروع به تولید تصاویر جدید در دستگاه خود کنید!
3. راه اندازی Image Generator
برای این مثال، اکثر کارهای تولید تصویر در فایل ImageGenerationHelper.kt اتفاق می افتد. هنگامی که این فایل را باز می کنید، متوجه متغیری به نام imageGenerator در بالای کلاس خواهید شد. این شیء Task است که کارهای سنگین را در برنامه تولید تصویر شما انجام می دهد.
درست در زیر آن شی، تابعی به نام ()initializeImageGenerator را با نظر زیر مشاهده خواهید کرد: // مرحله 2 - مقدار دهی اولیه مولد تصویر. همانطور که ممکن است حدس بزنید، اینجا جایی است که شی ImageGenerator را مقداردهی اولیه می کنید. برای تنظیم مسیر مدل تولید تصویر و مقداردهی اولیه شی ImageGenerator ، آن بدنه تابع را با کد زیر جایگزین کنید:
// Step 2 - initialize the image generator
val options = ImageGeneratorOptions.builder()
.setImageGeneratorModelDirectory(modelPath)
.build()
imageGenerator = ImageGenerator.createFromOptions(context, options)
در زیر آن تابع دیگری به نام setInput() مشاهده خواهید کرد. این سه پارامتر را می پذیرد: یک رشته اعلان که برای تعریف تصویر تولید شده استفاده می شود، تعداد تکرارهایی که Task باید در حین تولید تصویر جدید انجام دهد، و یک مقدار seed که می تواند برای ایجاد نسخه های جدید یک تصویر مبتنی بر تصویر استفاده شود. در همان اعلان هنگام تولید همان تصویر زمانی که از همان دانه استفاده می شود. هدف از این تابع تنظیم این پارامترهای اولیه برای مولد تصویر زمانی است که می خواهید تصویری ایجاد کنید که مراحل میانی را نمایش دهد .
ادامه دهید و بدنه setInput() (که در آن نظر // مرحله 3 - پذیرش ورودی ها را می بینید) را با این خط جایگزین کنید:
// Step 3 - accept inputs
imageGenerator.setInputs(prompt, iteration, seed)
دو مرحله بعدی جایی است که نسل در آن اتفاق می افتد. تابع ()genere همان ورودیهای setInput را میپذیرد، اما تصویری را بهعنوان یک فراخوانی تکشات ایجاد میکند که هیچ تصویر مرحلهای میانی را بر نمیگرداند. می توانید بدنه این تابع (که شامل نظر // مرحله 4 - تولید بدون نمایش تکرارها) را با موارد زیر جایگزین کنید:
// Step 4 - generate without showing iterations
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap
مهم است که بدانید این کار به صورت همزمان انجام می شود، بنابراین باید تابع را از یک رشته پس زمینه فراخوانی کنید. کمی بعداً در این کد لبه در مورد آن بیشتر خواهید آموخت.
آخرین مرحله ای که در این فایل بردارید، پر کردن تابع ()execute (با برچسب مرحله 5) است. این پارامتری را میپذیرد که به آن میگوید آیا باید یک تصویر میانی را برای یک مرحله از تولید که با تابع execute() ImageGenerator انجام میشود، برگرداند یا نه. بدنه تابع را با این کد جایگزین کنید:
// Step 5 - generate with iterations
val result = imageGenerator.execute(showResult)
if (result == null || result.generatedImage() == null) {
return Bitmap.createBitmap(512, 512, Bitmap.Config.ARGB_8888)
.apply {
val canvas = Canvas(this)
val paint = Paint()
paint.color = Color.WHITE
canvas.drawPaint(paint)
}
}
val bitmap =
BitmapExtractor.extract(result.generatedImage())
return bitmap
و این برای فایل کمکی است. در بخش بعدی فایل ViewModel را که منطق این مثال را مدیریت می کند پر می کنید.
4. برنامه را کنار هم بیاورید
فایل MainViewModel حالت های رابط کاربری و دیگر منطق های مربوط به این برنامه مثال را کنترل می کند. همین الان برو و بازش کن
در بالای فایل باید نظر // مرحله 6 - مسیر مدل را تنظیم کنید. اینجاست که به برنامه خود میگویید کجا میتواند فایلهای مدلی را که برای تولید تصویر ضروری هستند پیدا کند. برای این مثال، مقدار /data/local/tmp/image_generator/bins/ را تنظیم میکنید.
// Step 6 - set model path
private val MODEL_PATH = "/data/local/tmp/image_generator/bins/"
از آنجا به سمت پایین به تابع ()generatorImage بروید. در پایین این تابع، هر دو مرحله 7 و 8 را مشاهده خواهید کرد که به ترتیب برای تولید تصاویر با تکرارهای بازگشتی یا بدون هیچ کدام استفاده خواهند شد. از آنجایی که هر دوی این عملیات به صورت همزمان انجام می شوند، متوجه خواهید شد که در یک کوروتین پیچیده شده اند. میتوانید با جایگزین کردن // مرحله 7 شروع کنید - بدون نشان دادن تکرار با این بلوک کد برای فراخوانی Generation() از فایل ImageGenerationHelper ، سپس وضعیت رابط کاربری را بهروزرسانی کنید.
// Step 7 - Generate without showing iterations
val result = helper?.generate(prompt, iteration, seed)
_uiState.update {
it.copy(outputBitmap = result)
}
مرحله 8 کمی پیچیده تر می شود. از آنجایی که تابع execute() تنها یک مرحله را به جای تمام مراحل برای تولید تصویر انجام می دهد، باید هر مرحله را به صورت جداگانه از طریق یک حلقه فراخوانی کنید. همچنین باید تعیین کنید که آیا مرحله فعلی باید برای کاربر نمایش داده شود یا خیر. در نهایت، اگر تکرار فعلی نمایش داده شود، وضعیت رابط کاربری را به روز می کنید. اکنون می توانید همه این کارها را انجام دهید.
// Step 8 - Generate with showing iterations
helper?.setInput(prompt, iteration, seed)
for (step in 0 until iteration) {
isDisplayStep =
(displayIteration > 0 && ((step + 1) % displayIteration == 0))
val result = helper?.execute(isDisplayStep)
if (isDisplayStep) {
_uiState.update {
it.copy(
outputBitmap = result,
generatingMessage = "Generating... (${step + 1}/$iteration)",
)
}
}
}
در این مرحله باید بتوانید برنامه خود را نصب کنید، تولید کننده تصویر را مقداردهی اولیه کنید و سپس یک تصویر جدید بر اساس یک اعلان متن ایجاد کنید.
... با این تفاوت که اکنون وقتی می خواهید مولد تصویر را مقداردهی اولیه کنید، برنامه از کار می افتد. دلیل این اتفاق این است که باید فایل های مدل خود را در دستگاه خود کپی کنید. برای دریافت به روزترین اطلاعات در مورد مدل های شخص ثالث شناخته شده برای کار، تبدیل آنها برای این کار MediaPipe و کپی کردن آنها در دستگاه خود، می توانید این بخش از اسناد رسمی را مرور کنید.
علاوه بر کپی کردن فایل ها به طور مستقیم در دستگاه توسعه خود، همچنین می توانید Firebase Storage را راه اندازی کنید تا فایل های لازم را مستقیماً در دستگاه کاربر در زمان اجرا دانلود کند.
5. برنامه را مستقر و آزمایش کنید
پس از همه اینها، شما باید یک برنامه کاربردی داشته باشید که بتواند یک پیام متنی را بپذیرد و تصاویر جدید را کاملاً روی دستگاه تولید کند! ادامه دهید و برنامه را روی یک دستگاه اندرویدی فیزیکی برای آزمایش آن نصب کنید، هرچند به یاد داشته باشید که میخواهید این کار را با دستگاهی با حداقل 8 گیگابایت حافظه امتحان کنید.
- روی Run کلیک کنید (
) در نوار ابزار اندروید استودیو برای اجرای برنامه.
- نوع مراحل تولید (نهایی یا با تکرار) را انتخاب کنید و سپس دکمه INITIALIZE را فشار دهید.
- در صفحه بعدی، هر ویژگی را که می خواهید تنظیم کنید و روی دکمه GENERATE کلیک کنید تا ببینید ابزار چه چیزی را ارائه می دهد.
6. تبریک می گویم!
تو انجامش دادی! در این کد لبه یاد گرفتهاید که چگونه تولید متن به تصویر روی دستگاه را به برنامه اندروید اضافه کنید.
مراحل بعدی
کارهای بیشتری می توانید با کار تولید تصویر انجام دهید، از جمله
- با استفاده از یک تصویر پایه برای ساختاربندی تصاویر تولید شده از طریق پلاگین ها، یا آموزش وزن های LoRA اضافی خود از طریق Vertex AI.
- از Firebase Storage برای بازیابی فایل های مدل در دستگاه خود بدون نیاز به استفاده از ابزار ADB استفاده کنید.
ما مشتاقانه منتظر دیدن همه چیزهای جالبی هستیم که با این کار آزمایشی می سازید، و مراقب کدها و محتوای بیشتری از تیم MediaPipe باشیم!