1. Başlamadan önce
Kod yazmak, kas hafızası oluşturmak ve materyali daha iyi anlamak için harika bir yöntemdir. Kopyalama ve yapıştırma zaman kazandırsa da bu uygulamaya yatırım yapmak uzun vadede daha fazla verimlilik ve daha güçlü kodlama becerileri sağlayabilir.
Bu codelab'de, Google'ın TensorFlow Lite için yeni çalışma zamanı olan LiteRT'yi kullanarak canlı kamera feed'inde gerçek zamanlı görüntü segmentasyonu gerçekleştiren bir Android uygulaması oluşturmayı öğreneceksiniz. Başlangıç Android uygulamasını alıp buna görüntü segmentasyonu özellikleri ekleyeceksiniz. Ayrıca ön işleme, çıkarım ve son işleme adımlarını da inceleyeceğiz. Bu kurstan sonra:
- Görüntüleri gerçek zamanlı olarak segmentlere ayıran bir Android uygulaması oluşturun.
- Önceden eğitilmiş bir LiteRT görüntü segmentasyonu modelini entegre edin.
- Giriş resmini model için önceden işleyin.
- CPU ve GPU hızlandırması için LiteRT çalışma zamanını kullanın.
- Segmentasyon maskesini görüntülemek için modelin çıkışını nasıl işleyeceğinizi öğrenin.
- Ön kameraya göre nasıl ayarlama yapacağınızı öğrenin.
Sonunda, aşağıdaki resme benzer bir şey oluşturursunuz:

Ön koşullar
Bu codelab, makine öğrenimi konusunda deneyim kazanmak isteyen deneyimli mobil geliştiriciler için tasarlanmıştır. Aşağıdaki konular hakkında bilgi sahibi olmanız gerekir:
- Kotlin ve Android Studio ile Android geliştirme
- Görüntü işlemenin temel kavramları
Neler öğreneceksiniz?
- LiteRT çalışma zamanını Android uygulamasına entegre etme ve kullanma
- Önceden eğitilmiş bir LiteRT modeli kullanarak görüntü segmentasyonu gerçekleştirme
- Giriş görüntüsünü model için nasıl önceden işleyeceğiniz.
- Model için çıkarım çalıştırma.
- Sonuçları görselleştirmek için segmentasyon modelinin çıkışını işleme
- Gerçek zamanlı kamera feed'i işleme için CameraX'i kullanma
İhtiyacınız olanlar
- Android Studio'nun son sürümlerinden biri (v2025.1.1'de test edilmiştir).
- Fiziksel bir Android cihaz. En iyi test Galaxy ve Pixel cihazlarda yapılır.
- Örnek kod (GitHub'dan).
- Kotlin ile Android geliştirmeye ilişkin temel bilgiler
2. Görüntü Segmentasyonu
Görüntü segmentasyonu, bir görüntüyü birden fazla segmente veya bölgeye ayırmayı içeren bir bilgisayar görme görevidir. Nesne algılama, bir nesnenin etrafına sınırlayıcı kutu çizerken görüntü segmentasyonu, görüntüdeki her bir piksele belirli bir sınıf veya etiket atar. Bu sayede, resmin içeriği hakkında çok daha ayrıntılı ve ayrıntılı bir anlayış elde edebilir, her nesnenin tam şeklini ve sınırını öğrenebilirsiniz.
Örneğin, bir kutuda yalnızca bir "kişi" olduğunu bilmek yerine, bu kişiye ait piksellerin hangileri olduğunu tam olarak öğrenebilirsiniz. Bu eğiticide, önceden eğitilmiş bir makine öğrenimi modeli kullanarak Android cihazda gerçek zamanlı görüntü segmentasyonu işleminin nasıl yapılacağı gösterilmektedir.

LiteRT: Cihazda makine öğreniminin sınırlarını zorlama
Mobil cihazlarda gerçek zamanlı ve yüksek doğrulukta segmentasyon sağlayan temel teknolojilerden biri LiteRT'dir. TensorFlow Lite için Google'ın yeni nesil, yüksek performanslı çalışma zamanı olan LiteRT, temel donanımdan mutlak en iyi performansı elde etmek üzere tasarlanmıştır.
Bu, GPU (Grafik İşlem Birimi) ve NPU (Nöral İşlem Birimi) gibi donanım hızlandırıcıların akıllı ve optimize edilmiş kullanımıyla sağlanır. LiteRT, segmentasyon modelinin yoğun hesaplama iş yükünü genel amaçlı CPU'dan bu özel işlemcilere aktararak çıkarım süresini önemli ölçüde kısaltır. Bu hızlandırma, karmaşık modellerin canlı kamera feed'inde sorunsuz bir şekilde çalıştırılmasını mümkün kılar ve makine öğrenimiyle doğrudan telefonunuzda yapabileceklerimizin sınırlarını genişletir. Bu performans seviyesi olmadan, gerçek zamanlı segmentasyon iyi bir kullanıcı deneyimi için çok yavaş ve kesintili olurdu.
3. Hazırlanın
Depoyu klonlama
Öncelikle LiteRT deposunu klonlayın:
git clone https://github.com/google-ai-edge/litert-samples.git
litert-samples/v2/image_segmentation, ihtiyacınız olan tüm kaynakların bulunduğu dizindir. Bu kod laboratuvarı için yalnızca kotlin_cpu_gpu/android_starter projesine ihtiyacınız olacak. Takılırsanız bitmiş projeyi inceleyebilirsiniz: kotlin_cpu_gpu/android
Dosya yollarıyla ilgili not
Bu eğitimde, dosya yolları Linux/macOS biçiminde belirtilir. Windows kullanıyorsanız yolları buna göre ayarlamanız gerekir.
Android Studio proje görünümü ile standart dosya sistemi görünümü arasındaki ayrımı da belirtmek önemlidir. Android Studio proje görünümü, Android geliştirme için düzenlenmiş proje dosyalarınızın yapılandırılmış bir gösterimidir. Bu eğitimdeki dosya yolları, Android Studio proje görünümündeki yolları değil, dosya sistemi yollarını ifade eder.
Başlangıç uygulamasını içe aktarma
Başlangıç uygulamasını Android Studio'ya aktararak başlayalım.
- Android Studio'yu açın ve Open'ı (Aç) seçin.

kotlin_cpu_gpu/android_starterdizinine gidip dizini açın.

Tüm bağımlılıkların uygulamanızda kullanılabilir olduğundan emin olmak için içe aktarma işlemi tamamlandığında projenizi Gradle dosyalarıyla senkronize etmeniz gerekir.
- Android Studio araç çubuğundan Projeyi Gradle Dosyalarıyla Senkronize Et'i seçin.

- Lütfen bu adımı atlamayın. Bu adım işe yaramazsa eğitimin geri kalanı anlaşılmaz.
Başlangıç uygulamasını çalıştırma
Projeyi Android Studio'ya aktardığınıza göre artık uygulamayı ilk kez çalıştırmaya hazırsınız.
Android cihazınızı USB ile bilgisayarınıza bağlayın ve Android Studio araç çubuğunda Çalıştır'ı tıklayın.

Uygulama, cihazınızda başlatılmalıdır. Canlı kamera feed'i görürsünüz ancak henüz segmentasyon yapılmaz. Bu eğitimde yapacağınız tüm dosya düzenlemeleri litert-samples/v2/image_segmentation/kotlin_cpu_gpu/android_starter/app/src/main/java/com/google/ai/edge/examples/image_segmentation dizininde yer alır (Android Studio'nun bu dizini neden yeniden yapılandırdığını artık biliyorsunuz 😃).

Ayrıca TODO yorumlarını ImageSegmentationHelper.kt, MainViewModel.kt ve view/SegmentationOverlay.kt dosyalarında da görürsünüz. Aşağıdaki adımlarda, bu TODO'ları doldurarak görüntü segmentasyonu işlevini uygulayacaksınız.
4. Başlangıç uygulamasını anlama
Başlangıç uygulamasında temel bir kullanıcı arayüzü ve kamera işleme mantığı zaten vardır. Aşağıda, önemli dosyalara hızlı bir genel bakış verilmiştir:
app/src/main/java/com/google/ai/edge/examples/image_segmentation/MainActivity.kt: Bu, uygulamanın ana giriş noktasıdır. Jetpack Compose kullanarak kullanıcı arayüzünü oluşturur ve kamera izinlerini yönetir.app/src/main/java/com/google/ai/edge/examples/image_segmentation/MainViewModel.kt: Bu ViewModel, kullanıcı arayüzü durumunu yönetir ve görüntü segmentasyonu sürecini düzenler.app/src/main/java/com/google/ai/edge/examples/image_segmentation/ImageSegmentationHelper.kt: Görüntü segmentasyonu için temel mantığı buraya ekleyeceğiz. Modelin yüklenmesi, kamera karelerinin işlenmesi ve çıkarımın çalıştırılması bu kitaplık tarafından gerçekleştirilir.app/src/main/java/com/google/ai/edge/examples/image_segmentation/view/CameraScreen.kt: Bu Composable işlevi, kamera önizlemesini ve vücudu bölme yer paylaşımını gösterir.app/download_model.gradle: Bu komut dosyasıselfie_multiclass.tfliteindirir. Bu, kullanacağımız önceden eğitilmiş TensorFlow Lite görüntü segmentasyonu modelidir.
5. LiteRT'yi anlama ve bağımlılık ekleme
Şimdi de başlangıç uygulamasına görüntü segmentasyonu işlevini ekleyelim.
1. LiteRT bağımlılığını ekleme
Öncelikle LiteRT kitaplığını projenize eklemeniz gerekir. Bu, Google'ın optimize edilmiş çalışma zamanı ile cihaz üzerinde makine öğrenimini etkinleştirmenin ilk ve en önemli adımıdır.
app/build.gradle.kts dosyasını açın ve aşağıdaki satırı dependencies bloğuna ekleyin:
// LiteRT for on-device ML
implementation(libs.litert)
Bağımlılığı ekledikten sonra Android Studio'nun sağ üst köşesinde görünen Şimdi Senkronize Et düğmesini tıklayarak projenizi Gradle dosyalarıyla senkronize edin.

2. Key LiteRT API'lerini Anlama
AçImageSegmentationHelper.kt
Uygulama kodunu yazmadan önce, kullanacağınız LiteRT API'nin temel bileşenlerini anlamanız önemlidir. com.google.ai.edge.litert paketinden içe aktardığınızdan emin olun ve ImageSegmentationHelper.kt dosyasının en üstüne aşağıdaki içe aktarma işlemlerini ekleyin:
import com.google.ai.edge.litert.Accelerator
import com.google.ai.edge.litert.CompiledModel
CompiledModel: Bu, TFLite modelinizle etkileşim kurmak için kullanılan merkezi sınıftır. Belirli bir donanım hızlandırıcı (CPU veya GPU gibi) için önceden derlenmiş ve optimize edilmiş bir modeli temsil eder. Bu ön derleme, LiteRT'nin temel bir özelliğidir ve daha hızlı ve verimli çıkarım sağlar.CompiledModel.Options:CompiledModelöğesini yapılandırmak için bu oluşturucu sınıfını kullanırsınız. En önemli ayar, modelinizi çalıştırmak için kullanmak istediğiniz donanım hızlandırıcıyı belirtmektir.Accelerator: Bu enum, çıkarım için donanımı seçmenize olanak tanır. Başlangıç projesi, şu seçenekleri işleyecek şekilde yapılandırılmıştır:Accelerator.CPU: Modeli cihazın CPU'sunda çalıştırmak için. Bu, en evrensel uyumluluğa sahip seçenektir.Accelerator.GPU: Modeli cihazın GPU'sunda çalıştırmak için. Bu, genellikle görüntü tabanlı modeller için CPU'dan çok daha hızlıdır.
- Giriş ve Çıkış Arabellekleri (
TensorBuffer): LiteRT, model girişleri ve çıkışları içinTensorBufferkullanır. Bu sayede, bellek üzerinde ayrıntılı kontrol sahibi olursunuz ve gereksiz veri kopyalarını önlersiniz. Bu arabelleklerimodel.createInputBuffers()vemodel.createOutputBuffers()kullanarak doğrudanCompiledModelörneğinizden alırsınız. Ardından giriş verilerinizi bu arabelleklere yazıp sonuçları bu arabelleklerden okursunuz. model.run(): Bu, çıkarımı yürüten işlevdir. Giriş ve çıkış arabelleklerini LiteRT'ye iletirsiniz. LiteRT, modeli seçilen donanım hızlandırıcıda çalıştırma gibi karmaşık görevleri yönetir.
6. İlk ImageSegmentationHelper Uygulamasını Tamamlama
Şimdi biraz kod yazma zamanı. ImageSegmentationHelper.kt'nın ilk uygulamasını tamamlayacaksınız. Bu işlem, LiteRT modelini tutmak için Segmenter özel sınıfını ayarlamayı ve düzgün şekilde yayınlamak için cleanup() işlevini uygulamayı içerir.
Segmentersınıfını vecleanup()işlevini tamamlama:ImageSegmentationHelper.ktdosyasında,Segmenteradlı özel bir sınıfın vecleanup()adlı bir işlevin iskeletini bulacaksınız. İlk olarak,Segmentersınıfını tamamlayın. Bunun için sınıfın oluşturucusunu modeli tutacak şekilde tanımlayın, giriş/çıkış arabellekleri için özellikler oluşturun ve modeli serbest bırakacak birclose()yöntemi ekleyin. Ardından, bu yeniclose()yöntemini çağırmak içincleanup()işlevini uygulayın. MevcutSegmentersınıfını vecleanup()işlevini aşağıdakilerle değiştirin: (~83. satır)private class Segmenter( // Add this argument private val model: CompiledModel, private val coloredLabels: List<ColoredLabel>, ) { // Add these private vals private val inputBuffers = model.createInputBuffers() private val outputBuffers = model.createOutputBuffers() fun cleanup() { // cleanup buffers inputBuffers.forEach { it.close() } outputBuffers.forEach { it.close() } // cleanup model model.close() } }- toAccelerator yöntemini tanımlayın: Bu yöntem, tanımlanan hızlandırıcı numaralandırmalarını hızlandırıcı menüsünden içe aktarılan LiteRT modüllerine özgü hızlandırıcı numaralandırmalarıyla eşler (~225. satır):
fun toAccelerator(acceleratorEnum: AcceleratorEnum): Accelerator { return when (acceleratorEnum) { AcceleratorEnum.CPU -> Accelerator.CPU AcceleratorEnum.GPU -> Accelerator.GPU } } CompiledModelişlevini başlatın: ŞimdiinitSegmenterişlevini bulun.CompiledModelörneğini burada oluşturacak ve artık tanımlanmış olanSegmentersınıfınızı örneklendirmek için kullanacaksınız. Bu kod, modeli belirtilen hızlandırıcıyla (CPU veya GPU) kurar ve çıkarıma hazırlar.initSegmenteriçindekiTODOöğesini aşağıdaki uygulamayla değiştirin (Cmd/Ctrl+f "initSegmenter" veya ~62. satır):cleanup() try { withContext(singleThreadDispatcher) { val model = CompiledModel.create( context.assets, "selfie_multiclass.tflite", CompiledModel.Options(toAccelerator(acceleratorEnum)), null, ) segmenter = Segmenter(model, coloredLabels) Log.d(TAG, "Created an image segmenter") } } catch (e: Exception) { Log.i(TAG, "Create LiteRT from selfie_multiclass is failed: ${e.message}") _error.emit(e) }
7. Segmentasyon ve Ön İşleme İşlemini Başlatma
Artık bir modelimiz olduğuna göre, segmentasyon sürecini tetiklememiz ve giriş verilerini model için hazırlamamız gerekiyor.
Tetikleyici Segmentasyonu
Segmentasyon süreci, kameradan kareler alan MainViewModel.kt içinde başlar.
AçMainViewModel.kt
- Kamera Çerçevelerinden Segmentasyonu Tetikleme:
MainViewModeliçindekisegmentişlevleri, segmentasyon görevimizin giriş noktasıdır. Kameradan yeni bir resim geldiğinde veya galeriden bir resim seçildiğinde çağrılırlar. Bu işlevler daha sonraImageSegmentationHelperiçindekisegmentyöntemini çağırır. Her ikisegmentişlevindekiTODO'ları aşağıdakiyle değiştirin (satır ~107):// For ImageProxy (from CameraX) fun segment(imageProxy: ImageProxy) { segmentJob = viewModelScope.launch { imageSegmentationHelper.segment(imageProxy.toBitmap(), imageProxy.imageInfo.rotationDegrees) imageProxy.close() } } // For Bitmaps (from gallery) fun segment(bitmap: Bitmap, rotationDegrees: Int) { segmentJob = viewModelScope.launch { val argbBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true) imageSegmentationHelper.segment(argbBitmap, rotationDegrees) } }
Resmi Önceden İşleme
Şimdi de resim ön işlemesini yapmak için ImageSegmentationHelper.kt'ye geri dönelim.
AçImageSegmentationHelper.kt
- Public
segmentişlevini uygulama: Bu işlev,Segmentersınıfındaki özelsegmentişlevini çağıran bir sarmalayıcı görevi görür.TODOyerine şunu yazın (~line 95):try { withContext(singleThreadDispatcher) { segmenter?.segment(bitmap, rotationDegrees)?.let { if (isActive) _segmentation.emit(it) } } } catch (e: Exception) { Log.i(TAG, "Image segment error occurred: ${e.message}") _error.emit(e) } - Ön İşleme Uygulama:
Segmentersınıfındaki özelsegmentişlevi, giriş görüntüsünde modeli hazırlamak için gerekli dönüşümleri gerçekleştireceğimiz yerdir. Görüntüyü ölçeklendirme, döndürme ve normalleştirme bu kapsamdadır. Bu işlev daha sonra çıkarım işlemini gerçekleştirmek için başka bir özelsegmentişlevini çağırır.segment(bitmap: Bitmap, ...)işlevindekiTODOyerine şunu girin (~121. satır):val totalStartTime = SystemClock.uptimeMillis() val rotation = -rotationDegrees / 90 val (h, w) = Pair(256, 256) // Preprocessing val preprocessStartTime = SystemClock.uptimeMillis() var image = bitmap.scale(w, h, true) image = rot90Clockwise(image, rotation) val inputFloatArray = normalize(image, 127.5f, 127.5f) Log.d(TAG, "Preprocessing time: ${SystemClock.uptimeMillis() - preprocessStartTime} ms") // Inference val inferenceStartTime = SystemClock.uptimeMillis() val segmentResult = segment(inputFloatArray) Log.d(TAG, "Inference time: ${SystemClock.uptimeMillis() - inferenceStartTime} ms") Log.d(TAG, "Total segmentation time: ${SystemClock.uptimeMillis() - totalStartTime} ms") return SegmentationResult(segmentResult, SystemClock.uptimeMillis() - inferenceStartTime)
8. LiteRT ile birincil çıkarım
Giriş verileri önceden işlendiğinden artık LiteRT kullanarak temel çıkarım işlemini çalıştırabiliriz.
Açık ImageSegmentationHelper.kt
- Model Yürütmeyi Uygulama: Özel
segment(inputFloatArray: FloatArray)işlevi, LiteRTrun()yöntemiyle doğrudan etkileşim kurduğumuz yerdir. Ön işlenmiş verilerimizi giriş tamponuna yazarız, modeli çalıştırırız ve sonuçları çıkış tamponundan okuruz. Bu işlevdekiTODOyerine şunu yazın (~188. satır):val (h, w, c) = Triple(256, 256, 6) // MODEL EXECUTION PHASE val modelExecStartTime = SystemClock.uptimeMillis() // Write input data - measure time val bufferWriteStartTime = SystemClock.uptimeMillis() inputBuffers[0].writeFloat(inputFloatArray) val bufferWriteTime = SystemClock.uptimeMillis() - bufferWriteStartTime Log.d(TAG, "Buffer write time: $bufferWriteTime ms") // Optional tensor inspection logTensorStats("Input tensor", inputFloatArray) // Run model inference - measure time val modelRunStartTime = SystemClock.uptimeMillis() model.run(inputBuffers, outputBuffers) val modelRunTime = SystemClock.uptimeMillis() - modelRunStartTime Log.d(TAG, "Model.run() time: $modelRunTime ms") // Read output data - measure time val bufferReadStartTime = SystemClock.uptimeMillis() val outputFloatArray = outputBuffers[0].readFloat() val outputBuffer = FloatBuffer.wrap(outputFloatArray) val bufferReadTime = SystemClock.uptimeMillis() - bufferReadStartTime Log.d(TAG, "Buffer read time: $bufferReadTime ms") val modelExecTime = SystemClock.uptimeMillis() - modelExecStartTime Log.d(TAG, "Total model execution time: $modelExecTime ms") // Optional tensor inspection logTensorStats("Output tensor", outputFloatArray) // POSTPROCESSING PHASE val postprocessStartTime = SystemClock.uptimeMillis() // Process mask from model output val inferenceData = InferenceData(width = w, height = h, channels = c, buffer = outputBuffer) val mask = processImage(inferenceData) val postprocessTime = SystemClock.uptimeMillis() - postprocessStartTime Log.d(TAG, "Postprocessing time (mask creation): $postprocessTime ms") return Segmentation( listOf(Mask(mask, inferenceData.width, inferenceData.height)), coloredLabels, )
9. İşleme sonrası ve yer paylaşımını görüntüleme
Çıkarım çalıştırıldıktan sonra modelden ham çıktı elde edilir. Bu çıktıyı işleyerek görsel segmentasyon maskesi oluşturmamız ve ardından ekranda görüntülememiz gerekiyor.
Açık ImageSegmentationHelper.kt
- Çıktı İşlemeyi Uygula:
processImageişlevi, modelden gelen ham kayan nokta çıktısını, segmentasyon maskesini temsil eden birByteBufferöğesine dönüştürür. Bunu, her piksel için en yüksek olasılıklı sınıfı bularak yapar.TODOöğesini (~line 238) ile değiştirin:val mask = ByteBuffer.allocateDirect(inferenceData.width * inferenceData.height) for (i in 0 until inferenceData.height) { for (j in 0 until inferenceData.width) { val offset = inferenceData.channels * (i * inferenceData.width + j) var maxIndex = 0 var maxValue = inferenceData.buffer.get(offset) for (index in 1 until inferenceData.channels) { if (inferenceData.buffer.get(offset + index) > maxValue) { maxValue = inferenceData.buffer.get(offset + index) maxIndex = index } } mask.put(i * inferenceData.width + j, maxIndex.toByte()) } } return mask
Açık MainViewModel.kt
- Segmentasyon Sonuçlarını Toplama ve İşleme: Şimdi
ImageSegmentationHelper'den gelen segmentasyon sonuçlarını işlemek içinMainViewModel'ye geri dönüyoruz.segmentationUiShareFlow,SegmentationResulttoplar, maskeyi renkli birBitmaphaline getirir ve kullanıcı arayüzüne sunar.segmentationUiShareFlowmülkündekiTODOyerine (~63. satır) ifadesini girin. Burada mevcut kodu değiştirmeyin, yalnızca gövdeyi doldurun:viewModelScope.launch { imageSegmentationHelper.segmentation .filter { it.segmentation.masks.isNotEmpty() } .map { val segmentation = it.segmentation val mask = segmentation.masks[0] val maskArray = mask.data val width = mask.width val height = mask.height val pixelSize = width * height val pixels = IntArray(pixelSize) val colorLabels = segmentation.coloredLabels.mapIndexed { index, coloredLabel -> ColorLabel(index, coloredLabel.label, coloredLabel.argb) } // Set color for pixels for (i in 0 until pixelSize) { val colorLabel = colorLabels[maskArray[i].toInt()] val color = colorLabel.getColor() pixels[i] = color } // Get image info val overlayInfo = OverlayInfo(pixels = pixels, width = width, height = height) val inferenceTime = it.inferenceTime Pair(overlayInfo, inferenceTime) } .collect { flow.emit(it) } }
Açview/SegmentationOverlay.kt
Son olarak, kullanıcı ön kameraya geçtiğinde segmentasyon yer paylaşımını doğru şekilde yönlendirmek gerekir. Kamera feed'i, ön kamera için doğal olarak yansıtılır. Bu nedenle, kaplamamızın Bitmap kamera önizlemesiyle doğru şekilde hizalanmasını sağlamak için aynı yatay çevirme işlemini uygulamamız gerekir.
- Handle Overlay Orientation:
SegmentationOverlay.ktdosyasındaTODOifadesini bulun ve aşağıdaki kodla değiştirin. Bu kod, ön kameranın etkin olup olmadığını kontrol eder. EtkinseCanvasüzerine çizilmeden önce yer paylaşımınaBitmapyatay çevirme uygular. (~line 42):val orientedBitmap = if (lensFacing == CameraSelector.LENS_FACING_FRONT) { // Create a matrix for horizontal flipping val matrix = Matrix().apply { preScale(-1f, 1f) } Bitmap.createBitmap(image, 0, 0, image.width, image.height, matrix, false).also { image.recycle() } } else { image }
10. Son Uygulamayı Çalıştırma ve Kullanma
Gerekli tüm kod değişikliklerini tamamladınız. Uygulamayı çalıştırmanın ve çalışmanızı görmenin zamanı geldi.
- Uygulamayı çalıştırma: Android cihazınızı bağlayın ve Android Studio araç çubuğunda Run'ı (Çalıştır) tıklayın.

- Özellikleri Test Etme: Uygulama başlatıldıktan sonra, renkli bir segmentasyon katmanıyla birlikte canlı kamera feed'ini görmeniz gerekir.
- Kameralar Arasında Geçiş Yapma: Ön ve arka kameralar arasında geçiş yapmak için üst kısımdaki kamera çevirme simgesine dokunun. Yerleşimin nasıl doğru şekilde yönlendirildiğine dikkat edin.
- Hızlandırıcıyı değiştirme: Donanım hızlandırıcıyı değiştirmek için alttaki "CPU" veya "GPU" düğmesine dokunun. Ekranın alt kısmında gösterilen Çıkarım Süresi'ndeki değişikliği gözlemleyin. GPU çok daha hızlı olmalıdır.
- Galeri resmini kullanma: Cihazınızın fotoğraf galerisinden bir resim seçmek için üstteki "Galeri" sekmesine dokunun. Uygulama, seçilen statik görüntüde segmentasyon gerçekleştirir.

Artık LiteRT tarafından desteklenen, tam işlevli ve gerçek zamanlı bir görüntü segmentasyonu uygulamanız var.
11. Gelişmiş (İsteğe bağlı): NPU'yu kullanma
Bu depoda, uygulama sürümünün Nöral İşleme Birimleri (NPUs) için optimize edilmiş bir versiyonu da bulunur. NPU sürümü, uyumlu NPU'ya sahip cihazlarda önemli bir performans artışı sağlayabilir.
NPU sürümünü denemek için Android Studio'da kotlin_npu/android projesini açın. Kod, CPU/GPU sürümüne çok benzer ve NPU temsilcisini kullanacak şekilde yapılandırılmıştır.
NPU temsilcisini kullanmak için erken erişim programına kaydolmanız gerekir.
12. Tebrikler!
LiteRT kullanarak gerçek zamanlı görüntü segmentasyonu gerçekleştiren bir Android uygulamasını başarıyla oluşturdunuz. Öğrendikleriniz:
- LiteRT çalışma zamanını bir Android uygulamasına entegre edin.
- Bir TFLite görüntü segmentasyon modeli yükleyin ve çalıştırın.
- Modelin girişini önceden işleyin.
- Segmentasyon maskesi oluşturmak için modelin çıkışını işleyin.
- Anlık kamera uygulaması için CameraX'i kullanın.
Sonraki Adımlar
- Farklı bir görüntü segmentasyonu modeli deneyin.
- Farklı LiteRT temsilcileriyle (CPU, GPU, NPU) denemeler yapın.