MediaPipe ile Android'de Cihaz Üzerinde Resim Oluşturma

1. Giriş

MediaPipe nedir?

MediaPipe Çözümleri, makine öğrenimi (ML) çözümlerini uygulamalarınıza uygulamanıza olanak tanır. Kullanıcılara anında, ilgi çekici ve faydalı çıktılar sağlayan önceden oluşturulmuş işleme işlem hatlarını yapılandırmak için bir çerçeve sunar. Hatta varsayılan modelleri güncellemek için bu çözümlerin birçoğunu MediaPipe Model Maker ile özelleştirebilirsiniz.

Metinden görüntü oluşturma, MediaPipe Çözümleri'nin sunduğu çeşitli makine öğrenimi görevlerinden biridir.

Bu Codelab'de, neredeyse boş bir Android uygulamasıyla başlayacak, ardından doğrudan Android cihazınızda yeni resimler oluşturabilene kadar çeşitli adımları tamamlayacaksınız.

Neler öğreneceksiniz?

  • MediaPipe Görevleri ile Android uygulamasında yerel olarak çalışan metinden görüntü oluşturma özelliğini uygulama

İhtiyacınız olanlar

  • Android Studio'nun yüklü bir sürümü (bu codelab, Android Studio Giraffe ile yazılmış ve test edilmiştir).
  • En az 8 GB RAM'e sahip bir Android cihaz olmalıdır.
  • Android geliştirme hakkında temel düzeyde bilgi ve önceden yazılmış bir Python komut dosyasını çalıştırma becerisi.

2. Android uygulamasına MediaPipe Görevleri'ni ekleme

Android başlangıç uygulamasını indirin

Bu codelab'de, görüntü üretmenin temel sürümünde kullanılacak kullanıcı arayüzünden oluşan önceden hazırlanmış bir örnekle başlayacağız. Başlangıç uygulamasını resmi MediaPipe Samples deposunda burada bulabilirsiniz. Depoyu klonlayın veya Kodu > ZIP olarak indir'i tıklayarak ZIP dosyasını indirin.

Uygulamayı Android Studio'ya aktarma

  1. Android Studio'yu açın.
  2. Welcome to Android Studio (Android Studio'ya Hoş Geldiniz) ekranında sağ üst köşedeki Open'ı (Aç) seçin.

a0b5b070b802e4ea.png

  1. Depoyu klonladığınız veya indirdiğiniz yere gidin ve codelabs/image_generation_basic/android/start dizinini açın.
  2. Bu aşamada, MediaPipe Görevleri bağımlılığını henüz eklemediğiniz için uygulama derlenmemelidir.

Uygulamayı düzeltip çalıştırmak için build.gradle dosyasına gidip // Step 1 - Add dependency. (1. adım: Bağımlılık ekleyin) bölümüne gidin. Buradan aşağıdaki satırı ekleyin ve ardından Android Studio'nun üst kısmındaki banner'da görünen Şimdi Senkronize Et düğmesine basın.

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

Senkronizasyon tamamlandıktan sonra Android Studio'nun sağ üst kısmındaki yeşil çalıştır okunu ( 7e15a9c9e1620fe7.png) tıklayarak her şeyin doğru şekilde açıldığını ve yüklendiğini doğrulayın. Uygulama, iki radyo düğmesi ve INITIALIZE (Başlat) etiketli bir düğme içeren bir ekranda açılır. Bu düğmeyi tıkladığınızda, metin istemi ve diğer seçeneklerin yanı sıra OLUŞTUR etiketli bir düğmeden oluşan ayrı bir kullanıcı arayüzüne yönlendirilirsiniz.

83c31de8e8a320ee.png 78b8765e832024e3.png

Başlangıç uygulaması maalesef bu kadar. Artık bu uygulamayı nasıl tamamlayacağınızı öğrenme ve cihazınızda yeni resimler oluşturmaya başlama zamanı!

3. Görsel Oluşturucu'yu ayarlama

Bu örnekte, resim oluşturma işinin büyük kısmı ImageGenerationHelper.kt dosyasında gerçekleşir. Bu dosyayı açtığınızda, sınıfın üst kısımlarında imageGenerator adlı bir değişken görürsünüz. Bu, görüntü üretme uygulamanızda işin zor kısmını yapacak olan Görev nesnesidir.

Bu nesnenin hemen altında, aşağıdaki yorumu içeren initializeImageGenerator() adlı bir işlev görürsünüz: // 2. Adım: Görüntü üretme aracını başlatın. Tahmin edebileceğiniz gibi, ImageGenerator nesnesini burada başlatacaksınız. Resim üretme modeli yolunu ayarlamak ve ImageGenerator nesnesini ilk kullanıma hazırlamak için bu işlev gövdesini aşağıdaki kodla değiştirin:

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

imageGenerator = ImageGenerator.createFromOptions(context, options)

Bunun altında setInput() adlı başka bir fonksiyon görürsünüz. Bu işlev üç parametre kabul eder: oluşturulan yapay görüntüyü tanımlamak için kullanılacak bir istem dizesi, yeni yapay görüntüyü oluştururken Görev'in geçmesi gereken iterasyon sayısı ve aynı isteme dayalı olarak bir yapay görüntünün yeni sürümlerini oluşturmak için kullanılabilecek bir çekirdek değer. Aynı çekirdek değer kullanıldığında aynı yapay görüntü oluşturulur. Bu işlevin amacı, ara adımları gösteren bir resim oluşturmaya çalıştığınızda görüntü üretme aracı için bu ilk parametreleri ayarlamaktır.

setInput() gövdesini (burada // 3. Adım - girişleri kabul et yorumunu görürsünüz) aşağıdaki satırla değiştirin:

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

Üretim, sonraki iki adımda gerçekleşir. generate() işlevi, setInput ile aynı girişleri kabul eder ancak herhangi bir ara adım resmi döndürmeyen tek seferlik bir çağrı olarak resim oluşturur. Bu işlevin gövdesini (// 4. Adım - yinelemeleri göstermeden oluşturma yorumunu içerir) aşağıdakilerle değiştirebilirsiniz:

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

Bu görevin eşzamanlı olarak gerçekleştiğini ve bu nedenle işlevi bir arka plan iş parçacığından çağırmanız gerektiğini bilmeniz önemlidir. Bu konu hakkında daha fazla bilgiyi bu codelab'in ilerleyen bölümlerinde edineceksiniz.

Bu dosyada yapacağınız son adım, execute() işlevini (5. adım olarak etiketlenmiştir) doldurmaktır. Bu işlev, ImageGenerator execute() işleviyle gerçekleştirilecek tek adımlık oluşturma işlemi için ara resim döndürüp döndürmeyeceğini belirten bir parametreyi kabul eder. İşlev gövdesini aşağıdaki kodla değiştirin:

// 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

Yardımcı dosya için yapmanız gerekenler bu kadar. Sonraki bölümde, bu örneğin mantığını işleyen ViewModel dosyasını dolduracaksınız.

4. Uygulamayı bir araya getirme

MainViewModel dosyası, kullanıcı arayüzü durumlarını ve bu örnek uygulamayla ilgili diğer mantığı işler. Şimdi dosyayı açın.

Dosyanın üst kısımlarında // Step 6 - set model path yorumunu görmeniz gerekir. Bu bölümde, uygulamanıza görüntü üretme için gerekli olan model dosyalarını nerede bulabileceğini söyleyeceksiniz. Bu örnekte değeri /data/local/tmp/image_generator/bins/ olarak ayarlayacaksınız.

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

Buradan aşağı kaydırarak generateImage() işlevine gidin. Bu işlevin alt kısmına doğru, sırasıyla döndürülen yinelemelerle veya yineleme olmadan resim oluşturmak için kullanılacak olan 7. ve 8. adımı görürsünüz. Bu işlemlerin her ikisi de eşzamanlı olarak gerçekleştiğinden bunların bir eş yordam içinde sarmalandığını görürsünüz. Öncelikle ImageGenerationHelper dosyasından generate() işlevini çağırmak için // Step 7 - Generate without showing iterations ifadesini bu kod bloğuyla değiştirerek başlayabilir, ardından kullanıcı arayüzü durumunu güncelleyebilirsiniz.

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

8. adım biraz daha karmaşıktır. execute() işlevi, görüntü üretme için tüm adımları değil yalnızca bir adımı gerçekleştirdiğinden her adımı bir döngü aracılığıyla ayrı ayrı çağırmanız gerekir. Ayrıca, mevcut adımın kullanıcıya gösterilip gösterilmeyeceğini de belirlemeniz gerekir. Son olarak, mevcut yinelemenin gösterilmesi gerekiyorsa kullanıcı arayüzü durumunu güncelleyeceksiniz. Tüm bunları şimdi yapabilirsiniz.

// 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)",
            )
        }
    }
}

Bu noktada uygulamanızı yükleyebilmeniz, görüntü üretme aracını ilk kullanıma hazırlayabilmeniz ve ardından metin istemine dayalı yeni bir görüntü oluşturabilmeniz gerekir.

... ancak artık görüntü üretme aracını başlatmaya çalıştığınızda uygulama çöküyor. Bunun nedeni, model dosyalarınızı cihazınıza kopyalamanız gerektiğidir. Çalıştığı bilinen üçüncü taraf modelleri, bunları bu MediaPipe görevi için dönüştürme ve cihazınıza kopyalama hakkında en güncel bilgileri edinmek için resmi belgelerin bu bölümünü inceleyebilirsiniz.

Dosyaları doğrudan geliştirme cihazınıza kopyalamanın yanı sıra, Firebase Storage'ı gerekli dosyaları çalışma zamanında doğrudan kullanıcının cihazına indirecek şekilde de ayarlayabilirsiniz.

5. Uygulamayı dağıtma ve test etme

Tüm bu işlemlerin ardından, metin istemini kabul edip tamamen cihaz üzerinde yeni resimler oluşturabilen çalışan bir uygulamanız olur. Uygulamayı test etmek için fiziksel bir Android cihaza dağıtabilirsiniz. Ancak bu işlemi en az 8 GB belleğe sahip bir cihazla denemeniz gerektiğini unutmayın.

  1. Uygulamayı çalıştırmak için Android Studio araç çubuğunda Çalıştır'ı ( 7e15a9c9e1620fe7.png) tıklayın.
  2. Üretim adımlarının türünü (son veya yinelemeli) seçin ve BAŞLAT düğmesine basın.
  3. Sonraki ekranda istediğiniz özellikleri ayarlayın ve aracın ne gibi sonuçlar ürettiğini görmek için OLUŞTUR düğmesini tıklayın.

e46cfaeb9d3fc235.gif

6. Tebrikler!

Başardınız! Bu codelab'de, cihaz üzerinde metinden görüntü oluşturma özelliğini Android uygulamalarına nasıl ekleyeceğinizi öğrendiniz.

Sonraki adımlar

Görüntü üretme göreviyle yapabilecekleriniz arasında şunlar da yer alır:

  • Eklentiler aracılığıyla oluşturulan resimleri yapılandırmak için temel bir resim kullanma veya Vertex AI aracılığıyla kendi ek LoRA ağırlıklarınızı eğitme
  • ADB aracını kullanmanıza gerek kalmadan cihazınızdaki model dosyalarını almak için Firebase Storage'ı kullanın.

Bu deneysel görevle oluşturduğunuz tüm harika şeyleri görmeyi dört gözle bekliyoruz. MediaPipe ekibinin diğer codelab'lerini ve içeriklerini de takip etmeye devam edin.