👨🏼‍💻HMS 3D Modeling Kit ve Kotlin kullanarak Motion Capture uygulaması oluşturma

Ertug Sagman
Huawei Developers - Türkiye
4 min readJun 24, 2022
Temel vücut hareketi verilerinden 3D karaktere

Giriş

Herkese selam! Bugün canlı Motion Capture yapabileceğimiz Android uygulamasının nasıl geliştirileceğini anlatacağım. Bu projenin amacı, canlı bir kaydınızı 2B çizgi karakterine dönüştürmektir. Bunun için Huawei’nin 3D Modelling Kit dahilinde bulunan Motion Capture özelliği kullanılarak iskelet ve eklem verileri elde edilecektir. Bu verileri elde ettikten sonra, hareketlerimize uygun karakteri çizmek için bir OpenGL sahnesi kullanacağız. Motion Capture’dan gelen verileri kullanarak, aşağıdaki çıktıları eşleştirebiliriz:

  • Kare hızı: orta menzilli veya üst seviye çipli bir telefonda 30 fps’den fazla.
  • 24 anahtar iskelet noktasının aynı anda çıktısı (aşağıdaki şekilde gösterildiği gibi) ve 3B koordinatları ve kök eklemin 3B düzlemde konumsal parametresi.
Motion Capture servisinin iskelet noktası çıktıları

İşte Motion Capture ile yakalayabileceğimiz eklem ve kemiklerin yapısı. Kök eklemin kuaterniyonlar, 3B koordinatları ve başlangıç parametresi (manuel olarak nokta 0 olarak da belirtilebilir) numaralandırmaya vücudun sağ tarafından başlanacak şekilde koordinat sisteminde bulunur. Kuaterniyonlar kök eklemine göredir. 3B koordinatlar, kök eklemin göreli koordinatlarıdır. Kök eklemin başlangıç parametresi, bu koordinat sistemindeki kök eklemin mutlak koordinatlarıdır. Burada dikkat edilmesi gereken bir nokta var, servisin şu anki sürümü, yorucu eylemleri veya yüksek hızlı hareketleri algılamakta zorluk çekebilir. Özellikle oturur pozisyonundaki bacak ile üst gövde arasındaki açı, ayakta dururken oluşan açıdan farklı olmakta, bu tür eklemlerin birbiri üstüne denk gelebileceği pozisyonlarda sistemin verdiği çıktının tutarlılığı düşebilir.

Artık bu servisten tam olarak ne bekleyebileceğimizi bildiğimize göre, teknik ayrıntılara daha yakından bakalım.

Öncelikle Android Studio ve AppGallery Connect’te projemizi oluşturduktan sonra build.gradle dosyalarında bazı konfigürasyonlar yapmamız gerekiyor. Entegrasyonumuzu etkileyebilecek üç farklı build.gradle sürümü olduğundan, hangi yolu izlemeniz gerektiğini kontrol etmek için buraya bir bağlantı ekledim. Gradle işlemlerimiz tamamlandıktan sonra asıl geliştirmeye başlayabiliriz. İzinlerimizi ekleyerek ve bunları MainActivity’mizde isteyerek başlayalım.

İzin isteklerini azaltmak ve kolaylaştırmak için basit bir kütüphane kullandım.

implementation 'com.vmadalin:easypermissions-ktx:1.0.0'

Kamerayı açacağımız ve vücut hareketlerimiz için OpenGL sahnesini önizleyeceğimiz RecordAcvitity’mizi başlatmak için üstteki kod bloğunu ekliyoruz. RecordActivity’ye gitmek için MainActivity’de basit bir button ve gerekli setOnClickListener’ini ekleyerek içerisinde bu kodu çağırdım.

RecordActivity’ye geçtikten sonra buradaki hedefimize ulaşmak için tamamlamamız gereken birkaç adım var:

1 — Canlı kayıt verilerimizi Motion Capture motoruna aktarabilmemiz için kamera kaynağımızı hazırlamamız gerekiyor.

2 — Görüntülerimizi çekebilmeye başladıktan sonra, verilerimize gerekli ayarları uygulayabilmemiz ve OpenGL sahnemize işleyebilmemiz için bir temel işlemci tanımlayacağız.

3 — Verilerimizi görüntülemek üzere OpenGL sahnesine çizim yapmak için bir SurfaceView hazırlayacağız.

  • Bu arada, tüm sürecimizde bize yardımcı olacak ve kodu biraz daha temiz tutacak bazı yardımcı utility classlar tanımlayacağız.

Adımların gözünüzü korkutmasına izin vermeyin, bunlar çoğunlukla boilerplate kodlar ve bunları projelerinize olduğu gibi aktarabilirsiniz. Örneğin ilk adım olarak, görüntümüzü yakalayabilmek için bir kamera kaynağı ve kamera kaynağı önizlemesi uygulayacağız. Bu diğerlerinden biraz büyük bir class olduğu için makaleyi temiz tutmak için dahil etmeyeceğim, gerekli classları ‘CameraSource’ ve ‘CameraSourcePreview’ adıyla aşağıdaki github bağlantısından bulabilirsiniz. Ayrıca bu iki classın kullandığı ekstra bir class olan ‘GraphicOverlay’ bulunmakta. Bu classı da eklemeyi unutmayın.

CameraSource ve CameraSourcePreview classlarını başarıyla ekledikten sonra, HmsMotionProcessorBase classının ekleme işlemine geçebiliriz. Base class aşağıdaki gibidir:

Daha sonra kullanılmak üzere HmsMotionImageProcessor isimli basit bir interface oluşturuyoruz.

Son olarak, OpenGL kütüphanesi tarafından kullanılabilecek ‘anlamlı veri’ elde etmek için bir iskelet işlemci hazırlamalıyız.

Bu LocalSkeletonProcessor’da, interfaceimiz HmsMotionImageProcessor’u ekliyoruz ve ayrıca eklem, kuaternion ve kemik verilerimizi kendi koordinatlarına göre ayarlamaya yardımcı olması amacıyla FilterUtils adlı bir yardımcı class kullanıyoruz.

RecordActivity’mizde yine hazırlayacağımız BoneGLSurfaceView classı ile cameraSource’umuzu oluşturmalıyız. Bu class, GLSurfaceView.Renderer’ı implement ediyor olacak ve bu interface, bize onSurfaceCreated, onSurfaceChanged ve onDrawFrame methodlarını sağlayacak. Shader’ımızı onSurfaceCreated’da tanımlayacağız, ayarlarımızı onSurfaceChanged’a koyacağız ve onDrawFrame’de elde ettiğimiz verilerden 2 boyutlu iskeletlerimizi çizeceğiz. Aşağıda bu işlemlerin nasıl yapıldığını görebilirsiniz:

onSurfaceCreated’daki vertexShader ve fragmanShader isimli iki variable’a dikkat etmemiz gerekiyor, çünkü bu variablelar ayarlarımızı string formatında taşıdığından, içeriklerinde bir değişiklik ya da eksiklik olduğunda hatanın kaynağının burası olduğunu fark etmek zaman alabiliyor. Ayrıca bu classta yardımcı classlarımızdan biri olan ShaderUtils’i kullanıyoruz, bu yüzden şimdi onu da tanımlayabiliriz.

Son adım! Her şeyi yapılandırdık ve servisimizi RecordActivity’de oluşturmaya hazırız. Activityimizi aşağıdaki kurguladım, buradan siz de variablelar ve methodlar üzerinden nasıl bir yol izlenebileceği hakkında referans alabilirsiniz.

Ayrıca activitymiz için custom layoutlarımızı da koymamız gereken XML dosyasını da unutmayalım :)

Son olarak…

Her şey tamamlandı ve bu adımları takip ettiğinizde bunları başarmış olduk:

  • Cihazımızın kamerasını başlatmak,
  • HMS Motion Capture özelliğinden anlık veri çekmek,
  • Bu verileri bir OpenGL sahnesine işlemek.

Umarım buraya kadar takip etmeniz keyifli bir macera olmuştur. Herhangi bir sorunuz varsa, lütfen benimle iletişime geçmekten çekinmeyin, cevap vermekten memnuniyet duyarım :) Teşekkürler!

Referanslar

--

--