Görüntü analizi

Görüntü analizi kullanım alanı, uygulamanıza görüntü işleme, bilgisayar görüşü veya makine öğrenimi çıkarımı gerçekleştirebileceğiniz, CPU tarafından erişilebilen bir görüntü sağlar. Uygulama her çerçevede çalıştırılan bir analyze() yöntemi uygular.

Google'ın Makine Öğrenimi Kiti'ni CameraX uygulamanızla nasıl entegre edeceğinizi öğrenmek için ML Kit Analiz Aracı sayfasına göz atın.

Çalışma Modları

Uygulamanın analiz ardışık düzeni CameraX'in kare hızı gereksinimlerini karşılayamadığında CameraX, aşağıdaki yöntemlerden biriyle kare bırakacak şekilde yapılandırılabilir:

  • non-blocking (varsayılan): Bu modda, uygulama önceki resmi analiz ederken yürütme aracı her zaman en son resmi bir görüntü arabelleğinde önbelleğe alır (bir derinliği olan sıraya benzer). CameraX, uygulamanın işlenmesi tamamlanmadan yeni bir görüntü alırsa yeni görüntü aynı arabelleğe kaydedilir ve önceki görüntünün üzerine yazılır. ImageAnalysis.Builder.setImageQueueDepth() öğesinin bu senaryoda herhangi bir etkisi yoktur ve arabellek içeriklerinin her zaman üzerine yazıldığını unutmayın. Engelleyici olmayan bu modu, STRATEGY_KEEP_ONLY_LATEST ile setBackpressureStrategy() yöntemini çağırarak etkinleştirebilirsiniz. Yürütücü sonuçları hakkında daha fazla bilgi için STRATEGY_KEEP_ONLY_LATEST referans belgelerine bakın.

  • blocking: Bu modda, dahili yürütücü, dahili resim sırasına birden fazla resim ekleyebilir ve yalnızca sıra dolduğunda kareleri bırakmaya başlar. Engelleme, kamera cihazının kapsamının tamamında gerçekleşir: Kamera cihazının birden çok sınırlı kullanım alanı varsa CameraX bu görüntüleri işlerken bu kullanım alanlarının tamamı engellenir. Örneğin, hem önizleme hem de görüntü analizi bir Kamera cihazına bağlandığında, CameraX resimleri işlerken önizleme de engellenir. STRATEGY_BLOCK_PRODUCER parametresini setBackpressureStrategy() hedefine ileterek engelleme modunu etkinleştirebilirsiniz. Görüntü sırası derinliğini ImageAnalysis.Builder.setImageQueueDepth() kullanarak da yapılandırabilirsiniz.

Bir resmin analiz edilmesi için toplam sürenin bir CameraX karesinin süresinden (örneğin 60 fps için 16 ms) kısa olduğu düşük gecikmeli ve yüksek performanslı analizcide, iki çalışma modu da sorunsuz bir genel deneyim sağlar. Engelleme modu, bazı durumlarda (örneğin, çok kısa sistem dalgalanmalarıyla başa çıkmak için) yine de yararlı olabilir.

Yüksek gecikme ve yüksek performanslı analiz aracı kullanıldığında gecikmeyi telafi etmek için daha uzun sıraya sahip engelleme modu gerekir. Yine de, uygulamanın tüm kareleri yine de işleyebileceğini unutmayın.

Analiz yolu için karelerin çıkarılması gerektiğinden (analiz aracı tüm çerçeveleri işleyemez) yüksek gecikme ve çok zaman alan analiz aracı ile daha uygun bir seçim olabilir. Ancak diğer eşzamanlı bağlı kullanım alanları, tüm kareleri görmeye devam edebilir.

Uygulama

Uygulamanızda görüntü analizini kullanmak için şu adımları izleyin:

Bağlamanın hemen ardından CameraX, görüntüleri kayıtlı analizcinize gönderir. Analizi tamamladıktan sonra ImageAnalysis.clearAnalyzer() çağrısı yapın veya analizi durdurmak için ImageAnalysis kullanım alanının bağlantısını kaldırın.

ImageAnalysis kullanım alanı derleme

ImageAnalysis analiz aracınızı (görüntü tüketicisi) bir görüntü üreticisi olan CameraX'e bağlar. Uygulamalar bir ImageAnalysis nesnesi derlemek için ImageAnalysis.Builder kullanabilir. ImageAnalysis.Builder ile uygulama aşağıdakileri yapılandırabilir:

Uygulamalar, çözünürlüğü veya en boy oranını ayarlayabilir, ancak ikisini birden ayarlayamaz. Kesin çıkış çözünürlüğü, uygulamanın istenen boyutuna (veya en boy oranına) ve donanım özelliklerine bağlıdır ve istenen boyut veya orandan farklı olabilir. Çözünürlük eşleştirme algoritması hakkında bilgi için setTargetResolution() belgelerine bakın.

Uygulamalar, çıkış resmi piksellerini YUV (varsayılan) veya RGBA renk alanlarında olacak şekilde yapılandırabilir. Bir RGBA çıkış biçimi ayarlarken CameraX, resimleri dahili olarak YUV'den RGBA renk alanına dönüştürür ve aşağıdaki sırayı kullanarak resim bitlerini ImageProxy'nin ilk düzleminin ByteBuffer içine ekler (diğer iki düzlem kullanılmaz):

ImageProxy.getPlanes()[0].buffer[0]: alpha
ImageProxy.getPlanes()[0].buffer[1]: red
ImageProxy.getPlanes()[0].buffer[2]: green
ImageProxy.getPlanes()[0].buffer[3]: blue
...

Cihazın kare hızına yetişemediği karmaşık görüntü analizi gerçekleştirirken bu konunun İşletim Modları bölümünde açıklanan stratejilerle CameraX'i kare atacak şekilde yapılandırabilirsiniz.

Analiz aracınızı oluşturma

Uygulamalar, ImageAnalysis.Analyzer arayüzünü uygulayıp analyze(ImageProxy image) kodunu geçersiz kılarak analiz araçları oluşturabilir. Her analiz edicide, uygulamalar Media.Image için sarmalayıcı olan bir ImageProxy alır. Resim biçimi, ImageProxy.getFormat() ile sorgulanabilir. Biçim, uygulamanın ImageAnalysis.Builder ile sağladığı aşağıdaki değerlerden biridir:

  • Uygulama OUTPUT_IMAGE_FORMAT_RGBA_8888 istediyse ImageFormat.RGBA_8888.
  • Uygulama OUTPUT_IMAGE_FORMAT_YUV_420_888 istediyse ImageFormat.YUV_420_888.

Renk alanı yapılandırmaları ve piksel baytlarının nereden alınabileceği hakkında bilgi edinmek için ImageAnalysis oluşturma kullanım alanına bakın.

Uygulama, analizci içinde aşağıdakileri yapmalıdır:

  1. Belirli bir kareyi mümkün olduğunca hızlı bir şekilde ve tercihen verilen kare hızı süre sınırı dahilinde analiz edin (örneğin, 30 fps'de 32 ms'den az). Uygulama bir kareyi yeterince hızlı analiz edemiyorsa desteklenen kare bırakma mekanizmalarından birini kullanmayı düşünün.
  2. ImageProxy.close() numaralı telefonu arayarak ImageProxy adlı kamerayı CameraX'e bırakın. Sarmalanmış Media.Image'ın kapat işlevini (Media.Image.close()) çağırmamanız gerektiğini unutmayın.

Uygulamalar, doğrudan ImageProxy'nin içindeki sarmalanmış Media.Image öğesini kullanabilir. Ancak sarmalanmış resimde Media.Image.close() işlevini çağırmayın. Aksi takdirde, CameraX içindeki görüntü paylaşım mekanizması bozulur. Bunun yerine, alttaki Media.Image öğesini CameraX'e serbest bırakmak için ImageProxy.close() değerini kullanın.

ImageAnalysis için analiz aracınızı yapılandırma

Analiz aracı oluşturduğunuzda, analize başlamak için bu aracı kaydetmek üzere ImageAnalysis.setAnalyzer() aracını kullanın. Analizi bitirdikten sonra kayıtlı analizciyi kaldırmak için ImageAnalysis.clearAnalyzer() aracını kullanın.

Görüntü analizi için yalnızca bir etkin analiz edici yapılandırılabilir. ImageAnalysis.setAnalyzer() çağrısı, zaten mevcutsa kayıtlı analizcinin yerini alır. Uygulamalar, kullanım alanını bağlamadan önce veya bağladıktan sonra herhangi bir zamanda yeni bir analiz aracı ayarlayabilir.

ImageAnalysis'i Yaşam Döngüsüne Bağlama

ImageAnalysis öğenizi, ProcessCameraProvider.bindToLifecycle() işleviyle mevcut bir AndroidX yaşam döngüsüne bağlamanız önerilir. bindToLifecycle() işlevinin, seçilen Camera cihazı döndürdüğünü ve bu cihazın pozlama ve diğer gelişmiş ayarlarda hassas düzenlemeler yapmak için kullanılabileceğini unutmayın. Kamera çıkışını kontrol etme hakkında daha fazla bilgi için bu kılavuza bakın.

Aşağıdaki örnekte, önceki adımlardan CameraX ImageAnalysis ve Preview kullanım alanlarının bir lifeCycle sahibine bağlanması dahil olmak üzere her şey birleştirilmiştir:

Kotlin

val imageAnalysis = ImageAnalysis.Builder()
    // enable the following line if RGBA output is needed.
    // .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
    .setTargetResolution(Size(1280, 720))
    .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
    .build()
imageAnalysis.setAnalyzer(executor, ImageAnalysis.Analyzer { imageProxy ->
    val rotationDegrees = imageProxy.imageInfo.rotationDegrees
    // insert your code here.
    ...
    // after done, release the ImageProxy object
    imageProxy.close()
})

cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, imageAnalysis, preview)

Java

ImageAnalysis imageAnalysis =
    new ImageAnalysis.Builder()
        // enable the following line if RGBA output is needed.
        //.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
        .setTargetResolution(new Size(1280, 720))
        .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
        .build();

imageAnalysis.setAnalyzer(executor, new ImageAnalysis.Analyzer() {
    @Override
    public void analyze(@NonNull ImageProxy imageProxy) {
        int rotationDegrees = imageProxy.getImageInfo().getRotationDegrees();
            // insert your code here.
            ...
            // after done, release the ImageProxy object
            imageProxy.close();
        }
    });

cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, imageAnalysis, preview);

Ek kaynaklar

CameraX hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynaklara bakın.

Kod laboratuvarı

  • CameraX'i Kullanmaya Başlama
  • Kod örneği

  • CameraX örnek uygulamaları