iOS Geliştiriciler için Makine Öğrenmesi #5: Görüntü İşleyen Bir Uygulamada En İyi Frame’i Nasıl Yakalarız?
iOS geliştiricilere makine öğrenmesi araçlarını tanıttığım yazı dizisinin önceki yazılarını okumadıysanız göz atmanızda fayda var.
CreateML ile Yazı Sınıflandırma
CreateML ile Görüntü Sınıflandırma
Bu yazıda başarılı bir görüntü işleme için düzgün görüntüyü nasıl yakalayabileceğimizi inceleyeceğiz.
iOS platformunda görüntü işleyen ve video buffer’ı tüketen herhangi bir uygulama geliştirdiyseniz, burada kaynaklarınızı (CPU, GPU) kullanırken temkinli olmanız gerektiğini bilirsiniz. Mesela görüntü işleyen bir uygulamada kamera akışını takip edip görüntüdeki nesneleri tahminlemeye çalışıyorsanız burada kullanıcı kamerasını sağa sola çevirirken her frame’i işlerseniz yanlış sınıflandırmalar yapabilir ve gereksiz kaynak tüketebilirsiniz. Yüksek doğrulukla görüntü tahminlemek için görüntü sahnesinin stabil olduğu anı yakalamanız gerekir. Bu sorunu çözmek için Apple’ın önerdiği bir yöntem var bu yazıda bu yöntemi öğreneceğiz.
Frame’i yakalamak için basitçe iki seçeneğiniz var:
- Kullanıcı resim çekme butonuna basar.
- Sürekli video bufferından gelen framelerden en iyisini otomatik olarak yakalarsınız.
İlk seçenekte sahne sabitliğini kullanıcıya bırakırsınız. Hot dog uygulamasını hatırlayın o uygulamada kullanıcı fotograf çekip görüntü işlemek için bir butona basıyordu. Burada en iyi frame’i yakalama görevini kullanıcıya bırakıyoruz.
İkinci seçenekte ise kullanıcı kamerasını hedefe doğrulttuğunda en iyi görüntüyü yakalamak uygulamanın görevi.
Bu aşamada kullanıcının telefonu sabit tutup tutmadığını anlamamız ve sabit tuttuğunda görüntüyü yakalamamız gerekiyor. Neyse ki görüntü işleme tanrıları bu işi çözmüşler ve bize Vision frameworküyle registration algoritmasını sağlamışlar :)
Görüntü Çakıştırma (Image Registration)
Tam Türkçe karşılığını görüntü çakıştırma mı emin değilim. Makalelerde bu şekilde kullanılmış. Görüntü çakıştırma birbirine benzer görüntüleri hizalama problemi olarak tanımlanabilir. Bu görüntüler farklı zamanlarda, farklı açılardan veya farklı algılayıcılardan elde edilmiş olabilir.
Çakıştırma işleminde iki resmi üst üste bindiririz ve algoritma bize ‘Şu kadar pikseli kaydırırsan resimler tam olarak üst üste gelecek’ der. Frank Doepke’nin Vision with CoreML sunumunda, söylediği üzere ucuz ve hızlı bir algoritmadır ve bu algoritma bize kamerayı ne kadar sabit tuttuğumuzu ve kameranın önünde herhangi bir hareket olup olmadığını söyler.
Görüntü işleyen uygulamalarda kamera bufferından gelen her frame’i işlersek UI katmanında gecikmelere ve performans kaybına neden olabiliriz. Bu aşamada Apple, registration algoritmasını kullanarak sahnenin ve kameranın sabit olduğunu tespit etmemizi ve bu frame üzerinde sınıflandırma algoritmamızı çalıştırmamızı öneriyor.
Resimler Arasındaki Farkı Nasıl Ölçeriz?
Apple’ın Vision kütüphanesindeki VNTranslationalImageRegistrationRequest bu aşamada bize çözüm sağlıyor. Bu request ile video bufferdan gelen frame’in Vision kaynaklarını harcamaya deyip değmeyeceğini tespit edebiliyoruz. iOS platformunda kameraya erişen uygulamalar captureOutput:didOutputSampleBuffer:fromConnection delegate metodunu kullanarak framelere erişirler. Bu metot içinde aşağıdaki gibi registration requestini gibi çağırarak frame değişimini kontrol edeceğiz.Bu request ile görüntü analizi yaparak iki resmi hizalamak için gereken dönüşümü (affine transform) tespit edeceğiz.
Burada sequenceRequestHandler (VNSequenceRequestHandler) ve VNTranslationalImageRegistrationRequest
nesnelerini kullanarak son 15 frame’i kaydediyor ve art arda gelen frameleri karşılaştırıyoruz. VNSequenceRequestHandler
ile bir seri frame’in (bu case için 15 frame) her biri üzerinde görüntü analizi yaptırabiliyoruz. Bu algoritmada iki frame arasındaki Manhattan uzaklığı 20'den az ise sahnenin sabit olduğunu kabul ediyoruz.
Her şey tamam da Manhattan uzaklığı nedir? Mesela koordinat sisteminde 𝑥=(𝑎,𝑏) ve 𝑦=(𝑐,𝑑) şeklinde iki noktamız olsun.
Öklid uzaklığına göre iki nokta arasındaki uzaklık, bu iki noktayı birleştiren doğrunun uzaklığıdır.
Manhattan uzaklığında ise uzaklık, bu noktalardan geçen ve dik kesişen doğru parçalarının uzaklığı kadardır yani|𝑎−𝑐|+|𝑏−𝑑|.
Manhattan uzaklığını tespit ettikten sonra, image registration requestinin sonuçlarını kontrol edeceğiz. Burada request sonucu alignmentObservation.alignmentTransform
olarak alınır ve sahnenin sabitliği kontrol edilir. RecordTransposition fonksiyonuyla son 15 frame sonucu transpositionHistoryPoints yığınına eklenir.
SceneStabilityAchieved fonksiyonu son 15 frame için bu sonuçları kontrol ederek sahne sabitliğini tespit eder. Yeterince stabil bir sahne yakalandıysa artık bu frame’i analiz etmek için Core ML’e iletebiliriz. Rastgele bir frame değil de bu şekilde sabit bir sahnenin olduğu frame’i ilettiğimiz için sınıflandırma algoritmamız daha başarılı çalışacaktır.
Sonuç
Bu yazıda görüntü çakıştırma yöntemini ve görüntüler arası Manhattan uzaklığını ölçerek sabit bir sahneyi nasıl yakalayabileceğimizi öğrendik. Bu yöntemle görüntü işleyen Core ML uygulamalarımız daha performanslı çalışacak ve daha az kaynak tüketecektir.
ViewController’ın tüm kodunu burada bulabilirsiniz.
Akıllı uygulama geliştirme yolunda bir adım daha attık bir sonraki yazıda görüşmek üzere.
Udemy’de hazırlayacağım iOS geliştiriciler için makine öğrenmesi kursundan beklentilerinizi şu formdan paylaşırsanız sevinirim.
Buraya kadar okuduğunuz için teşekkürler :) Benzer yazılardan haberdar olmak için beni Medium’da ve Twitter’da takip edebilir mail bültenime abone olabilirsiniz.
Esenlikle kalın, bol ML’li yıllar :)
Kaynaklar
https://pdfs.semanticscholar.org/c723/ebf73d5a4deb3e9a901450307dea92a8839d.pdf