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

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

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

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

مثال على الرمز

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

تنزيل الرمز

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

لتنزيل نموذج الرمز البرمجي، اتّبِع الخطوات التالية:

  1. استنسِخ مستودع git باستخدام الأمر التالي:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. يمكنك اختياريًا ضبط مثيل git لاستخدام sparse checkout، وذلك حتى لا يتوفّر لديك سوى ملفات تطبيق Image Generator النموذجي:
    cd mediapipe-samples
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_generation/android
    

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

المكوّنات الرئيسية

تحتوي الملفات التالية على الرمز الأساسي لمثال إنشاء الصور هذا التطبيق:

  • ImageGenerationHelper.kt: تتم تهيئة المهمة والتعامل مع عملية إنشاء الصور.
  • DiffusionActivity.kt: إنشاء صور عندما لا تكون المكوّنات الإضافية أو أوزان LoRA مفعَّلة
  • PluginActivity.kt: تنفِّذ هذه السمة نماذج المكوّن الإضافي التي تتيح للمستخدمين تقديم صورة شرطية كإدخال.
  • LoRAWeightActivity.kt: تتيح هذه السمة الوصول إلى أوزان LoRA والتعامل معها، وهي تُستخدم لتخصيص النماذج الأساسية وتمكينها من إنشاء صور لمفاهيم معيّنة.

الإعداد

يوضّح هذا القسم الخطوات الأساسية لإعداد بيئة التطوير ومشاريع الرموز البرمجية لاستخدام "أداة إنشاء الصور" تحديدًا. للحصول على معلومات عامة حول إعداد بيئة التطوير لاستخدام مهام MediaPipe، بما في ذلك متطلبات إصدار النظام الأساسي، راجِع دليل الإعداد لنظام التشغيل 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.

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

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

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

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

إنشاء المهمة

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

خيارات الإعداد

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

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

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

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

خيارات Canny edge

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

اسم الخيار الوصف نطاق القيم القيمة التلقائية
threshold1 الحدّ الأول لإجراء التباطؤ Float 100
threshold2 الحدّ الثاني لإجراء التباطؤ. Float 200
apertureSize حجم فتحة عامل تشغيل Sobel. يتراوح النطاق المعتاد بين 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)

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

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

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

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

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
}

الإنشاء التكراري

يمكن أن تعرض &quot;أداة إنشاء الصور&quot; أيضًا الصور الوسيطة التي تم إنشاؤها أثناء كل تكرار، كما هو محدّد في مَعلمة الإدخال 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

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

صورة تم إنشاؤها لراكون تتوافق مع الطلب