মিডিয়াপাইপের সাথে অ্যান্ড্রয়েডে ডিভাইসে ইমেজ জেনারেশন

1. ভূমিকা

মিডিয়াপাইপ কি?

MediaPipe সলিউশন আপনাকে আপনার অ্যাপে মেশিন-লার্নিং (ML) সমাধান প্রয়োগ করতে দেয়। এটি পূর্বনির্মাণ প্রক্রিয়াকরণ পাইপলাইনগুলি কনফিগার করার জন্য একটি কাঠামো প্রদান করে যা ব্যবহারকারীদের কাছে অবিলম্বে, আকর্ষক এবং দরকারী আউটপুট সরবরাহ করে। এমনকি আপনি ডিফল্ট মডেলগুলি আপডেট করতে MediaPipe মডেল মেকারের সাথে এই সমাধানগুলির অনেকগুলি কাস্টমাইজ করতে পারেন৷

টেক্সট-টু-ইমেজ জেনারেশন হল মিডিয়াপাইপ সলিউশনের অফার করা একাধিক এমএল টাস্কের মধ্যে একটি।

এই কোডল্যাবে, আপনি একটি বেশিরভাগ-বেয়ার অ্যান্ড্রয়েড অ্যাপ দিয়ে শুরু করবেন, তারপর একাধিক ধাপে অগ্রসর হবেন যতক্ষণ না আপনি সরাসরি আপনার অ্যান্ড্রয়েড ডিভাইসে নতুন ছবি তৈরি করতে সক্ষম হন।

আপনি কি শিখবেন

  • মিডিয়াপিপ টাস্ক সহ একটি অ্যান্ড্রয়েড অ্যাপে স্থানীয়ভাবে চলমান টেক্সট-টু-ইমেজ জেনারেশন কীভাবে বাস্তবায়ন করবেন।

আপনি কি প্রয়োজন হবে

  • অ্যান্ড্রয়েড স্টুডিওর একটি ইনস্টল করা সংস্করণ (এই কোডল্যাবটি অ্যান্ড্রয়েড স্টুডিও জিরাফের সাথে লেখা এবং পরীক্ষা করা হয়েছিল)।
  • কমপক্ষে 8GB RAM সহ একটি Android ডিভাইস।
  • অ্যান্ড্রয়েড বিকাশের প্রাথমিক জ্ঞান এবং একটি পূর্ব-লিখিত পাইথন স্ক্রিপ্ট চালানোর ক্ষমতা।

2. Android অ্যাপে MediaPipe টাস্ক যোগ করুন

অ্যান্ড্রয়েড স্টার্টার অ্যাপটি ডাউনলোড করুন

এই কোডল্যাবটি UI সমন্বিত একটি পূর্ব-তৈরি নমুনা দিয়ে শুরু হবে যা চিত্র তৈরির একটি মৌলিক সংস্করণের জন্য ব্যবহার করা হবে। আপনি এখানে অফিসিয়াল MediaPipe নমুনা রেপোতে সেই প্রারম্ভিক অ্যাপটি খুঁজে পেতে পারেন। রেপো ক্লোন করুন বা কোড > জিপ ডাউনলোড করুন ক্লিক করে জিপফাইলটি ডাউনলোড করুন।

অ্যাপটি অ্যান্ড্রয়েড স্টুডিওতে আমদানি করুন

  1. অ্যান্ড্রয়েড স্টুডিও খুলুন।
  2. ওয়েলকাম টু অ্যান্ড্রয়েড স্টুডিও স্ক্রীন থেকে, উপরের ডানদিকে কোণায় খুলুন নির্বাচন করুন।

a0b5b070b802e4ea.png

  1. আপনি যেখানে সংগ্রহস্থলটি ক্লোন করেছেন বা ডাউনলোড করেছেন সেখানে নেভিগেট করুন এবং codelabs/image_generation_basic/android/start ডিরেক্টরি খুলুন।
  2. এই পর্যায়ে অ্যাপটি কম্পাইল করা উচিত নয় কারণ আপনি এখনও MediaPipe টাস্ক নির্ভরতা অন্তর্ভুক্ত করেননি।

আপনি অ্যাপটি ঠিক করবেন এবং build.gradle ফাইলে গিয়ে এবং নিচে স্ক্রোল করে // ধাপ 1 - নির্ভরতা যোগ করে এটিকে চালু করবেন। সেখান থেকে, নিম্নলিখিত লাইনটি অন্তর্ভুক্ত করুন এবং তারপরে Android স্টুডিওর শীর্ষে ব্যানারে প্রদর্শিত সিঙ্ক নাও বোতামটি টিপুন৷

// Step 1 - Add dependency
implementation 'com.google.mediapipe:tasks-vision-image-generator:latest.release'

একবার সিঙ্কিং সম্পন্ন হলে, সবুজ রান তীরটিতে ক্লিক করে সবকিছু সঠিকভাবে খোলা এবং ইনস্টল করা হয়েছে কিনা তা যাচাই করুন ( 7e15a9c9e1620fe7.png ) অ্যান্ড্রয়েড স্টুডিওর উপরের ডানদিকে। আপনি দুটি রেডিও বোতাম এবং ইনিটিয়ালাইজ লেবেলযুক্ত একটি বোতাম সহ একটি স্ক্রিনে অ্যাপটি খোলা দেখতে পাবেন। আপনি যদি সেই বোতামটিতে ক্লিক করেন, তাহলে আপনাকে অবিলম্বে একটি পৃথক UI-এ নিয়ে যাওয়া উচিত যাতে একটি পাঠ্য প্রম্পট এবং GENERATE লেবেলযুক্ত একটি বোতামের পাশাপাশি অন্যান্য বিকল্পগুলি থাকে।

83c31de8e8a320ee.png78b8765e832024e3.png

দুর্ভাগ্যবশত এটি স্টার্টার অ্যাপের পরিমাণ সম্পর্কে, তাই আপনি কীভাবে এই অ্যাপটি শেষ করবেন এবং আপনার ডিভাইসে নতুন ছবি তৈরি করা শুরু করবেন তা শেখার সময় এসেছে!

3. ইমেজ জেনারেটর সেট আপ করা

এই উদাহরণের জন্য, বেশিরভাগ ইমেজ তৈরির কাজ ImageGenerationHelper.kt ফাইলে ঘটবে। আপনি যখন এই ফাইলটি খুলবেন, আপনি ক্লাসের উপরের দিকে একটি ভেরিয়েবল লক্ষ্য করবেন যার নাম imageGenerator। এটি সেই টাস্ক অবজেক্ট যা আপনার ইমেজ জেনারেশন অ্যাপে ভারী উত্তোলন করবে।

সেই অবজেক্টের ঠিক নীচে আপনি নিম্নলিখিত মন্তব্য সহ initializeImageGenerator() নামে একটি ফাংশন দেখতে পাবেন: // ধাপ 2 - ইমেজ জেনারেটর শুরু করুন। আপনি অনুমান করতে পারেন, এখানেই আপনি ImageGenerator অবজেক্ট শুরু করবেন। ইমেজ জেনারেশন মডেল পাথ সেট করতে এবং ইমেজজেনারেটর অবজেক্ট শুরু করতে নিম্নলিখিত কোড দিয়ে ফাংশন বডিটি প্রতিস্থাপন করুন:

// Step 2 - initialize the image generator
val options = ImageGeneratorOptions.builder()
    .setImageGeneratorModelDirectory(modelPath)
    .build()

imageGenerator = ImageGenerator.createFromOptions(context, options)

এর নিচে আপনি setInput() নামে আরেকটি ফাংশন দেখতে পাবেন। এটি তিনটি পরামিতি গ্রহণ করে: একটি প্রম্পট স্ট্রিং যা জেনারেট করা চিত্রকে সংজ্ঞায়িত করতে ব্যবহার করা হবে, নতুন চিত্র তৈরি করার সময় টাস্কের পুনরাবৃত্তির সংখ্যা এবং একটি বীজের মান যা একটি চিত্র ভিত্তিক নতুন সংস্করণ তৈরি করতে ব্যবহার করা যেতে পারে। একই বীজ ব্যবহার করার সময় একই চিত্র তৈরি করার সময় একই প্রম্পটে। এই ফাংশনের উদ্দেশ্য হল ইমেজ জেনারেটরের জন্য এই প্রাথমিক পরামিতিগুলি সেট করা যখন আপনি একটি ছবি তৈরি করার চেষ্টা করেন যা মধ্যবর্তী ধাপগুলি প্রদর্শন করে

এগিয়ে যান এবং setInput() বডিটি প্রতিস্থাপন করুন (যেখানে আপনি মন্তব্য দেখতে পাবেন // ধাপ 3 - ইনপুট গ্রহণ করুন) এই লাইনটি দিয়ে:

// Step 3 - accept inputs
imageGenerator.setInputs(prompt, iteration, seed)

পরবর্তী দুটি ধাপ যেখানে প্রজন্ম সঞ্চালিত হয়। generate() ফাংশন সেটইনপুট হিসাবে একই ইনপুট গ্রহণ করে, কিন্তু একটি এক-শট কল হিসাবে একটি চিত্র তৈরি করে যা কোনো মধ্যবর্তী ধাপের চিত্র ফেরত দেয় না। আপনি এই ফাংশনের মূল অংশটি প্রতিস্থাপন করতে পারেন (যাতে মন্তব্য অন্তর্ভুক্ত রয়েছে // ধাপ 4 - পুনরাবৃত্তি না দেখিয়ে তৈরি করুন)

// Step 4 - generate without showing iterations
val result = imageGenerator.generate(prompt, iteration, seed)
val bitmap = BitmapExtractor.extract(result?.generatedImage())
return bitmap

এটা জানা গুরুত্বপূর্ণ যে এই কাজটি সিঙ্ক্রোনাসভাবে ঘটে, তাই আপনাকে একটি ব্যাকগ্রাউন্ড থ্রেড থেকে ফাংশনটি কল করতে হবে। আপনি এই কোডল্যাবে একটু পরে এটি সম্পর্কে আরও শিখবেন।

এই ফাইলটিতে আপনি যে চূড়ান্ত পদক্ষেপটি নেবেন তা হল execute() ফাংশনটি পূরণ করা (পদক্ষেপ 5 হিসাবে লেবেল করা)। এটি একটি প্যারামিটার গ্রহণ করবে যা এটিকে বলে যে এটি একটি মধ্যবর্তী চিত্র ফেরত দেবে কি না প্রজন্মের একক ধাপের জন্য যা ImageGenerator execute() ফাংশনের সাথে সঞ্চালিত হবে। এই কোড দিয়ে ফাংশন বডি প্রতিস্থাপন করুন:

// 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 ফাইলটি এই উদাহরণ অ্যাপের সাথে সম্পর্কিত UI অবস্থা এবং অন্যান্য যুক্তি পরিচালনা করবে। এগিয়ে যান এবং এখন এটি খুলুন.

ফাইলের উপরের দিকে আপনি মন্তব্য দেখতে পাবেন // ধাপ 6 - মডেল পাথ সেট করুন। এখানেই আপনি আপনার অ্যাপকে বলবেন যেখানে এটি ইমেজ তৈরির জন্য প্রয়োজনীয় মডেল ফাইলগুলি খুঁজে পেতে পারে। এই উদাহরণের জন্য আপনি মান সেট করবেন /data/local/tmp/image_generator/bins/।

// Step 6 - set model path
private val MODEL_PATH = "/data/local/tmp/image_generator/bins/"

সেখান থেকে, generateImage() ফাংশনে নিচে স্ক্রোল করুন। এই ফাংশনের নীচের দিকে আপনি ধাপ 7 এবং ধাপ 8 উভয়ই দেখতে পাবেন, যা যথাক্রমে ফিরে আসা পুনরাবৃত্তি বা কোনটি না দিয়ে ছবি তৈরি করতে ব্যবহৃত হবে। যেহেতু এই দুটি ক্রিয়াকলাপ সিঙ্ক্রোনাসভাবে ঘটে, আপনি লক্ষ্য করবেন যে তারা একটি কোরোটিনে মোড়ানো। আপনি প্রতিস্থাপনের মাধ্যমে শুরু করতে পারেন // ধাপ 7 - ImageGenerationHelper ফাইল থেকে generate() কল করতে কোডের এই ব্লকের সাথে পুনরাবৃত্তি না দেখিয়ে জেনারেট করুন, তারপর UI অবস্থা আপডেট করুন।

// Step 7 - Generate without showing iterations
val result = helper?.generate(prompt, iteration, seed)
_uiState.update {
    it.copy(outputBitmap = result)
}

ধাপ 8 একটু trickier পায়. যেহেতু execute() ফাংশন ইমেজ তৈরির জন্য সমস্ত ধাপের পরিবর্তে শুধুমাত্র একটি ধাপ সঞ্চালন করে, আপনাকে লুপের মাধ্যমে প্রতিটি ধাপকে পৃথকভাবে কল করতে হবে। বর্তমান পদক্ষেপটি ব্যবহারকারীর জন্য প্রদর্শিত হবে কিনা তাও আপনাকে নির্ধারণ করতে হবে। অবশেষে, বর্তমান পুনরাবৃত্তি প্রদর্শিত হলে আপনি UI অবস্থা আপডেট করবেন। আপনি এখন এই সব করতে পারেন.

// 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 স্টোরেজ সেট আপ করাও সম্ভব।

5. অ্যাপটি স্থাপন এবং পরীক্ষা করুন

এত কিছুর পরে, আপনার একটি কার্যকরী অ্যাপ থাকা উচিত যা একটি পাঠ্য প্রম্পট গ্রহণ করতে পারে এবং সম্পূর্ণরূপে ডিভাইসে নতুন ছবি তৈরি করতে পারে! এগিয়ে যান এবং অ্যাপটিকে পরীক্ষা করার জন্য একটি শারীরিক অ্যান্ড্রয়েড ডিভাইসে স্থাপন করুন, যদিও মনে রাখবেন যে আপনি কমপক্ষে 8GB মেমরি সহ একটি ডিভাইসের সাথে এটি চেষ্টা করতে চাইবেন।

  1. রান ক্লিক করুন ( 7e15a9c9e1620fe7.png ) অ্যাপটি চালানোর জন্য অ্যান্ড্রয়েড স্টুডিও টুলবারে।
  2. প্রজন্মের ধাপের ধরন নির্বাচন করুন (চূড়ান্ত বা পুনরাবৃত্তি সহ) এবং তারপরে শুরু বোতাম টিপুন।
  3. পরবর্তী স্ক্রিনে, আপনি যে কোনো বৈশিষ্ট্য সেট করুন এবং টুলটি কী নিয়ে আসে তা দেখতে জেনারেট বোতামে ক্লিক করুন।

e46cfaeb9d3fc235.gif

6. অভিনন্দন!

আপনি এটা করেছেন! এই কোডল্যাবে আপনি শিখেছেন কিভাবে একটি Android অ্যাপে অন-ডিভাইস টেক্সট-টু-ইমেজ জেনারেশন যোগ করতে হয়।

পরবর্তী পদক্ষেপ

ইমেজ জেনারেশন টাস্ক সহ আপনি আরও অনেক কিছু করতে পারেন

  • প্লাগইনগুলির মাধ্যমে তৈরি করা চিত্রগুলিকে গঠন করতে একটি বেস ইমেজ ব্যবহার করে, অথবা Vertex AI এর মাধ্যমে আপনার নিজের অতিরিক্ত LoRA ওজন প্রশিক্ষণ দিন।
  • ADB টুল ব্যবহার না করে আপনার ডিভাইসে মডেল ফাইল পুনরুদ্ধার করতে Firebase স্টোরেজ ব্যবহার করুন।

আমরা এই পরীক্ষামূলক কাজটি দিয়ে আপনার তৈরি করা দুর্দান্ত জিনিসগুলি দেখার অপেক্ষায় রয়েছি, এবং MediaPipe টিমের আরও বেশি কোডল্যাব এবং সামগ্রীর জন্য নজর রাখুন!