دليل إنشاء الصور لنظام التشغيل Android

تتيح لك مهمة "أداة إنشاء الصور" من MediaPipe إنشاء صور استنادًا إلى طلب نصي. تستخدِم هذه المهمّة نموذج تحويل النص إلى صورة لإنشاء صور باستخدام تقنيات الانتشار.

تقبل المهمة طلبًا نصيًا كمدخل، بالإضافة إلى صورة شرطية اختيارية يمكن للنموذج تحسينها واستخدامها كمرجع لإنشاء الصور. يمكن أن ينشئ "أداة إنشاء الصور" أيضًا صورًا استنادًا إلى مفاهيم محدّدة يتم تقديمها للنموذج أثناء التدريب أو إعادة التدريب. لمزيد من المعلومات، يُرجى الاطّلاع على مقالة التخصيص باستخدام تقنية LoRA.

يتوفّر نموذج الرمز البرمجي الموضّح في هذه التعليمات على GitHub. لمزيد من المعلومات عن الإمكانات والنماذج وخيارات الضبط لهذه المهمة، اطّلِع على نظرة عامة.

مثال على الرمز البرمجي

مثال رمز MediaPipe Tasks هو تطبيق أساسي لإنشاء صور على نظام التشغيل Android. يمكنك استخدام التطبيق كنقطة بداية لتطبيق Android الخاص بك، أو الرجوع إليه عند تعديل تطبيق حالي. يتم استضافة مثال رمز "أداة إنشاء الصور" على GitHub.

تنزيل الرمز

توضّح لك التعليمات التالية كيفية إنشاء نسخة محلية من مثال الرمز البرمجي باستخدام أداة سطر الأوامر git.

لتنزيل نموذج الرمز البرمجي:

  1. استنسِخ مستودع git باستخدام الأمر التالي:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. يمكنك اختياريًا ضبط مثيل git لاستخدام ميزة "الفحص الخفيف"، بحيث تتوفّر لديك فقط الملفات الخاصة بتطبيق مثال "أداة إنشاء الصور":
    cd mediapipe
    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، بما في ذلك requirements لإصدار النظام الأساسي، يُرجى الاطّلاع على دليل الإعداد لنظام Android.

التبعيات

تستخدِم مهمة "أداة إنشاء الصور" مكتبة com.google.mediapipe:tasks-vision-image-generator. أضِف هذا الملحق إلى ملف build.gradle لتطبيق Android:

dependencies {
    implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'
}

بالنسبة إلى الأجهزة التي تعمل بالإصدار 12 من Android (المستوى 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 نموذجًا أساسيًا مدرَّبًا ومتوافقًا مع هذه المهمة. بعد تنزيل نموذج، ثبِّت التبعيات المطلوبة و احوِّل النموذج إلى تنسيق مناسب. بعد ذلك، أرسِل النموذج المحوَّل إلى جهاز Android.

لمزيد من المعلومات عن النماذج المدربة المتاحة لتطبيق "أداة إنشاء الصور"، يُرجى الاطّلاع على قسم "النماذج" ضمن النظرة العامة على المهمة.

تنزيل نموذج الأساس

يتطلّب "أداة إنشاء الصور" أن يتطابق النموذج الأساسي مع تنسيق runwayml/stable-diffusion-v1-5 EMA-only، استنادًا إلى النموذج التالي: runwayml/stable-diffusion-v1-5.

تثبيت التبعيات وتحويل النموذج

$ 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 أو تنزيلها عند الطلب. نماذج المكوّنات الإضافية خفيفة الوزن (حوالي 23 ميغابايت) ويمكن تجميعها مباشرةً في حزمة APK. ومع ذلك، ننصحك بتنزيل نماذج الإضافات عند الطلب.

إذا خصّصت نموذجًا باستخدام LoRA، يمكنك تنزيله عند الطلب. لمزيد من المعلومات، اطّلِع على نموذج المكوّن الإضافي لوزن LoRA.

أنشئ المهمة.

تستخدِم مهمة "أداة إنشاء الصور" من MediaPipe الدالة createFromOptions() لإعداد المهمة. تقبل الدالة createFromOptions() قيمًا لإعدادات options. لمزيد من المعلومات حول خيارات الضبط، يُرجى الاطّلاع على خيارات الضبط.

خيارات الضبط

تتضمّن هذه المهمة خيارات الضبط التالية لتطبيقات Android:

اسم الخيار الوصف نطاق القيمة
imageGeneratorModelDirectory دليل نموذج إنشاء الصور الذي يخزِّن أوزان النموذج PATH
loraWeightsFilePath لضبط المسار إلى ملف أوزان LoRA اختياري ولا ينطبق إلا إذا تم تخصيص النموذج باستخدام LoRA. PATH
errorListener تُستخدَم لضبط مستمع أخطاء اختياري. N/A

تتيح المهمة أيضًا استخدام نماذج المكونات الإضافية، ما يتيح للمستخدمين تضمين صور الشروط في إدخال المهمة، ويمكن للنموذج الأساسي تحسينها واستخدامها كمرجع لإنشاء الصور. يمكن أن تكون هذه الصور المشروطة معالم الوجه وخطوط الحواف واقتباسات العمق التي يستخدمها النموذج كسياق ومعلومات إضافية لإنشاء الصور.

عند إضافة نموذج مكوّن إضافي إلى نموذج الأساس، عليك أيضًا ضبط خيارات المكوّن الإضافي. يستخدم المكوّن الإضافي "معالم الوجه" faceConditionOptions، ويستخدم المكوّن الإضافي "حواف Canny" edgeConditionOptions، ويستخدم المكوّن الإضافي "العمق" depthConditionOptions.

خيارات الحواف الحادة

اضبط الخيارات التالية في edgeConditionOptions.

اسم الخيار الوصف نطاق القيمة القيمة التلقائية
threshold1 الحدّ الأول لإجراء التباطؤ Float 100
threshold2 الحدّ الثاني لإجراء التباطؤ Float 200
apertureSize حجم فتحة عدسة عامل التشغيل Sobel يتراوح النطاق المعتاد بين 3 و7. Integer 3
l2Gradient ما إذا كان سيتم استخدام معيار L2 لاحتساب شدة تدرج الصورة، بدلاً من معيار L1 التلقائي BOOLEAN False
EdgePluginModelBaseOptions عنصر BaseOptions الذي يحدّد المسار لنموذج المكوّن الإضافي عنصر BaseOptions N/A

لمزيد من المعلومات حول آلية عمل خيارات الضبط هذه، يُرجى الاطّلاع على مقالة كاشف الحواف باستخدام تقنية Canny.

خيارات معالم الوجه

اضبط الخيارات التالية في 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)

إعداد البيانات

يقبل "أداة إنشاء الصور" الإدخالات التالية:

  • الطلب (مطلوب): الطلب النصي الذي يصف الصورة المطلوب إنشاؤها.
  • iterations (سمة مطلوبة): إجمالي عدد التكرارات لإنشاء الصورة. ننصح بتحديد 20 كنقطة بداية جيدة.
  • seed (مطلوبة): القيمة الأساسية العشوائية المستخدَمة أثناء إنشاء الصورة.
  • صورة الحالة (اختيارية): الصورة التي يستخدمها النموذج كمرجع لعمليات المعالجة لا ينطبق إلا عند استخدام نموذج مكوّن إضافي.
  • نوع الشرط (اختياري): نوع نموذج المكوّن الإضافي المستخدَم مع المهمة. لا ينطبق ذلك إلا عند استخدام نموذج مكوّن إضافي.

المدخلات التي تتضمّن النموذج الأساسي فقط

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)
}

بعد إنشاء صورة الشرط، أدرِج الصورة كمدخل مع الطلب والبذرة وعدد التكرارات.

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
  • عدد التكرارات: 20

الصورة التي تم إنشاؤها: